diff --git a/src/main/java/techreborn/blockentity/storage/item/StorageUnitBaseBlockEntity.java b/src/main/java/techreborn/blockentity/storage/item/StorageUnitBaseBlockEntity.java index b2bfeac48..bfe8a35c4 100644 --- a/src/main/java/techreborn/blockentity/storage/item/StorageUnitBaseBlockEntity.java +++ b/src/main/java/techreborn/blockentity/storage/item/StorageUnitBaseBlockEntity.java @@ -68,6 +68,10 @@ public class StorageUnitBaseBlockEntity extends MachineBaseBlockEntity private TRContent.StorageUnit type; + // A locked storage unit will continue behaving as if it contains + // the locked-in item, even if the stored amount drops to zero. + private ItemStack lockedItemStack = ItemStack.EMPTY; + public StorageUnitBaseBlockEntity() { super(TRBlockEntities.STORAGE_UNIT); } @@ -170,6 +174,16 @@ public class StorageUnitBaseBlockEntity extends MachineBaseBlockEntity return storeItemStack.isEmpty() ? inventory.getInvStack(OUTPUT_SLOT) : storeItemStack; } + // Returns the ItemStack to be displayed to the player via UI / model + public ItemStack getDisplayedStack() { + if (!isLocked()) { + return getStoredStack(); + } else { + // Render the locked stack even if the unit is empty + return lockedItemStack; + } + } + public ItemStack getAll() { ItemStack returnStack = ItemStack.EMPTY; @@ -222,6 +236,10 @@ public class StorageUnitBaseBlockEntity extends MachineBaseBlockEntity } public boolean isSameType(ItemStack inputStack) { + if (isLocked()) { + return ItemUtils.isItemEqual(lockedItemStack, inputStack, true, true); + } + if (inputStack != ItemStack.EMPTY) { return ItemUtils.isItemEqual(getStoredStack(), inputStack, true, true); } @@ -281,6 +299,10 @@ public class StorageUnitBaseBlockEntity extends MachineBaseBlockEntity storeItemStack.setCount(Math.min(tagCompound.getInt("storedQuantity"), this.maxCapacity)); } + if (tagCompound.contains("lockedItem")) { + lockedItemStack = ItemStack.fromTag(tagCompound.getCompound("lockedItem")); + } + inventory.read(tagCompound); } @@ -300,6 +322,11 @@ public class StorageUnitBaseBlockEntity extends MachineBaseBlockEntity } else { tagCompound.putInt("storedQuantity", 0); } + + if (isLocked()) { + tagCompound.put("lockedItem", lockedItemStack.toTag(new CompoundTag())); + } + inventory.write(tagCompound); return tagCompound; } @@ -377,13 +404,50 @@ public class StorageUnitBaseBlockEntity extends MachineBaseBlockEntity // Inventory gets dropped automatically } + // The int methods are only for ContainerBuilder.sync() + private int isLockedInt() { + return isLocked() ? 1 : 0; + } + + private void setLockedInt(int lockedInt) { + setLocked(lockedInt == 1); + } + + public boolean isLocked() { + return lockedItemStack != ItemStack.EMPTY; + } + + public void setLocked(boolean value) { + // Only set lockedItem in response to user input + if (isLocked() == value) { + return; + } + + lockedItemStack = value ? getStoredStack().copy() : ItemStack.EMPTY; + } + + public boolean canModifyLocking() { + // Can always be unlocked + if (isLocked()) { + return true; + } + + // Can only lock if there is an item to lock + return !isEmpty(); + } + public BuiltContainer createContainer(int syncID, final PlayerEntity player) { return new ContainerBuilder("chest").player(player.inventory).inventory().hotbar().addInventory() - .blockEntity(this).slot(0, 100, 53).outputSlot(1, 140, 53).addInventory().create(this, syncID); + .blockEntity(this).slot(0, 100, 53).outputSlot(1, 140, 53) + .sync(this::isLockedInt, this::setLockedInt).addInventory().create(this, syncID); } @Override public boolean isValidInvStack(int slot, ItemStack stack) { + if (slot == INPUT_SLOT && isLocked()) { + return ItemUtils.isItemEqual(lockedItemStack, stack, true, true); + } + if (slot == INPUT_SLOT && !(isEmpty() || isSameType(stack))) { return false; } diff --git a/src/main/java/techreborn/client/gui/GuiStorageUnit.java b/src/main/java/techreborn/client/gui/GuiStorageUnit.java index 48d6e8527..4e8879330 100644 --- a/src/main/java/techreborn/client/gui/GuiStorageUnit.java +++ b/src/main/java/techreborn/client/gui/GuiStorageUnit.java @@ -29,6 +29,8 @@ import reborncore.client.containerBuilder.builder.BuiltContainer; import reborncore.client.gui.builder.GuiBase; import reborncore.common.util.StringUtils; import techreborn.blockentity.storage.item.StorageUnitBaseBlockEntity; +import reborncore.common.network.NetworkManager; +import techreborn.packets.ServerboundPackets; public class GuiStorageUnit extends GuiBase { @@ -49,17 +51,19 @@ public class GuiStorageUnit extends GuiBase { drawString(StringUtils.t("gui.techreborn.unit.out"), 140, 43, 4210752, layer); drawSlot(140, 53, layer); + + builder.drawLockButton(this, 150, 4, mouseX, mouseY, layer, storageEntity.isLocked()); } @Override protected void drawForeground(final int mouseX, final int mouseY) { super.drawForeground(mouseX, mouseY); - if (storageEntity.isEmpty()) { + if (storageEntity.isEmpty() && !storageEntity.isLocked()) { font.draw(StringUtils.t("techreborn.tooltip.unit.empty"), 10, 20, 4210752); } else { font.draw(StringUtils.t("gui.techreborn.storage.store"), 10, 20, 4210752); - font.draw(storageEntity.getStoredStack().getName().asString(), 10, 30, 4210752); + font.draw(storageEntity.getDisplayedStack().getName().asString(), 10, 30, 4210752); font.draw(StringUtils.t("gui.techreborn.storage.amount"), 10, 50, 4210752); @@ -72,4 +76,13 @@ public class GuiStorageUnit extends GuiBase { font.draw(StringUtils.t("gui.techreborn.unit.wrenchtip"), 10, 80, 16711680); } } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (isPointInRect(150, 4, 20, 12, mouseX, mouseY) && storageEntity.canModifyLocking()) { + NetworkManager.sendToServer(ServerboundPackets.createPacketStorageUnitLock(storageEntity, !storageEntity.isLocked())); + return true; + } + return super.mouseClicked(mouseX, mouseY, mouseButton); + } } diff --git a/src/main/java/techreborn/client/render/entitys/StorageUnitRenderer.java b/src/main/java/techreborn/client/render/entitys/StorageUnitRenderer.java index d20f63c7c..846f27a5b 100644 --- a/src/main/java/techreborn/client/render/entitys/StorageUnitRenderer.java +++ b/src/main/java/techreborn/client/render/entitys/StorageUnitRenderer.java @@ -50,7 +50,7 @@ public class StorageUnitRenderer extends BlockEntityRenderer { + BlockPos machinePos = extendedPacketBuffer.readBlockPos(); + boolean locked = extendedPacketBuffer.readBoolean(); + + context.getTaskQueue().execute(() -> { + BlockEntity BlockEntity = context.getPlayer().world.getBlockEntity(machinePos); + if (BlockEntity instanceof StorageUnitBaseBlockEntity) { + ((StorageUnitBaseBlockEntity) BlockEntity).setLocked(locked); + } + }); + }); + registerPacketHandler(REFUND, (extendedPacketBuffer, context) -> { if(!TechRebornConfig.allowManualRefund){ return; @@ -188,6 +202,13 @@ public class ServerboundPackets { }); } + public static Packet createPacketStorageUnitLock(StorageUnitBaseBlockEntity machine, boolean locked) { + return NetworkManager.createServerBoundPacket(STORAGE_UNIT_LOCK, extendedPacketBuffer -> { + extendedPacketBuffer.writeBlockPos(machine.getPos()); + extendedPacketBuffer.writeBoolean(locked); + }); + } + public static Packet createRefundPacket(){ return NetworkManager.createServerBoundPacket(REFUND, extendedPacketBuffer -> {