From 03e6cad0985c150cb693a575f20449008264d8df Mon Sep 17 00:00:00 2001 From: Dakedres Date: Wed, 7 May 2025 22:26:32 -0600 Subject: [PATCH] Slot order preview pt. 2 --- .../block/entity/WorkbenchBlockEntity.java | 48 +++--- .../dakedres/grafting/mixin/ExampleMixin.java | 13 +- .../grafting/ui/CursorListeningSimpleGui.java | 142 ++++++++++++++++++ .../grafting/font/slot_order_overlay.json | 2 +- .../textures/gui/slot_order_overlay.png | Bin 0 -> 1119 bytes .../textures/gui/slot_order_overlay.xcf | Bin 0 -> 68268 bytes .../assets/grafting/textures/gui/slots.png | Bin 1353 -> 0 bytes .../assets/grafting/textures/gui/slots.xcf | Bin 87049 -> 0 bytes 8 files changed, 170 insertions(+), 35 deletions(-) create mode 100644 src/main/java/net/sys42/dakedres/grafting/ui/CursorListeningSimpleGui.java create mode 100644 src/main/resources/assets/grafting/textures/gui/slot_order_overlay.png create mode 100644 src/main/resources/assets/grafting/textures/gui/slot_order_overlay.xcf delete mode 100644 src/main/resources/assets/grafting/textures/gui/slots.png delete mode 100644 src/main/resources/assets/grafting/textures/gui/slots.xcf 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 0000000000000000000000000000000000000000..1016bafd9447ae8c7704c8b7810fcf93e42da5b7 GIT binary patch literal 1119 zcmeAS@N?(olHy`uVBq!ia0y~yVB7#?J8-Z8$?DZg?LdK+OlRi+PiJR^f};Gi%$!sP z291fe6RkZC2Z*%&w_Bp5%NHh4cp_l#n@8Noqgs_hIJP>i=2J7Tb)4L$a`b3mfv&}m zh&5I_EMC8QpvBR|FHnBa^P;Pljk)HQj*kbP*8TbZ$Nu{~?jN&5m(4oJvLI{PL{HV$ zn7UAoy-FR9KMZ<1j`-C2iCq4$W_|UmCA+#m>%8A*uf0gbhwTT;BbLj&-4)FhX_qfq zz87|nj11~H-+7#Om%>No>#5W4TTGYv_W8_;iD%CUyLYw*iJy)=bE?hD##JUbr1#Tb z%ju%$qUT)An!EM=$#@C94DHh~%T1d^#5S@BGNoJzbQBePv?Y7Vj1w0sFCDgj^TW01 z+Rnx z{p1^T&T7>%%g8V#tDcJcUQwR^{m#F)ndjfLw`movo1paD9~docN#5=*4Ba5OqJD}g zP=vFEaktaqI2fgSl%Q z1XwQITj9|X($N%R#&_wEy1Y(r*uAz!x6k*UX6u(8Uiz!|NcOB{wtTamTi$zLenL_| zJ#tz&!<~mcOt-(+$}6Vd-ey1Z|KHlObMN23*`NNbqN%}%b=uFzx3qc|Te|<-acZaD zabcE-1m-6x)5G7(aPtHtO#J_T<2}o1lUdm`HYAGAkemxX5M^&L1#mfWnO}qM8J*%cMd#>NN8YHQ;+IakN%XGz#z+ghW88;^M(Um zPj@s%COA9gaU?m3jL_(wJ=|Z5B8xFBPV^cfM#H?drc`?f7 z=A?3F<`)qOAWt-~hUpv!IhhOOZ(wL_IPk^2=rs)DA~Uu}Jgu4hn3G9o!w0d|+annBbPV!0MkO$aMQoG- z`BozaXj_qv!2zbp!fTIC)~z%*Xy^kvDvetHIG|dyF{)3$iW!)|kimgKdx`7Y^^H{S QcYuUFUHx3vIVCg!0EE`!*8l(j literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..46eba3d929ba789ba6e8c40cf75efd19a38a74e4 GIT binary patch literal 68268 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 D%v;)* literal 0 HcmV?d00001 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 9fe911ff3bc1706a3e3072efc4b98c81f17a0da6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1353 zcmeAS@N?(olHy`uVBq!ia0y~yVB7#?J8-Z8$?DZg?LdLnOlRi+PiJR^f};Gi%$!sP z291fe6Ky>XJIEZ3x8I^9D%jm&k+Om>NnEsWO{j)bYk>BaR|!Qg+b=9p^eikCiQ(p} z(+QJ}nNwO?Aj)!(U!eS;=S5eqKk-2sf{zat+TXideP=K8pRY#2XA@)sOiz2L3p<%@ zS89n9bdk3*Y%uJc`D=~FvImy?-aUN$I<_aha{lk)FB+AT8SNS^&XpWiic_C=Z%fI! z-$w+)CW$;MepJ}3=ke!6>CLC+=Um(W+88ILTq-^yn6&W5u_EcslNJj33%ZMjF0QG+ zmfHGREPZQC>e=c~;%%RAeGK$~4GlNv8e7hw?>#ly;^R z2n z3eK@h^BS6+6SjEV%$9rqF6;f<`^IPg)iE?@7p4ojv)I-@#+PlUuc!8t=Atf3i7S5?{E% ze9xOh-_va5t}k4?cI{gErBed=i}y_rx>h}-IL2${7lY+mOKV;xo?9MtYE8T4?4?uI z+n%Y6_uBa`@!ajbd-ujOCNQ$CUcH*#@R)%NU;Uc3Yk6&urdUn8%V{!Kr(y}P^n+VeYe zZeG0_`novp+`+SFeL?h-Z{N0kwKPwE{O;X45M5GVfB)B<*~T?BH957{N@J^=8d~EL zV)fQfxm5bO{l?QzUYfPp&q{Xg3G&*U<~RMc_R^9IXI>UnE}f!wc8=ckaIeh8GcSWw z_0F;c>$;Qwv45r|O1|a70X=DUqO#=p?u!zJ1Od+r;o&b5zT!alo&z;UUulQMZ)8Gp5+VD+ zE@MRZ77wyZl?Ih>U~fa}yVTw|~CpR_{GCBWCX8#oK%D#hO)tf>&%t z`HFiBtJ=BtoZvnazGh$2S5a+gTe~DWM4fkh4(D 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 ba60fca6f7c35d115c0d646aa470a716d471daca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87049 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