Skip to content

Commit df6df1d

Browse files
authored
Merge pull request #14 from octoturt/mc1.21
Backport bundle fix from 1.21.2 (octoturt)
2 parents 824a204 + 355b079 commit df6df1d

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

common/src/main/java/dev/terminalmc/clientsort/inventory/sort/InventorySorter.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
2323
import net.minecraft.world.inventory.ClickType;
2424
import net.minecraft.world.inventory.Slot;
25-
import net.minecraft.world.item.ItemStack;
25+
import net.minecraft.world.item.*;
2626

2727
import java.util.ArrayDeque;
2828
import java.util.ArrayList;
@@ -136,6 +136,17 @@ protected void sortOnClient(int[] sortedIds) {
136136
}
137137
if (stacks[i].isEmpty()) doneSlashEmpty.set(slotCount + i); // mark if it's empty
138138
}
139+
140+
// Bundles require special handling. Specifically, to perform a swap between the carried
141+
// item and the target slot, you normally use left-click (0), but if holding a bundle
142+
// you must use right-click (1).
143+
// It isn't possible to always use right-click because right-clicking a bundle on an empty
144+
// slot does nothing, and right-clicking on a stack while carrying nothing takes half.
145+
// The current workaround is to maintain a copy of the theoretical inventory state to inform
146+
// the click decision. This will break if items enter or leave the inventory unexpectedly.
147+
Item carriedItem = Items.AIR;
148+
Item[] backingStacks = Arrays.stream(stacks.clone()).map(ItemStack::getItem).toArray(Item[]::new);
149+
139150
// Iterate all slots, with i as the target slot index
140151
// sortedIds[i] is therefore the origin slot
141152
for (int i = 0; i < slotCount; i++) {
@@ -149,8 +160,11 @@ protected void sortOnClient(int[] sortedIds) {
149160

150161
// This is where the action happens.
151162
// Pick up the stack at the origin slot.
152-
InteractionManager.push(screenHelper.createClickEvent(inventorySlots[sortedIds[i]], 0, ClickType.PICKUP));
153-
doneSlashEmpty.set(slotCount + sortedIds[i]); // Mark the origin slot as empty (because we picked the stack up, duh)
163+
Item temp = backingStacks[sortedIds[i]];
164+
backingStacks[sortedIds[i]] = carriedItem;
165+
carriedItem = temp;
166+
InteractionManager.push(screenHelper.createClickEvent(inventorySlots[sortedIds[i]], 0, ClickType.PICKUP));
167+
doneSlashEmpty.set(slotCount + sortedIds[i]); // Mark the origin slot as empty (because we picked the stack up, duh)
154168
currentStack = stacks[sortedIds[i]]; // Save the stack we're currently working with
155169
Slot workingSlot = inventorySlots[sortedIds[i]]; // A slot that we can use when fiddling around with swapping stacks
156170
int id = i; // id will reflect the target slot in the following loop
@@ -170,6 +184,9 @@ protected void sortOnClient(int[] sortedIds) {
170184
if (currentStack.getCount() < stacks[id].getCount()) { // Clicking with a low stack on a full stack does nothing
171185
// The workaround is: click working slot, click target slot, click working slot, click target slot, click working slot
172186
Slot targetSlot = inventorySlots[id];
187+
temp = backingStacks[id];
188+
backingStacks[id] = carriedItem;
189+
carriedItem = temp;
173190
InteractionManager.push(screenHelper.createClickEvent(workingSlot, 0, ClickType.PICKUP));
174191
InteractionManager.push(screenHelper.createClickEvent(targetSlot, 0, ClickType.PICKUP));
175192
InteractionManager.push(screenHelper.createClickEvent(workingSlot, 0, ClickType.PICKUP));
@@ -184,7 +201,18 @@ protected void sortOnClient(int[] sortedIds) {
184201
}
185202

186203
// swap the current stack with the target stack
187-
InteractionManager.push(screenHelper.createClickEvent(inventorySlots[id], 0, ClickType.PICKUP));
204+
if ((backingStacks[id] instanceof BundleItem && !(carriedItem instanceof AirItem))
205+
|| (carriedItem instanceof BundleItem && !(backingStacks[id] instanceof AirItem))) {
206+
temp = backingStacks[id];
207+
backingStacks[id] = carriedItem;
208+
carriedItem = temp;
209+
InteractionManager.push(screenHelper.createClickEvent(inventorySlots[id], 1, ClickType.PICKUP));
210+
} else {
211+
temp = backingStacks[id];
212+
backingStacks[id] = carriedItem;
213+
carriedItem = temp;
214+
InteractionManager.push(screenHelper.createClickEvent(inventorySlots[id], 0, ClickType.PICKUP));
215+
}
188216
currentStack = stacks[id];
189217
doneSlashEmpty.set(id); // mark the current target as done
190218
// If the target that we just swapped with was empty before, then this breaks the chain.

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Neo/Forge version ranges: https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
33

44
# Project
5-
mod_version=1.0.1+1.21
5+
mod_version=1.0.1+1.21-bundlefix
66
mod_group=dev.terminalmc
77
mod_id=clientsort
88
mod_name=ClientSort

0 commit comments

Comments
 (0)