From 28009840618f0f72f73455bd2dea565856b94a56 Mon Sep 17 00:00:00 2001 From: ks <2777389616@qq.com> Date: Fri, 20 Jun 2025 20:58:44 +0800 Subject: [PATCH 1/2] fixed threshold switch not counting stacks correctly. cherry-picked from my previous 1.21.1 branch https://github.com/Creators-of-Create/Create/issues/7688#issue-2894355570 --- .../ThresholdSwitchBlockEntity.java | 109 +++++++++--------- .../ThresholdSwitchScreen.java | 21 ++-- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java index 26b901d7bc..e90ce0d68a 100644 --- a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java @@ -123,7 +123,6 @@ public int getMaxLevel() { } public void updateCurrentLevel() { - boolean changed = false; int prevLevel = currentLevel; int prevMaxLevel = currentMaxLevel; @@ -137,66 +136,68 @@ public void updateCurrentLevel() { currentMinLevel = observable.getMinValue(); currentLevel = observable.getCurrentValue(); currentMaxLevel = observable.getMaxValue(); - - /*} else if (StorageDrawers.isDrawer(targetBlockEntity) && observedInventory.hasInventory()) { - currentMinLevel = 0; - currentLevel = StorageDrawers.getItemCount(observedInventory.getInventory(), filtering); - currentMaxLevel = StorageDrawers.getTotalStorageSpace(observedInventory.getInventory()); - */ - - } else if (observedInventory.hasInventory() || observedTank.hasInventory()) { + } else if (observedInventory.hasInventory()) { currentMinLevel = 0; currentLevel = 0; currentMaxLevel = 0; - if (observedInventory.hasInventory()) { - - // Item inventory - IItemHandler inv = observedInventory.getInventory(); - if (invVersionTracker.stillWaiting(inv)) { - currentLevel = prevLevel; - currentMaxLevel = prevMaxLevel; - - } else { - invVersionTracker.awaitNewVersion(inv); - for (int slot = 0; slot < inv.getSlots(); slot++) { - ItemStack stackInSlot = inv.getStackInSlot(slot); - - int finalSlot = slot; - long space = COMPAT - .stream() - .filter(compat -> compat.isFromThisMod(targetBlockEntity)) - .map(compat -> compat.getSpaceInSlot(inv, finalSlot)) - .findFirst() - .orElseGet(() -> (long) Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(finalSlot))); - - int count = stackInSlot.getCount(); - if (space == 0) - continue; - + IItemHandler inv = observedInventory.getInventory(); + if (invVersionTracker.stillWaiting(inv)) { + currentLevel = prevLevel; + currentMaxLevel = prevMaxLevel; + } else { + invVersionTracker.awaitNewVersion(inv); + for (int slot = 0; slot < inv.getSlots(); slot++) { + ItemStack stackInSlot = inv.getStackInSlot(slot); + + final int slotClone = slot; + long space = COMPAT.stream() + .filter(compat -> compat.isFromThisMod(targetBlockEntity)) + .map(compat -> compat.getSpaceInSlot(inv, slotClone)) + .findFirst() + .orElseGet(() -> (long) Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slotClone))); + + if (space == 0) continue; + + if (inStacks) { + // When counting in stacks, each slot has 1 unit of capacity + currentMaxLevel += 1; + + if (filtering.test(stackInSlot)) { + // only count full stacks as 1, partial stacks as 0 + if (stackInSlot.getCount() == space) { + currentLevel += 1; + } + } + } else { + // When counting individual items, use actual item capacity currentMaxLevel += space; - if (filtering.test(stackInSlot)) - currentLevel += count; + + // Count items that pass the filter + if (filtering.test(stackInSlot)) { + currentLevel += stackInSlot.getCount(); + } } } } + } else if (observedTank.hasInventory()) { + currentMinLevel = 0; + currentLevel = 0; + currentMaxLevel = 0; - if (observedTank.hasInventory()) { - // Fluid inventory - IFluidHandler tank = observedTank.getInventory(); - for (int slot = 0; slot < tank.getTanks(); slot++) { - FluidStack stackInSlot = tank.getFluidInTank(slot); - int space = tank.getTankCapacity(slot); - int count = stackInSlot.getAmount(); - if (space == 0) - continue; - - currentMaxLevel += space; - if (filtering.test(stackInSlot)) - currentLevel += count; + // Fluid inventory + IFluidHandler tank = observedTank.getInventory(); + for (int slot = 0; slot < tank.getTanks(); slot++) { + FluidStack stackInSlot = tank.getFluidInTank(slot); + int space = tank.getTankCapacity(slot); + int count = stackInSlot.getAmount(); + if (space == 0) continue; + + currentMaxLevel += space; + if (filtering.test(stackInSlot)) { + currentLevel += count; } } - } else { // No compatible inventories found currentMinLevel = -1; @@ -213,7 +214,8 @@ public void updateCurrentLevel() { } currentLevel = Mth.clamp(currentLevel, currentMinLevel, currentMaxLevel); - changed = currentLevel != prevLevel; + boolean levelChanged = currentLevel != prevLevel; + boolean anyChanged = levelChanged || currentMaxLevel != prevMaxLevel || currentMinLevel != prevLevel; boolean previouslyPowered = redstoneState; if (redstoneState && currentLevel <= offWhenBelow) @@ -232,10 +234,11 @@ else if (!redstoneState && currentLevel >= onWhenAbove) if (update) scheduleBlockTick(); - if (changed || update) { + if (levelChanged || update) DisplayLinkBlock.notifyGatherers(level, worldPosition); + + if (anyChanged) notifyUpdate(); - } } private boolean isSuitableInventory(BlockEntity be) { diff --git a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchScreen.java b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchScreen.java index 330006ff61..b5a26c990d 100644 --- a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchScreen.java +++ b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchScreen.java @@ -67,6 +67,7 @@ protected void init() { .forOptions(List.of(CreateLang.translateDirect("schedule.condition.threshold.items"), CreateLang.translateDirect("schedule.condition.threshold.stacks"))) .titled(CreateLang.translateDirect("schedule.condition.threshold.item_measure")) + .calling((state) -> send(blockEntity.isInverted())) .setState(blockEntity.inStacks ? 1 : 0); offBelow = new ScrollInput(x + 48, y + 47, 1, 18) @@ -78,7 +79,6 @@ protected void init() { if (onAbove.getState() / valueStep == 0 && state / valueStep == 0) return; - if (onAbove.getState() / valueStep <= state / valueStep) { onAbove.setState((state + valueStep) / valueStep * valueStep); onAbove.onChanged(); @@ -152,19 +152,16 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float inputBg.render(graphics, x + 44, y + 21); inputBg.render(graphics, x + 44, y + 21 + 24); - int valueStep = 1; + int valueStep = typeOfCurrentTarget == ThresholdType.FLUID ? 1000 : 1; boolean stacks = inStacks.getState() == 1; - if (typeOfCurrentTarget == ThresholdType.FLUID) - valueStep = 1000; if (forItems) { Component suffix = - inStacks.getState() == 0 ? CreateLang.translateDirect("schedule.condition.threshold.items") - : CreateLang.translateDirect("schedule.condition.threshold.stacks"); - valueStep = inStacks.getState() == 0 ? 1 : 64; + stacks + ? CreateLang.translateDirect("schedule.condition.threshold.stacks") + : CreateLang.translateDirect("schedule.condition.threshold.items"); graphics.drawString(font, suffix, x + 105, y + 28, 0xFFFFFFFF, true); graphics.drawString(font, suffix, x + 105, y + 28 + 24, 0xFFFFFFFF, true); - } graphics.drawString(font, @@ -327,13 +324,9 @@ private void updateInputBoxes() { } private int getValueStep() { - boolean stacks = inStacks.getState() == 1; - int valueStep = 1; if (blockEntity.getTypeOfCurrentTarget() == ThresholdType.FLUID) - valueStep = 1000; - else if (stacks) - valueStep = 64; - return valueStep; + return 1000; + return 1; } @Override From 6f1179efb7e3d9dbaf5ed1640509d27844fe16bd Mon Sep 17 00:00:00 2001 From: ks <2777389616@qq.com> Date: Fri, 27 Jun 2025 17:39:24 +0800 Subject: [PATCH 2/2] fixed threshold switch not updating when configuring if it is targeting a vault --- .../ConfigureThresholdSwitchPacket.java | 8 +++--- .../ThresholdSwitchBlockEntity.java | 27 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ConfigureThresholdSwitchPacket.java b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ConfigureThresholdSwitchPacket.java index 9f5a9fe4ac..c8f413c556 100644 --- a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ConfigureThresholdSwitchPacket.java +++ b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ConfigureThresholdSwitchPacket.java @@ -19,11 +19,11 @@ public ConfigureThresholdSwitchPacket(BlockPos pos, int offBelow, int onAbove, b this.invert = invert; this.inStacks = inStacks; } - + public ConfigureThresholdSwitchPacket(FriendlyByteBuf buffer) { super(buffer); } - + @Override protected void readSettings(FriendlyByteBuf buffer) { offBelow = buffer.readInt(); @@ -45,7 +45,7 @@ protected void applySettings(ThresholdSwitchBlockEntity be) { be.offWhenBelow = offBelow; be.onWhenAbove = onAbove; be.setInverted(invert); - be.inStacks = inStacks; + be.setInStacks(inStacks); } - + } diff --git a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java index e90ce0d68a..bd8af39f02 100644 --- a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.redstone.thresholdSwitch; import java.util.List; +import java.util.Optional; import com.simibubi.create.compat.thresholdSwitch.FunctionalStorage; import com.simibubi.create.compat.thresholdSwitch.SophisticatedStorage; @@ -147,15 +148,19 @@ public void updateCurrentLevel() { currentMaxLevel = prevMaxLevel; } else { invVersionTracker.awaitNewVersion(inv); + Optional compatibilityHandler = COMPAT.stream() + .filter(compat -> compat.isFromThisMod(targetBlockEntity)) + .findFirst(); + for (int slot = 0; slot < inv.getSlots(); slot++) { ItemStack stackInSlot = inv.getStackInSlot(slot); - final int slotClone = slot; - long space = COMPAT.stream() - .filter(compat -> compat.isFromThisMod(targetBlockEntity)) - .map(compat -> compat.getSpaceInSlot(inv, slotClone)) - .findFirst() - .orElseGet(() -> (long) Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slotClone))); + long space; + if (compatibilityHandler.isPresent()){ + space = compatibilityHandler.get().getSpaceInSlot(inv, slot); + } else { + space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot)); + } if (space == 0) continue; @@ -350,4 +355,14 @@ public void setInverted(boolean inverted) { this.inverted = inverted; updatePowerAfterDelay(); } + + public void setInStacks(Boolean value) { + // When configuration values such as inStacks are changed from the screen, + // ensure that the next tick recalculates the inventory even if its version + // has not changed yet. + inStacks = value; + if (invVersionTracker != null) + invVersionTracker.reset(); + updateCurrentLevel(); + } }