ME接口倍增按钮添加
This commit is contained in:
parent
98e97f1103
commit
48709c6ce8
|
|
@ -25,6 +25,15 @@ public final class ModCapabilities {
|
|||
(be, ctx) -> (IInWorldGridNodeHost) be
|
||||
);
|
||||
|
||||
// 并行处理单元(CraftingUnitBlock -> CraftingBlockEntity 实现了 IInWorldGridNodeHost)
|
||||
// 未注册该能力时,AE 电缆通过 GridHelper.getNodeHost(...) 无法发现节点,导致节点不入网,
|
||||
// 方块虽然能成型并提供并行度,但 getMainNode().isOnline() 为 false,从而显示“设备离线”。
|
||||
event.registerBlockEntity(
|
||||
AECapabilities.IN_WORLD_GRID_NODE_HOST,
|
||||
ModBlockEntities.EPLUS_CRAFTING_UNIT_BE.get(),
|
||||
(be, ctx) -> (IInWorldGridNodeHost) be
|
||||
);
|
||||
|
||||
// 如果还有其他实现了 IInWorldGridNodeHost 的方块实体,也在这里一并注册
|
||||
// event.registerBlockEntity(AECapabilities.IN_WORLD_GRID_NODE_HOST, ModBlockEntities.NETWORK_PATTERN_CONTROLLER_BE.get(), (be, ctx) -> (IInWorldGridNodeHost) be);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.extendedae_plus.mixin.accessor;
|
|||
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
|
|
@ -11,4 +12,5 @@ public interface AbstractContainerScreenAccessor<T extends AbstractContainerMenu
|
|||
@Accessor("topPos") int eap$getTopPos();
|
||||
@Accessor("imageWidth") int eap$getImageWidth();
|
||||
@Accessor("imageHeight") int eap$getImageHeight();
|
||||
@Accessor("hoveredSlot") Slot eap$getHoveredSlot();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,280 @@
|
|||
package com.extendedae_plus.mixin.ae2.client.gui;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.implementations.InterfaceScreen;
|
||||
import appeng.menu.AEBaseMenu;
|
||||
import appeng.menu.SlotSemantics;
|
||||
import com.extendedae_plus.NewIcon;
|
||||
import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor;
|
||||
import com.extendedae_plus.mixin.accessor.ScreenAccessor;
|
||||
import com.extendedae_plus.network.InterfaceAdjustConfigAmountC2SPacket;
|
||||
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* 在 AE2 的 ME 接口界面注入倍增/除法按钮(x2/÷2、x5/÷5、x10/÷10)。
|
||||
* 点击时通过 NeoForge 自定义负载发送到服务端调整配置数量。
|
||||
*/
|
||||
@Mixin(value = AEBaseScreen.class, remap = false)
|
||||
public abstract class InterfaceScreenMixin<T extends AEBaseMenu> {
|
||||
|
||||
@Unique private ActionEPPButton eap$x2Button;
|
||||
@Unique private ActionEPPButton eap$divideBy2Button;
|
||||
@Unique private ActionEPPButton eap$x5Button;
|
||||
@Unique private ActionEPPButton eap$divideBy5Button;
|
||||
@Unique private ActionEPPButton eap$x10Button;
|
||||
@Unique private ActionEPPButton eap$divideBy10Button;
|
||||
|
||||
@Unique private int eap$lastLeftPos = -1;
|
||||
@Unique private int eap$lastTopPos = -1;
|
||||
@Unique private int eap$lastImageWidth = -1;
|
||||
@Unique private int eap$lastImageHeight = -1;
|
||||
// 最近一次在 CONFIG 区域悬停的配置槽索引
|
||||
@Unique private int eap$lastConfigIndex = -1;
|
||||
|
||||
@Inject(method = "init", at = @At("TAIL"))
|
||||
private void eap$addScaleButtons(CallbackInfo ci) {
|
||||
if (!eap$isSupportedInterfaceScreen()) {
|
||||
return;
|
||||
}
|
||||
try { LogUtils.getLogger().info("[EAP][InterfaceMixin] init tail reached, preparing scale buttons."); } catch (Throwable ignored) {}
|
||||
if (eap$x2Button == null) {
|
||||
eap$x2Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(false, 2), NewIcon.MULTIPLY2);
|
||||
eap$x2Button.setTooltip(null);
|
||||
eap$x2Button.setVisibility(true);
|
||||
}
|
||||
if (eap$divideBy2Button == null) {
|
||||
eap$divideBy2Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(true, 2), NewIcon.DIVIDE2);
|
||||
eap$divideBy2Button.setTooltip(null);
|
||||
eap$divideBy2Button.setVisibility(true);
|
||||
}
|
||||
if (eap$x5Button == null) {
|
||||
eap$x5Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(false, 5), NewIcon.MULTIPLY5);
|
||||
eap$x5Button.setTooltip(null);
|
||||
eap$x5Button.setVisibility(true);
|
||||
}
|
||||
if (eap$divideBy5Button == null) {
|
||||
eap$divideBy5Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(true, 5), NewIcon.DIVIDE5);
|
||||
eap$divideBy5Button.setTooltip(null);
|
||||
eap$divideBy5Button.setVisibility(true);
|
||||
}
|
||||
if (eap$x10Button == null) {
|
||||
eap$x10Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(false, 10), NewIcon.MULTIPLY10);
|
||||
eap$x10Button.setTooltip(null);
|
||||
eap$x10Button.setVisibility(true);
|
||||
}
|
||||
if (eap$divideBy10Button == null) {
|
||||
eap$divideBy10Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(true, 10), NewIcon.DIVIDE10);
|
||||
eap$divideBy10Button.setTooltip(null);
|
||||
eap$divideBy10Button.setVisibility(true);
|
||||
}
|
||||
|
||||
// 注册到渲染与交互列表
|
||||
var accessor = (ScreenAccessor) (Object) this;
|
||||
if (!accessor.eap$getRenderables().contains(eap$divideBy2Button)) accessor.eap$getRenderables().add(eap$divideBy2Button);
|
||||
if (!accessor.eap$getChildren().contains(eap$divideBy2Button)) accessor.eap$getChildren().add(eap$divideBy2Button);
|
||||
if (!accessor.eap$getRenderables().contains(eap$x2Button)) accessor.eap$getRenderables().add(eap$x2Button);
|
||||
if (!accessor.eap$getChildren().contains(eap$x2Button)) accessor.eap$getChildren().add(eap$x2Button);
|
||||
if (!accessor.eap$getRenderables().contains(eap$divideBy5Button)) accessor.eap$getRenderables().add(eap$divideBy5Button);
|
||||
if (!accessor.eap$getChildren().contains(eap$divideBy5Button)) accessor.eap$getChildren().add(eap$divideBy5Button);
|
||||
if (!accessor.eap$getRenderables().contains(eap$x5Button)) accessor.eap$getRenderables().add(eap$x5Button);
|
||||
if (!accessor.eap$getChildren().contains(eap$x5Button)) accessor.eap$getChildren().add(eap$x5Button);
|
||||
if (!accessor.eap$getRenderables().contains(eap$divideBy10Button)) accessor.eap$getRenderables().add(eap$divideBy10Button);
|
||||
if (!accessor.eap$getChildren().contains(eap$divideBy10Button)) accessor.eap$getChildren().add(eap$divideBy10Button);
|
||||
if (!accessor.eap$getRenderables().contains(eap$x10Button)) accessor.eap$getRenderables().add(eap$x10Button);
|
||||
if (!accessor.eap$getChildren().contains(eap$x10Button)) accessor.eap$getChildren().add(eap$x10Button);
|
||||
|
||||
eap$relayoutButtons();
|
||||
try { LogUtils.getLogger().info("[EAP][InterfaceMixin] buttons added and laid out."); } catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Inject(method = "containerTick", at = @At("TAIL"))
|
||||
private void eap$ensureButtons(CallbackInfo ci) {
|
||||
if (!eap$isSupportedInterfaceScreen()) {
|
||||
return;
|
||||
}
|
||||
var accessor = (ScreenAccessor) (Object) this;
|
||||
if (eap$divideBy2Button != null && !accessor.eap$getRenderables().contains(eap$divideBy2Button)) {
|
||||
accessor.eap$getRenderables().add(eap$divideBy2Button);
|
||||
accessor.eap$getChildren().add(eap$divideBy2Button);
|
||||
}
|
||||
if (eap$x2Button != null && !accessor.eap$getRenderables().contains(eap$x2Button)) {
|
||||
accessor.eap$getRenderables().add(eap$x2Button);
|
||||
accessor.eap$getChildren().add(eap$x2Button);
|
||||
}
|
||||
if (eap$divideBy5Button != null && !accessor.eap$getRenderables().contains(eap$divideBy5Button)) {
|
||||
accessor.eap$getRenderables().add(eap$divideBy5Button);
|
||||
accessor.eap$getChildren().add(eap$divideBy5Button);
|
||||
}
|
||||
if (eap$x5Button != null && !accessor.eap$getRenderables().contains(eap$x5Button)) {
|
||||
accessor.eap$getRenderables().add(eap$x5Button);
|
||||
accessor.eap$getChildren().add(eap$x5Button);
|
||||
}
|
||||
if (eap$divideBy10Button != null && !accessor.eap$getRenderables().contains(eap$divideBy10Button)) {
|
||||
accessor.eap$getRenderables().add(eap$divideBy10Button);
|
||||
accessor.eap$getChildren().add(eap$divideBy10Button);
|
||||
}
|
||||
if (eap$x10Button != null && !accessor.eap$getRenderables().contains(eap$x10Button)) {
|
||||
accessor.eap$getRenderables().add(eap$x10Button);
|
||||
accessor.eap$getChildren().add(eap$x10Button);
|
||||
}
|
||||
|
||||
int curLeft = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos();
|
||||
int curTop = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos();
|
||||
int curImgW = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth();
|
||||
int curImgH = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageHeight();
|
||||
if (curLeft != eap$lastLeftPos || curTop != eap$lastTopPos || curImgW != eap$lastImageWidth || curImgH != eap$lastImageHeight) {
|
||||
eap$lastLeftPos = curLeft;
|
||||
eap$lastTopPos = curTop;
|
||||
eap$lastImageWidth = curImgW;
|
||||
eap$lastImageHeight = curImgH;
|
||||
eap$relayoutButtons();
|
||||
}
|
||||
eap$updateLastConfigFromHover();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void eap$sendAdjustForHoveredConfig(boolean divide, int factor) {
|
||||
try {
|
||||
if (!eap$isSupportedInterfaceScreen()) {
|
||||
return;
|
||||
}
|
||||
Slot hovered = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getHoveredSlot();
|
||||
var screen = (AEBaseScreen<?>) (Object) this;
|
||||
var menu = screen.getMenu();
|
||||
if (!(menu instanceof appeng.menu.implementations.InterfaceMenu interfaceMenu)) {
|
||||
return;
|
||||
}
|
||||
var configSlots = interfaceMenu.getSlots(SlotSemantics.CONFIG);
|
||||
if (configSlots == null || configSlots.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Integer slotFieldObj = null;
|
||||
if (hovered != null) {
|
||||
for (var s : configSlots) {
|
||||
if (s == hovered) {
|
||||
try {
|
||||
var f = s.getClass().getDeclaredField("slot");
|
||||
f.setAccessible(true);
|
||||
Object v = f.get(s);
|
||||
if (v instanceof Integer i) {
|
||||
slotFieldObj = i;
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
if (slotFieldObj == null) {
|
||||
slotFieldObj = configSlots.indexOf(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int slotField = -1;
|
||||
if (slotFieldObj != null) {
|
||||
slotField = slotFieldObj;
|
||||
} else if (eap$lastConfigIndex >= 0 && eap$lastConfigIndex < configSlots.size()) {
|
||||
slotField = eap$lastConfigIndex;
|
||||
}
|
||||
if (slotField < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var conn = Minecraft.getInstance().getConnection();
|
||||
if (conn != null) conn.send(new InterfaceAdjustConfigAmountC2SPacket(slotField, divide, factor));
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void eap$sendAdjustForAllConfigs(boolean divide, int factor) {
|
||||
try {
|
||||
if (!eap$isSupportedInterfaceScreen()) {
|
||||
return;
|
||||
}
|
||||
var conn = Minecraft.getInstance().getConnection();
|
||||
if (conn != null) conn.send(new InterfaceAdjustConfigAmountC2SPacket(-1, divide, factor));
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean eap$isSupportedInterfaceScreen() {
|
||||
if (((Object) this) instanceof InterfaceScreen) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
String cn = ((Object) this).getClass().getName();
|
||||
if ("com.glodblock.github.extendedae.client.gui.GuiExInterface".equals(cn)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void eap$relayoutButtons() {
|
||||
try {
|
||||
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos();
|
||||
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos();
|
||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth();
|
||||
int bx = leftPos + imageWidth + 1;
|
||||
int by = topPos + 20;
|
||||
int spacing = 22;
|
||||
if (eap$divideBy2Button != null) { eap$divideBy2Button.setX(bx); eap$divideBy2Button.setY(by); }
|
||||
if (eap$x2Button != null) { eap$x2Button.setX(bx); eap$x2Button.setY(by + spacing); }
|
||||
if (eap$divideBy5Button != null) { eap$divideBy5Button.setX(bx); eap$divideBy5Button.setY(by + spacing * 2); }
|
||||
if (eap$x5Button != null) { eap$x5Button.setX(bx); eap$x5Button.setY(by + spacing * 3); }
|
||||
if (eap$divideBy10Button != null) { eap$divideBy10Button.setX(bx); eap$divideBy10Button.setY(by + spacing * 4); }
|
||||
if (eap$x10Button != null) { eap$x10Button.setX(bx); eap$x10Button.setY(by + spacing * 5); }
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void eap$updateLastConfigFromHover() {
|
||||
try {
|
||||
if (!(((Object) this) instanceof InterfaceScreen)) {
|
||||
return;
|
||||
}
|
||||
Slot hovered = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getHoveredSlot();
|
||||
if (hovered == null) {
|
||||
return;
|
||||
}
|
||||
var screen = (AEBaseScreen<?>) (Object) this;
|
||||
var menu = screen.getMenu();
|
||||
if (!(menu instanceof appeng.menu.implementations.InterfaceMenu interfaceMenu)) {
|
||||
return;
|
||||
}
|
||||
var configSlots = interfaceMenu.getSlots(SlotSemantics.CONFIG);
|
||||
if (configSlots == null || configSlots.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Integer idx = null;
|
||||
for (var s : configSlots) {
|
||||
if (s == hovered) {
|
||||
try {
|
||||
var f = s.getClass().getDeclaredField("slot");
|
||||
f.setAccessible(true);
|
||||
Object v = f.get(s);
|
||||
if (v instanceof Integer i) {
|
||||
idx = i;
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
if (idx == null) {
|
||||
idx = configSlots.indexOf(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx != null && idx >= 0) {
|
||||
if (eap$lastConfigIndex != idx) {
|
||||
eap$lastConfigIndex = idx;
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.extendedae_plus.network;
|
||||
|
||||
import appeng.menu.implementations.InterfaceMenu;
|
||||
import appeng.api.stacks.GenericStack;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
|
||||
/**
|
||||
* C2S:调整 ME 接口配置槽位(标记物品)的数量。
|
||||
* 支持按因子倍增或整除,且保持最小值为 1。
|
||||
*/
|
||||
public class InterfaceAdjustConfigAmountC2SPacket implements CustomPacketPayload {
|
||||
public static final Type<InterfaceAdjustConfigAmountC2SPacket> TYPE = new Type<>(
|
||||
ResourceLocation.fromNamespaceAndPath(com.extendedae_plus.ExtendedAEPlus.MODID, "interface_adjust_config_amount"));
|
||||
|
||||
public static final StreamCodec<FriendlyByteBuf, InterfaceAdjustConfigAmountC2SPacket> STREAM_CODEC = StreamCodec.of(
|
||||
(buf, pkt) -> {
|
||||
buf.writeVarInt(pkt.slotIndex);
|
||||
buf.writeBoolean(pkt.divide);
|
||||
buf.writeVarInt(pkt.factor);
|
||||
},
|
||||
buf -> new InterfaceAdjustConfigAmountC2SPacket(buf.readVarInt(), buf.readBoolean(), buf.readVarInt())
|
||||
);
|
||||
|
||||
private final int slotIndex; // 配置槽位索引(-1 表示全部)
|
||||
private final boolean divide; // true 表示做除法,否则做乘法
|
||||
private final int factor; // 因子:2/5/10
|
||||
|
||||
public InterfaceAdjustConfigAmountC2SPacket(int slotIndex, boolean divide, int factor) {
|
||||
this.slotIndex = slotIndex;
|
||||
this.divide = divide;
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public static void handle(final InterfaceAdjustConfigAmountC2SPacket msg, final IPayloadContext ctx) {
|
||||
ctx.enqueueWork(() -> {
|
||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||
|
||||
// 支持 AE2 原版接口和 ExtendedAE 扩展接口(若存在)
|
||||
InterfaceMenu menu = null;
|
||||
com.glodblock.github.extendedae.container.ContainerExInterface exMenu = null;
|
||||
if (player.containerMenu instanceof InterfaceMenu im) {
|
||||
menu = im;
|
||||
} else if (player.containerMenu instanceof com.glodblock.github.extendedae.container.ContainerExInterface cem) {
|
||||
exMenu = cem;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var logic = (menu != null ? menu.getHost() : exMenu.getHost()).getInterfaceLogic();
|
||||
var config = logic.getConfig();
|
||||
if (msg.slotIndex == -1) {
|
||||
// 对所有配置槽统一生效
|
||||
int size = config.size();
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
var st = config.getStack(idx);
|
||||
if (st == null) continue;
|
||||
|
||||
long current = st.amount();
|
||||
int factor = Math.max(1, msg.factor);
|
||||
long next;
|
||||
if (msg.divide) {
|
||||
if (factor <= 1) continue;
|
||||
if (current % factor != 0) continue;
|
||||
next = current / factor;
|
||||
if (next < 1) next = 1;
|
||||
} else {
|
||||
if (factor <= 1) continue;
|
||||
next = current * factor;
|
||||
if (next < 1) next = 1;
|
||||
}
|
||||
|
||||
GenericStack newStack = new GenericStack(st.what(), next);
|
||||
config.setStack(idx, newStack);
|
||||
}
|
||||
} else {
|
||||
var stack = config.getStack(msg.slotIndex);
|
||||
if (stack == null) return; // 槽位无标记
|
||||
|
||||
long current = stack.amount();
|
||||
int factor = Math.max(1, msg.factor);
|
||||
long next;
|
||||
if (msg.divide) {
|
||||
// 只能整除,且至少为 1
|
||||
if (factor <= 1) return;
|
||||
if (current % factor != 0) return; // 不能整除则跳过
|
||||
next = current / factor;
|
||||
if (next < 1) next = 1;
|
||||
} else {
|
||||
// 倍增,至少为 1
|
||||
if (factor <= 1) return;
|
||||
next = current * factor;
|
||||
if (next < 1) next = 1;
|
||||
}
|
||||
|
||||
// 应用
|
||||
GenericStack newStack = new GenericStack(stack.what(), next);
|
||||
config.setStack(msg.slotIndex, newStack);
|
||||
}
|
||||
// InterfaceLogic.config 的变更监听器会触发保存与计划更新
|
||||
} catch (Throwable ignored) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ public class ModNetwork {
|
|||
registrar.playToServer(ToggleAdvancedBlockingC2SPacket.TYPE, ToggleAdvancedBlockingC2SPacket.STREAM_CODEC, ToggleAdvancedBlockingC2SPacket::handle);
|
||||
registrar.playToServer(ToggleSmartDoublingC2SPacket.TYPE, ToggleSmartDoublingC2SPacket.STREAM_CODEC, ToggleSmartDoublingC2SPacket::handle);
|
||||
registrar.playToServer(ScalePatternsC2SPacket.TYPE, ScalePatternsC2SPacket.STREAM_CODEC, ScalePatternsC2SPacket::handle);
|
||||
registrar.playToServer(InterfaceAdjustConfigAmountC2SPacket.TYPE, InterfaceAdjustConfigAmountC2SPacket.STREAM_CODEC, InterfaceAdjustConfigAmountC2SPacket::handle);
|
||||
registrar.playToClient(SetPatternHighlightS2CPacket.TYPE, SetPatternHighlightS2CPacket.STREAM_CODEC, SetPatternHighlightS2CPacket::handle);
|
||||
registrar.playToClient(AdvancedBlockingSyncS2CPacket.TYPE, AdvancedBlockingSyncS2CPacket.STREAM_CODEC, AdvancedBlockingSyncS2CPacket::handle);
|
||||
registrar.playToClient(ProvidersListS2CPacket.TYPE, ProvidersListS2CPacket.STREAM_CODEC, ProvidersListS2CPacket::handle);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
"ae2.accessor.MEStorageScreenAccessor",
|
||||
"ae2.accessor.PatternAccessTermScreenAccessor",
|
||||
"ae2.accessor.PatternAccessTermScreenSlotsRowAccessor",
|
||||
"ae2.client.gui.InterfaceScreenMixin",
|
||||
"ae2.client.gui.AEBaseScreenMixin",
|
||||
"ae2.client.gui.PatternEncodingTermScreenMixin",
|
||||
"ae2.client.gui.PatternProviderCloseMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user