diff --git a/src/main/java/net/sys42/dakedres/grafting/block/entity/WorkbenchBlockEntity.java b/src/main/java/net/sys42/dakedres/grafting/block/entity/WorkbenchBlockEntity.java index 522ad8a..0059434 100644 --- a/src/main/java/net/sys42/dakedres/grafting/block/entity/WorkbenchBlockEntity.java +++ b/src/main/java/net/sys42/dakedres/grafting/block/entity/WorkbenchBlockEntity.java @@ -3,7 +3,6 @@ package net.sys42.dakedres.grafting.block.entity; import eu.pb4.polymer.resourcepack.api.PolymerModelData; import eu.pb4.sgui.api.ClickType; import eu.pb4.sgui.api.elements.GuiElement; -import eu.pb4.sgui.api.gui.SimpleGui; import eu.pb4.sgui.virtual.inventory.VirtualSlot; import net.minecraft.block.BlockState; import net.minecraft.block.CrafterBlock; @@ -32,6 +31,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.sys42.dakedres.grafting.Grafting; import net.sys42.dakedres.grafting.PlacementUtils; +import net.sys42.dakedres.grafting.ui.CursorListeningSimpleGui; import net.sys42.dakedres.grafting.ui.Icons; import java.util.ArrayList; @@ -94,7 +94,7 @@ public class WorkbenchBlockEntity extends OrderedContainer { @Override public void markDirty() { for(Gui gui : guis) { - gui.updateResult(); + gui.update(); } super.markDirty(); } @@ -244,7 +244,7 @@ public class WorkbenchBlockEntity extends OrderedContainer { } } - public class Gui extends SimpleGui { + public class Gui extends CursorListeningSimpleGui { private static final Identifier GUI_FONT_ID = Identifier.of(Grafting.MOD_ID, "workbench_gui"); private static final Identifier SLOT_ORDER_OVERLAY_FONT_ID = Identifier.of(Grafting.MOD_ID, "slot_order_overlay"); @@ -261,7 +261,7 @@ public class WorkbenchBlockEntity extends OrderedContainer { private final CraftingResultInventory resultInventory = new CraftingResultInventory(); private AttachedInventory attachedInventory; - private ItemStack knownCursorStack = ItemStack.EMPTY; + private ItemStack slotOrderPreviewStack = ItemStack.EMPTY; public Gui(ServerPlayerEntity player) { this(player, Optional.empty()); } @@ -277,8 +277,6 @@ public class WorkbenchBlockEntity extends OrderedContainer { attachedInventory.ifPresent(inventory -> this.attachedInventory = inventory); guis.add(this); - updateTitle(); - setSlot(BUTTON_COLUMN, new RotateGridButton(Icons.ROTATE_CLOCKWISE,1)); setSlot(BUTTON_COLUMN + 9, new RotateGridButton(Icons.ROTATE_COUNTER_CLOCKWISE, -1)); setSlotRedirect( @@ -297,15 +295,16 @@ public class WorkbenchBlockEntity extends OrderedContainer { inventory.redirectSlots(BASE_HEIGHT, this); }); - updateResult(); + update(); } public int getUnextendedSize() { return BASE_HEIGHT * 9; } - protected void updateResult() { + protected void update() { resultInventory.setStack(0, getResult(player)); + updateTitle(); } @Override @@ -315,20 +314,12 @@ public class WorkbenchBlockEntity extends OrderedContainer { } @Override - public boolean onAnyClick(int index, ClickType type, SlotActionType action) { - ItemStack cursorStack = screenHandler.getCursorStack(); - - Slot slot = getSlotRedirectOrPlayer(index); - if(type.equals(ClickType.MOUSE_LEFT) && slot != null) { - cursorStack = slot.getStack(); - } - - if(cursorStack != knownCursorStack) { - knownCursorStack = cursorStack; + public void onCursorStackChange(ItemStack stack) { + var different = stack.isEmpty() || !ItemStack.areItemsAndComponentsEqual(stack, slotOrderPreviewStack); + this.slotOrderPreviewStack = stack; + if(different) { updateTitle(); } - - return super.onAnyClick(index, type, action); } private void updateTitle() { @@ -350,28 +341,29 @@ public class WorkbenchBlockEntity extends OrderedContainer { private String getSlotOrderLiteral() { StringBuilder out = new StringBuilder(); + out.append(" ".repeat(GRID_START_COLUMN)); - if(knownCursorStack.isEmpty()) { + if(slotOrderPreviewStack.isEmpty()) { return out.toString(); } var placements = PlacementUtils.rotate( - PlacementUtils.getPlacements(knownCursorStack, (ServerWorld) world), + PlacementUtils.getPlacements(slotOrderPreviewStack, (ServerWorld) world), craftingOrientation ); for(int i = 0; i < 3; i++) { - boolean newCol = true; + boolean columnEmpty = true; for(int j = 0; j < 3; j++) { - int order = placements[j * 3 + i] - filledSlots() - 1; + int order = placements[j * 3 + i] - Math.max(filledSlots(), 1); if(order < 0) { continue; } - if(newCol) { - newCol = false; + if(columnEmpty) { + columnEmpty = false; out.append('.'); } else { out.append('-'); @@ -380,15 +372,13 @@ public class WorkbenchBlockEntity extends OrderedContainer { out.append(SLOT_ORDER_OVERLAY_FONT_MAP[j][order]); } - if(newCol) { + if(columnEmpty) { out.append(' '); } } out.append("___"); - Grafting.LOGGER.info("Test: {}", out.toString()); - return out.toString(); } diff --git a/src/main/java/net/sys42/dakedres/grafting/mixin/ExampleMixin.java b/src/main/java/net/sys42/dakedres/grafting/mixin/ExampleMixin.java index be05b06..bb7bbca 100644 --- a/src/main/java/net/sys42/dakedres/grafting/mixin/ExampleMixin.java +++ b/src/main/java/net/sys42/dakedres/grafting/mixin/ExampleMixin.java @@ -1,15 +1,18 @@ package net.sys42.dakedres.grafting.mixin; +import eu.pb4.sgui.virtual.inventory.VirtualScreenHandler; import net.minecraft.server.MinecraftServer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@Mixin(MinecraftServer.class) +@Mixin(VirtualScreenHandler.class) public class ExampleMixin { - @Inject(at = @At("HEAD"), method = "loadWorld") - private void init(CallbackInfo info) { - // This code is injected into the start of MinecraftServer.loadWorld()V - } +// @Inject(at = @At("TAIL"), method = "loadWorld") +// private void init(CallbackInfo info) { +// // This code is injected into the start of MinecraftServer.loadWorld()V +// } + + } \ No newline at end of file diff --git a/src/main/java/net/sys42/dakedres/grafting/ui/CursorListeningSimpleGui.java b/src/main/java/net/sys42/dakedres/grafting/ui/CursorListeningSimpleGui.java new file mode 100644 index 0000000..f95d6c5 --- /dev/null +++ b/src/main/java/net/sys42/dakedres/grafting/ui/CursorListeningSimpleGui.java @@ -0,0 +1,142 @@ +package net.sys42.dakedres.grafting.ui; + +import eu.pb4.sgui.api.elements.GuiElementInterface; +import eu.pb4.sgui.api.gui.SimpleGui; +import eu.pb4.sgui.api.gui.SlotGuiInterface; +import eu.pb4.sgui.virtual.SguiScreenHandlerFactory; +import eu.pb4.sgui.virtual.inventory.VirtualScreenHandler; +import eu.pb4.sgui.virtual.inventory.VirtualSlot; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.s2c.play.OpenScreenS2CPacket; +import net.minecraft.screen.NamedScreenHandlerFactory; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.Slot; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.OptionalInt; + +public abstract class CursorListeningSimpleGui extends SimpleGui { + private CursorListeningScreenHandler screenHandler = null; + private Text title; + + public CursorListeningSimpleGui(ScreenHandlerType type, ServerPlayerEntity player, boolean manipulatePlayerSlots) { + super(type, player, manipulatePlayerSlots); + } + + @Override + public void setSlot(int index, GuiElementInterface element) { + super.setSlot(index, element); + if (this.isOpen() && this.autoUpdate) { + this.screenHandler.setSlot(index, new VirtualSlot(this, index, 0, 0)); + } + + } + + @Override + public void setSlotRedirect(int index, Slot slot) { + super.setSlotRedirect(index, slot); + if (this.isOpen() && this.autoUpdate) { + this.screenHandler.setSlot(index, slot); + } + + } + + @Override + public void clearSlot(int index) { + super.clearSlot(index); + this.hasRedirects = true; + if (this.isOpen() && this.autoUpdate) { + this.screenHandler.setSlot(index, new VirtualSlot(this, index, 0, 0)); + } + + } + + @Override + public boolean isOpen() { + return this.screenHandler != null && this.screenHandler == this.player.currentScreenHandler; + } + + public Text getTitle() { + return this.title; + } + + @Override + public void setTitle(Text title) { + this.title = title; + if (this.isOpen()) { + this.player.networkHandler.sendPacket(new OpenScreenS2CPacket(this.syncId, this.type, title)); + this.screenHandler.syncState(); + } + + } + + @Override + protected boolean sendGui() { + this.reOpen = true; + OptionalInt temp = this.player.openHandledScreen(getFactory()); + this.reOpen = false; + if (temp.isPresent()) { + this.syncId = temp.getAsInt(); + if (this.player.currentScreenHandler instanceof CursorListeningScreenHandler) { + this.screenHandler = (CursorListeningScreenHandler) this.player.currentScreenHandler; + return true; + } + } + + return false; + } + + private NamedScreenHandlerFactory getFactory() { + return new SguiScreenHandlerFactory( + this, + (syncId, inv, player) -> new CursorListeningScreenHandler(getType(), syncId, this, player) + ); + } + + @Override + public ScreenHandler openAsScreenHandler(int syncId, PlayerInventory playerInventory, PlayerEntity player) { + if (!this.player.isDisconnected() && player == this.player && !this.isOpen()) { + this.beforeOpen(); + this.onOpen(); + this.screenHandler = new CursorListeningScreenHandler(this.getType(), syncId, this, player); + return this.screenHandler; + } else { + return null; + } + } + + public abstract void onCursorStackChange(ItemStack stack); + + @Override + public void close(boolean screenHandlerIsClosed) { + if ((this.isOpen() || screenHandlerIsClosed) && !this.reOpen) { + if (!screenHandlerIsClosed && this.player.currentScreenHandler == this.screenHandler) { + this.player.closeHandledScreen(); + this.screenHandler = null; + } + + this.player.currentScreenHandler.syncState(); + this.onClose(); + } else { + this.reOpen = false; + } + + } + + public class CursorListeningScreenHandler extends VirtualScreenHandler { + public CursorListeningScreenHandler(@Nullable ScreenHandlerType type, int syncId, SlotGuiInterface gui, PlayerEntity player) { + super(type, syncId, gui, player); + } + + @Override + public void setCursorStack(ItemStack stack) { + super.setCursorStack(stack); + onCursorStackChange(stack); + } + } +} diff --git a/src/main/resources/assets/grafting/font/slot_order_overlay.json b/src/main/resources/assets/grafting/font/slot_order_overlay.json index cfd5765..a1b3c1d 100644 --- a/src/main/resources/assets/grafting/font/slot_order_overlay.json +++ b/src/main/resources/assets/grafting/font/slot_order_overlay.json @@ -11,7 +11,7 @@ }, { "type": "bitmap", - "file": "grafting:gui/slots.png", + "file": "grafting:gui/slot_order_overlay.png", "ascent": -4, "height": 64, "chars": [ diff --git a/src/main/resources/assets/grafting/textures/gui/slot_order_overlay.png b/src/main/resources/assets/grafting/textures/gui/slot_order_overlay.png new file mode 100644 index 0000000..1016baf Binary files /dev/null and b/src/main/resources/assets/grafting/textures/gui/slot_order_overlay.png differ diff --git a/src/main/resources/assets/grafting/textures/gui/slot_order_overlay.xcf b/src/main/resources/assets/grafting/textures/gui/slot_order_overlay.xcf new file mode 100644 index 0000000..46eba3d Binary files /dev/null and b/src/main/resources/assets/grafting/textures/gui/slot_order_overlay.xcf differ diff --git a/src/main/resources/assets/grafting/textures/gui/slots.png b/src/main/resources/assets/grafting/textures/gui/slots.png deleted file mode 100644 index 9fe911f..0000000 Binary files a/src/main/resources/assets/grafting/textures/gui/slots.png and /dev/null differ diff --git a/src/main/resources/assets/grafting/textures/gui/slots.xcf b/src/main/resources/assets/grafting/textures/gui/slots.xcf deleted file mode 100644 index ba60fca..0000000 Binary files a/src/main/resources/assets/grafting/textures/gui/slots.xcf and /dev/null differ