完成打开样板编码终端自动填充样板功能
This commit is contained in:
parent
981d2f2b32
commit
319253d6f9
|
|
@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G
|
||||||
loom.platform = forge
|
loom.platform = forge
|
||||||
|
|
||||||
# Mod properties
|
# Mod properties
|
||||||
mod_version = 1.1.3
|
mod_version = 1.1.4
|
||||||
maven_group = com.extendedae_plus
|
maven_group = com.extendedae_plus
|
||||||
archives_name = extendedae_plus
|
archives_name = extendedae_plus
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
package com.extendedae_plus.mixin;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.MenuType;
|
||||||
|
|
||||||
|
import appeng.api.inventories.InternalInventory;
|
||||||
|
import appeng.api.networking.energy.IEnergySource;
|
||||||
|
import appeng.api.storage.MEStorage;
|
||||||
|
import appeng.api.storage.StorageHelper;
|
||||||
|
import appeng.api.stacks.AEItemKey;
|
||||||
|
import appeng.api.stacks.AEKey;
|
||||||
|
import appeng.core.definitions.AEItems;
|
||||||
|
import appeng.helpers.IPatternTerminalMenuHost;
|
||||||
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
|
import appeng.api.networking.security.IActionSource;
|
||||||
|
import appeng.menu.slot.RestrictedInputSlot;
|
||||||
|
import appeng.menu.me.common.MEStorageMenu;
|
||||||
|
import com.extendedae_plus.mixin.accessor.MEStorageMenuAccessor;
|
||||||
|
|
||||||
|
@Mixin(PatternEncodingTermMenu.class)
|
||||||
|
public abstract class PatternEncodingTermMenuMixin {
|
||||||
|
|
||||||
|
// 防止重复执行
|
||||||
|
@org.spongepowered.asm.mixin.Unique
|
||||||
|
private boolean extendedae_plus$blankAutoFilled = false;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private RestrictedInputSlot blankPatternSlot;
|
||||||
|
|
||||||
|
@org.spongepowered.asm.mixin.Unique
|
||||||
|
private void extendedae_plus$tryFill(IPatternTerminalMenuHost host, Inventory ip) {
|
||||||
|
try {
|
||||||
|
var self = (PatternEncodingTermMenu) (Object) this;
|
||||||
|
var player = ip.player;
|
||||||
|
// 仅在服务器端执行
|
||||||
|
if (ip.player.level().isClientSide()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 必须可与网络交互
|
||||||
|
var acc = (MEStorageMenuAccessor) (Object) ((MEStorageMenu) self);
|
||||||
|
MEStorage storage = acc.getStorage();
|
||||||
|
IEnergySource power = acc.getPowerSource();
|
||||||
|
boolean hasPower = acc.getHasPower();
|
||||||
|
boolean canInteract = storage != null && power != null && hasPower; // 等价于 canInteractWithGrid()
|
||||||
|
if (!canInteract) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (storage == null || power == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalInventory blankInv = host.getLogic().getBlankPatternInv();
|
||||||
|
var current = blankInv.getStackInSlot(0);
|
||||||
|
int limit = blankInv.getSlotLimit(0);
|
||||||
|
int space = Math.max(0, limit - current.getCount());
|
||||||
|
space = Math.min(space, AEItems.BLANK_PATTERN.asItem().getMaxStackSize());
|
||||||
|
if (space <= 0) {
|
||||||
|
return; // 已满,无需填充
|
||||||
|
}
|
||||||
|
|
||||||
|
AEKey blankKey = AEItemKey.of(AEItems.BLANK_PATTERN.asItem());
|
||||||
|
long extracted = StorageHelper.poweredExtraction(power, storage, blankKey, space,
|
||||||
|
self.getActionSource());
|
||||||
|
if (extracted <= 0) {
|
||||||
|
return; // 网络无可用空白样板
|
||||||
|
}
|
||||||
|
|
||||||
|
int toInsert = (int) Math.min(extracted, space);
|
||||||
|
var stackInSlot = this.blankPatternSlot.getItem();
|
||||||
|
if (stackInSlot.isEmpty()) {
|
||||||
|
this.blankPatternSlot.set(AEItems.BLANK_PATTERN.stack(toInsert));
|
||||||
|
} else {
|
||||||
|
stackInSlot.grow(toInsert);
|
||||||
|
this.blankPatternSlot.set(stackInSlot);
|
||||||
|
}
|
||||||
|
long leftover = extracted - toInsert;
|
||||||
|
if (leftover > 0) {
|
||||||
|
StorageHelper.poweredInsert(power, storage, blankKey, leftover, self.getActionSource());
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// swallow errors to avoid noisy logs in production
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/IPatternTerminalMenuHost;Z)V",
|
||||||
|
at = @At("TAIL"))
|
||||||
|
private void extendedae_plus$autoFillBlankPattern(MenuType<?> menuType, int id, Inventory ip,
|
||||||
|
IPatternTerminalMenuHost host, boolean bindInventory,
|
||||||
|
CallbackInfo ci) {
|
||||||
|
extendedae_plus$tryFill(host, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/IPatternTerminalMenuHost;)V",
|
||||||
|
at = @At("TAIL"))
|
||||||
|
private void extendedae_plus$autoFillCtor3(int id, Inventory ip, IPatternTerminalMenuHost host, CallbackInfo ci) {
|
||||||
|
extendedae_plus$tryFill(host, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在首次 broadcastChanges 后再尝试一次,避免构造时网络未激活
|
||||||
|
@Inject(method = "broadcastChanges", at = @At("TAIL"))
|
||||||
|
private void extendedae_plus$retryFillAfterPower(CallbackInfo ci) {
|
||||||
|
if (this.extendedae_plus$blankAutoFilled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 仅在服务器端执行
|
||||||
|
var self = (PatternEncodingTermMenu) (Object) this;
|
||||||
|
var player = self.getPlayerInventory().player;
|
||||||
|
var acc = (MEStorageMenuAccessor) (Object) ((MEStorageMenu) self);
|
||||||
|
MEStorage storage = acc.getStorage();
|
||||||
|
IEnergySource power = acc.getPowerSource();
|
||||||
|
boolean hasPower = acc.getHasPower();
|
||||||
|
if (player.level().isClientSide()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean canInteract = storage != null && power != null && hasPower;
|
||||||
|
if (!canInteract) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 通过 host 获取 blankPatternInv
|
||||||
|
var host = ((IPatternTerminalMenuHost) self.getTarget());
|
||||||
|
InternalInventory blankInv = host.getLogic().getBlankPatternInv();
|
||||||
|
var current = blankInv.getStackInSlot(0);
|
||||||
|
int limit = blankInv.getSlotLimit(0);
|
||||||
|
int space = Math.max(0, limit - current.getCount());
|
||||||
|
space = Math.min(space, AEItems.BLANK_PATTERN.asItem().getMaxStackSize());
|
||||||
|
if (space <= 0) {
|
||||||
|
this.extendedae_plus$blankAutoFilled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AEKey blankKey = AEItemKey.of(AEItems.BLANK_PATTERN.asItem());
|
||||||
|
long extracted = StorageHelper.poweredExtraction(power, storage, blankKey, space,
|
||||||
|
self.getActionSource());
|
||||||
|
if (extracted <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int toInsert = (int) Math.min(extracted, space);
|
||||||
|
var stackInSlot = this.blankPatternSlot.getItem();
|
||||||
|
if (stackInSlot.isEmpty()) {
|
||||||
|
this.blankPatternSlot.set(AEItems.BLANK_PATTERN.stack(toInsert));
|
||||||
|
} else {
|
||||||
|
stackInSlot.grow(toInsert);
|
||||||
|
this.blankPatternSlot.set(stackInSlot);
|
||||||
|
}
|
||||||
|
long leftover = extracted - toInsert;
|
||||||
|
if (leftover > 0) {
|
||||||
|
StorageHelper.poweredInsert(power, storage, blankKey, leftover, self.getActionSource());
|
||||||
|
}
|
||||||
|
this.extendedae_plus$blankAutoFilled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.extendedae_plus.mixin.accessor;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import appeng.api.networking.energy.IEnergySource;
|
||||||
|
import appeng.api.storage.MEStorage;
|
||||||
|
import appeng.menu.me.common.MEStorageMenu;
|
||||||
|
|
||||||
|
@Mixin(MEStorageMenu.class)
|
||||||
|
public interface MEStorageMenuAccessor {
|
||||||
|
@Accessor("storage")
|
||||||
|
@Nullable
|
||||||
|
MEStorage getStorage();
|
||||||
|
|
||||||
|
@Accessor("powerSource")
|
||||||
|
@Nullable
|
||||||
|
IEnergySource getPowerSource();
|
||||||
|
|
||||||
|
@Accessor("hasPower")
|
||||||
|
boolean getHasPower();
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,9 @@
|
||||||
"ContainerWirelessExPatternTerminalMixin",
|
"ContainerWirelessExPatternTerminalMixin",
|
||||||
"ContainerUWirelessExPatternTerminalMixin",
|
"ContainerUWirelessExPatternTerminalMixin",
|
||||||
"TileExPatternProviderMixin",
|
"TileExPatternProviderMixin",
|
||||||
"PartExPatternProviderMixin"
|
"PartExPatternProviderMixin",
|
||||||
|
"PatternEncodingTermMenuMixin",
|
||||||
|
"accessor.MEStorageMenuAccessor"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user