Slot order preview pt. 2
Some checks failed
build / build (push) Has been cancelled

This commit is contained in:
Dakedres 2025-05-07 22:26:32 -06:00
parent f588ac5de8
commit 03e6cad098
8 changed files with 170 additions and 35 deletions

View File

@ -3,7 +3,6 @@ package net.sys42.dakedres.grafting.block.entity;
import eu.pb4.polymer.resourcepack.api.PolymerModelData; import eu.pb4.polymer.resourcepack.api.PolymerModelData;
import eu.pb4.sgui.api.ClickType; import eu.pb4.sgui.api.ClickType;
import eu.pb4.sgui.api.elements.GuiElement; import eu.pb4.sgui.api.elements.GuiElement;
import eu.pb4.sgui.api.gui.SimpleGui;
import eu.pb4.sgui.virtual.inventory.VirtualSlot; import eu.pb4.sgui.virtual.inventory.VirtualSlot;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.CrafterBlock; import net.minecraft.block.CrafterBlock;
@ -32,6 +31,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.sys42.dakedres.grafting.Grafting; import net.sys42.dakedres.grafting.Grafting;
import net.sys42.dakedres.grafting.PlacementUtils; import net.sys42.dakedres.grafting.PlacementUtils;
import net.sys42.dakedres.grafting.ui.CursorListeningSimpleGui;
import net.sys42.dakedres.grafting.ui.Icons; import net.sys42.dakedres.grafting.ui.Icons;
import java.util.ArrayList; import java.util.ArrayList;
@ -94,7 +94,7 @@ public class WorkbenchBlockEntity extends OrderedContainer {
@Override @Override
public void markDirty() { public void markDirty() {
for(Gui gui : guis) { for(Gui gui : guis) {
gui.updateResult(); gui.update();
} }
super.markDirty(); 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 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"); 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 final CraftingResultInventory resultInventory = new CraftingResultInventory();
private AttachedInventory attachedInventory; private AttachedInventory attachedInventory;
private ItemStack knownCursorStack = ItemStack.EMPTY; private ItemStack slotOrderPreviewStack = ItemStack.EMPTY;
public Gui(ServerPlayerEntity player) { public Gui(ServerPlayerEntity player) {
this(player, Optional.empty()); this(player, Optional.empty());
} }
@ -277,8 +277,6 @@ public class WorkbenchBlockEntity extends OrderedContainer {
attachedInventory.ifPresent(inventory -> this.attachedInventory = inventory); attachedInventory.ifPresent(inventory -> this.attachedInventory = inventory);
guis.add(this); guis.add(this);
updateTitle();
setSlot(BUTTON_COLUMN, new RotateGridButton(Icons.ROTATE_CLOCKWISE,1)); setSlot(BUTTON_COLUMN, new RotateGridButton(Icons.ROTATE_CLOCKWISE,1));
setSlot(BUTTON_COLUMN + 9, new RotateGridButton(Icons.ROTATE_COUNTER_CLOCKWISE, -1)); setSlot(BUTTON_COLUMN + 9, new RotateGridButton(Icons.ROTATE_COUNTER_CLOCKWISE, -1));
setSlotRedirect( setSlotRedirect(
@ -297,15 +295,16 @@ public class WorkbenchBlockEntity extends OrderedContainer {
inventory.redirectSlots(BASE_HEIGHT, this); inventory.redirectSlots(BASE_HEIGHT, this);
}); });
updateResult(); update();
} }
public int getUnextendedSize() { public int getUnextendedSize() {
return BASE_HEIGHT * 9; return BASE_HEIGHT * 9;
} }
protected void updateResult() { protected void update() {
resultInventory.setStack(0, getResult(player)); resultInventory.setStack(0, getResult(player));
updateTitle();
} }
@Override @Override
@ -315,20 +314,12 @@ public class WorkbenchBlockEntity extends OrderedContainer {
} }
@Override @Override
public boolean onAnyClick(int index, ClickType type, SlotActionType action) { public void onCursorStackChange(ItemStack stack) {
ItemStack cursorStack = screenHandler.getCursorStack(); var different = stack.isEmpty() || !ItemStack.areItemsAndComponentsEqual(stack, slotOrderPreviewStack);
this.slotOrderPreviewStack = stack;
Slot slot = getSlotRedirectOrPlayer(index); if(different) {
if(type.equals(ClickType.MOUSE_LEFT) && slot != null) {
cursorStack = slot.getStack();
}
if(cursorStack != knownCursorStack) {
knownCursorStack = cursorStack;
updateTitle(); updateTitle();
} }
return super.onAnyClick(index, type, action);
} }
private void updateTitle() { private void updateTitle() {
@ -350,28 +341,29 @@ public class WorkbenchBlockEntity extends OrderedContainer {
private String getSlotOrderLiteral() { private String getSlotOrderLiteral() {
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
out.append(" ".repeat(GRID_START_COLUMN)); out.append(" ".repeat(GRID_START_COLUMN));
if(knownCursorStack.isEmpty()) { if(slotOrderPreviewStack.isEmpty()) {
return out.toString(); return out.toString();
} }
var placements = PlacementUtils.rotate( var placements = PlacementUtils.rotate(
PlacementUtils.getPlacements(knownCursorStack, (ServerWorld) world), PlacementUtils.getPlacements(slotOrderPreviewStack, (ServerWorld) world),
craftingOrientation craftingOrientation
); );
for(int i = 0; i < 3; i++) { for(int i = 0; i < 3; i++) {
boolean newCol = true; boolean columnEmpty = true;
for(int j = 0; j < 3; j++) { 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) { if(order < 0) {
continue; continue;
} }
if(newCol) { if(columnEmpty) {
newCol = false; columnEmpty = false;
out.append('.'); out.append('.');
} else { } else {
out.append('-'); out.append('-');
@ -380,15 +372,13 @@ public class WorkbenchBlockEntity extends OrderedContainer {
out.append(SLOT_ORDER_OVERLAY_FONT_MAP[j][order]); out.append(SLOT_ORDER_OVERLAY_FONT_MAP[j][order]);
} }
if(newCol) { if(columnEmpty) {
out.append(' '); out.append(' ');
} }
} }
out.append("___"); out.append("___");
Grafting.LOGGER.info("Test: {}", out.toString());
return out.toString(); return out.toString();
} }

View File

@ -1,15 +1,18 @@
package net.sys42.dakedres.grafting.mixin; package net.sys42.dakedres.grafting.mixin;
import eu.pb4.sgui.virtual.inventory.VirtualScreenHandler;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftServer.class) @Mixin(VirtualScreenHandler.class)
public class ExampleMixin { public class ExampleMixin {
@Inject(at = @At("HEAD"), method = "loadWorld") // @Inject(at = @At("TAIL"), method = "loadWorld")
private void init(CallbackInfo info) { // private void init(CallbackInfo info) {
// This code is injected into the start of MinecraftServer.loadWorld()V // // This code is injected into the start of MinecraftServer.loadWorld()V
} // }
} }

View File

@ -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<CursorListeningSimpleGui>(
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);
}
}
}

View File

@ -11,7 +11,7 @@
}, },
{ {
"type": "bitmap", "type": "bitmap",
"file": "grafting:gui/slots.png", "file": "grafting:gui/slot_order_overlay.png",
"ascent": -4, "ascent": -4,
"height": 64, "height": 64,
"chars": [ "chars": [

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB