ExtendedAE_Plus/src/main/java/com/extendedae_plus/mixin/GuiExPatternProviderMixin.java

225 lines
8.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.extendedae_plus.mixin;
import appeng.client.gui.Icon;
import appeng.client.gui.implementations.PatternProviderScreen;
import appeng.client.gui.style.PaletteColor;
import appeng.client.gui.style.ScreenStyle;
import appeng.client.gui.widgets.VerticalButtonBar;
import appeng.menu.SlotSemantics;
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
import com.extendedae_plus.network.UpdatePagePacket;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
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;
import java.lang.reflect.Field;
import java.util.List;
@Mixin(GuiExPatternProvider.class)
public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<ContainerExPatternProvider> {
@Unique
ScreenStyle screenStyle;
@Unique
private VerticalButtonBar rightToolbar;
@Unique
private static final int SLOTS_PER_PAGE = 36; // 每页显示36个槽位
public GuiExPatternProviderMixin(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style) {
super(menu, playerInventory, title, style);
}
@Unique
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) {
super.render(guiGraphics, mouseX, mouseY, partialTicks);
int maxSlots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN).size();
// 只有当槽位数超过每页显示数量时才显示翻页信息
if (maxSlots > SLOTS_PER_PAGE) {
Font fontRenderer = Minecraft.getInstance().font;
// 获取当前页码
int currentPage = getCurrentPage();
int maxPage = getMaxPage();
// 获取ae通用界面样式
int color = screenStyle.getColor(PaletteColor.DEFAULT_TEXT_COLOR).toARGB();
guiGraphics.drawString(font, Component.literal("" + (currentPage + 1) + "/" + maxPage + ""),
leftPos + imageWidth / 2 - 30, topPos + 5, color, false);
}
}
@Unique
public void updateBeforeRender() {
super.updateBeforeRender();
try {
ContainerExPatternProvider menu1 = this.getMenu();
// 调用showPage方法
java.lang.reflect.Method showPageMethod = menu1.getClass().getMethod("showPage");
showPageMethod.invoke(menu1);
// 获取当前页码和最大页码
Field fieldPage = menu1.getClass().getDeclaredField("page");
fieldPage.setAccessible(true);
Integer page = (Integer) fieldPage.get(menu1);
Field fieldMaxPage = menu1.getClass().getDeclaredField("maxPage");
fieldMaxPage.setAccessible(true);
Integer maxPage = (Integer) fieldMaxPage.get(menu1);
// 更新按钮可见性
if (nextPage != null && prevPage != null) {
this.nextPage.setVisibility(page + 1 < maxPage);
this.prevPage.setVisibility(page - 1 >= 0);
}
// 调整槽位位置
this.adjustSlotPositions(page);
} catch (Exception e) {
// 忽略反射错误
}
}
@Unique
private void adjustSlotPositions(int currentPage) {
try {
List<Slot> slots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN);
int totalSlots = slots.size();
if (totalSlots <= SLOTS_PER_PAGE) {
return; // 不需要翻页
}
int slot_id = 0;
for (Slot s : slots) {
int page_id = slot_id / SLOTS_PER_PAGE;
if (page_id == currentPage) {
// 当前页的槽位需要调整位置
int slotInPage = slot_id % SLOTS_PER_PAGE;
int row = slotInPage / 9; // 0-3
int col = slotInPage % 9; // 0-8
// 计算目标位置始终在前4行
int x = 8 + col * 18;
int y = 42 + row * 18;
// 使用反射设置槽位位置,支持混淆环境
Field xField = null;
Field yField = null;
// 尝试不同的字段名(开发环境和生产环境可能不同)
String[] xFieldNames = {"x", "field_75262_c"};
String[] yFieldNames = {"y", "field_75263_d"};
for (String fieldName : xFieldNames) {
try {
xField = Slot.class.getDeclaredField(fieldName);
xField.setAccessible(true);
break;
} catch (NoSuchFieldException ignored) {}
}
for (String fieldName : yFieldNames) {
try {
yField = Slot.class.getDeclaredField(fieldName);
yField.setAccessible(true);
break;
} catch (NoSuchFieldException ignored) {}
}
if (xField != null && yField != null) {
xField.set(s, x);
yField.set(s, y);
}
}
++slot_id;
}
} catch (Exception e) {
// 忽略反射错误
}
}
@Unique
private int getCurrentPage() {
try {
ContainerExPatternProvider menu1 = this.getMenu();
Field fieldPage = menu1.getClass().getDeclaredField("page");
fieldPage.setAccessible(true);
return (Integer) fieldPage.get(menu1);
} catch (Exception e) {
return 0;
}
}
@Unique
private int getMaxPage() {
try {
ContainerExPatternProvider menu1 = this.getMenu();
Field fieldMaxPage = menu1.getClass().getDeclaredField("maxPage");
fieldMaxPage.setAccessible(true);
return (Integer) fieldMaxPage.get(menu1);
} catch (Exception e) {
return 1;
}
}
public ActionEPPButton nextPage;
public ActionEPPButton prevPage;
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
private void injectInit(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
this.screenStyle = style;
this.rightToolbar = new VerticalButtonBar();
// 只有当槽位数超过每页显示数量时才添加翻页按钮
int maxSlots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN).size();
if (maxSlots > SLOTS_PER_PAGE) {
// 前进后退按钮
this.prevPage = new ActionEPPButton((b) -> {
int currentPage = getCurrentPage();
if (currentPage > 0) {
// 发送网络包更新页码
// 这里简化处理直接调用setPage方法
try {
ContainerExPatternProvider menu1 = this.getMenu();
java.lang.reflect.Method setPageMethod = menu1.getClass().getMethod("setPage", int.class);
setPageMethod.invoke(menu1, currentPage - 1);
} catch (Exception e) {
// 忽略反射错误
}
}
}, Icon.ARROW_LEFT);
this.nextPage = new ActionEPPButton((b) -> {
int currentPage = getCurrentPage();
int maxPage = getMaxPage();
if (currentPage + 1 < maxPage) {
try {
ContainerExPatternProvider menu1 = this.getMenu();
java.lang.reflect.Method setPageMethod = menu1.getClass().getMethod("setPage", int.class);
setPageMethod.invoke(menu1, currentPage + 1);
} catch (Exception e) {
// 忽略反射错误
}
}
}, Icon.ARROW_RIGHT);
this.addToLeftToolbar(this.nextPage);
this.addToLeftToolbar(this.prevPage);
}
}
}