From c2e6dac9f361060e46acaa2b54930dba1e134b7c Mon Sep 17 00:00:00 2001 From: NotRyken <127091011+NotRyken@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:48:19 +0800 Subject: [PATCH] Add bundle workaround --- .../inventory/sort/InventorySorter.java | 36 ++++++++++++++++--- gradle.properties | 2 +- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/dev/terminalmc/clientsort/inventory/sort/InventorySorter.java b/common/src/main/java/dev/terminalmc/clientsort/inventory/sort/InventorySorter.java index 5eea99f..94e80be 100644 --- a/common/src/main/java/dev/terminalmc/clientsort/inventory/sort/InventorySorter.java +++ b/common/src/main/java/dev/terminalmc/clientsort/inventory/sort/InventorySorter.java @@ -23,7 +23,7 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.inventory.ClickType; import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.*; import java.util.ArrayDeque; import java.util.ArrayList; @@ -137,6 +137,17 @@ protected void sortOnClient(int[] sortedIds) { } if (stacks[i].isEmpty()) doneSlashEmpty.set(slotCount + i); // mark if it's empty } + + // Bundles require special handling. Specifically, to perform a swap between the carried + // item and the target slot, you normally use left-click (0), but if holding a bundle + // you must use right-click (1). + // It isn't possible to always use right-click because right-clicking a bundle on an empty + // slot does nothing, and right-clicking on a stack while carrying nothing takes half. + // The current workaround is to maintain a copy of the theoretical inventory state to inform + // the click decision. This will break if items enter or leave the inventory unexpectedly. + Item carriedItem = Items.AIR; + Item[] backingStacks = Arrays.stream(stacks.clone()).map(ItemStack::getItem).toArray(Item[]::new); + // Iterate all slots, with i as the target slot index // sortedIds[i] is therefore the origin slot for (int i = 0; i < slotCount; i++) { @@ -150,8 +161,11 @@ protected void sortOnClient(int[] sortedIds) { // This is where the action happens. // Pick up the stack at the origin slot. - InteractionManager.push(screenHelper.createClickEvent(inventorySlots[sortedIds[i]], 0, ClickType.PICKUP)); - doneSlashEmpty.set(slotCount + sortedIds[i]); // Mark the origin slot as empty (because we picked the stack up, duh) + Item temp = backingStacks[sortedIds[i]]; + backingStacks[sortedIds[i]] = carriedItem; + carriedItem = temp; + InteractionManager.push(screenHelper.createClickEvent(inventorySlots[sortedIds[i]], 0, ClickType.PICKUP)); + doneSlashEmpty.set(slotCount + sortedIds[i]); // Mark the origin slot as empty (because we picked the stack up, duh) currentStack = stacks[sortedIds[i]]; // Save the stack we're currently working with Slot workingSlot = inventorySlots[sortedIds[i]]; // A slot that we can use when fiddling around with swapping stacks int id = i; // id will reflect the target slot in the following loop @@ -171,6 +185,9 @@ protected void sortOnClient(int[] sortedIds) { if (currentStack.getCount() < stacks[id].getCount()) { // Clicking with a low stack on a full stack does nothing // The workaround is: click working slot, click target slot, click working slot, click target slot, click working slot Slot targetSlot = inventorySlots[id]; + temp = backingStacks[id]; + backingStacks[id] = carriedItem; + carriedItem = temp; InteractionManager.push(screenHelper.createClickEvent(workingSlot, 0, ClickType.PICKUP)); InteractionManager.push(screenHelper.createClickEvent(targetSlot, 0, ClickType.PICKUP)); InteractionManager.push(screenHelper.createClickEvent(workingSlot, 0, ClickType.PICKUP)); @@ -185,7 +202,18 @@ protected void sortOnClient(int[] sortedIds) { } // swap the current stack with the target stack - InteractionManager.push(screenHelper.createClickEvent(inventorySlots[id], 0, ClickType.PICKUP)); + if ((backingStacks[id] instanceof BundleItem && !(carriedItem instanceof AirItem)) + || (carriedItem instanceof BundleItem && !(backingStacks[id] instanceof AirItem))) { + temp = backingStacks[id]; + backingStacks[id] = carriedItem; + carriedItem = temp; + InteractionManager.push(screenHelper.createClickEvent(inventorySlots[id], 1, ClickType.PICKUP)); + } else { + temp = backingStacks[id]; + backingStacks[id] = carriedItem; + carriedItem = temp; + InteractionManager.push(screenHelper.createClickEvent(inventorySlots[id], 0, ClickType.PICKUP)); + } currentStack = stacks[id]; doneSlashEmpty.set(id); // mark the current target as done // If the target that we just swapped with was empty before, then this breaks the chain. diff --git a/gradle.properties b/gradle.properties index 99bc8d8..1ce822a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # Neo/Forge version ranges: https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html # Project -mod_version=21.2.0-beta.01 +mod_version=21.2.0-beta.02 mod_group=dev.terminalmc mod_id=clientsort mod_name=ClientSort