Skip to content

Commit

Permalink
Add bundle workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
NotRyken committed Oct 23, 2024
1 parent 9dc54e2 commit c2e6dac
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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++) {
Expand All @@ -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
Expand All @@ -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));
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c2e6dac

Please sign in to comment.