Skip to content

Commit a3fd31b

Browse files
committed
Refactor "ClickEvent to "InvAction", with broader definition
1 parent d4490fa commit a3fd31b

11 files changed

Lines changed: 202 additions & 179 deletions

src/main/java/net/evmodder/evmod/apis/ClickUtils.java

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@
1111
import net.evmodder.evmod.Main;
1212
import net.evmodder.evmod.mixin.AccessorPlayerListHud;
1313
import net.minecraft.client.MinecraftClient;
14+
import net.minecraft.network.packet.c2s.play.BundleItemSelectedC2SPacket;
1415
import net.minecraft.screen.slot.SlotActionType;
1516
import net.minecraft.text.MutableText;
1617
import net.minecraft.text.Text;
1718

1819
public class ClickUtils{
19-
public record ClickEvent(int slotId, int button, SlotActionType actionType){}
20+
public enum ActionType{
21+
CLICK(SlotActionType.PICKUP),
22+
SHIFT_CLICK(SlotActionType.QUICK_MOVE),
23+
HOTBAR_SWAP(SlotActionType.SWAP),
24+
THROW(SlotActionType.THROW),
25+
BUNDLE_SELECT(null);
26+
27+
SlotActionType action;
28+
ActionType(SlotActionType a){action = a;}
29+
}
30+
public record InvAction(int slot, int button, ActionType action){}
2031

2132
public final int MAX_CLICKS;
2233
private final int[] tickDurationArr;
@@ -129,7 +140,7 @@ private int calcRemainingTicks(int clicksToExecute){
129140
private boolean clickOpOngoing/*, waitedForClicks*/;
130141
private int estimatedMsLeft;
131142
public final boolean hasOngoingClicks(){return clickOpOngoing;}
132-
public final void executeClicks(Queue<ClickEvent> clicks, Function<ClickEvent, Boolean> canProceed, Runnable onComplete){
143+
public final void executeClicks(Queue<InvAction> clicks, Function<InvAction, Boolean> canProceed, Runnable onComplete){
133144
final MinecraftClient client = MinecraftClient.getInstance();
134145
if(clickOpOngoing){
135146
Main.LOGGER.warn("executeClicks() already has an ongoing operation");
@@ -171,11 +182,14 @@ public final void executeClicks(Queue<ClickEvent> clicks, Function<ClickEvent, B
171182
Main.LOGGER.error("executeClicks() lost available click mid-op, seemingly due to click(s) occuring during check of canProceed()!");
172183
break;
173184
}
174-
ClickEvent click = clicks.remove();
185+
InvAction click = clicks.remove();
175186
try{
176187
//Main.LOGGER.info("Executing click: "+click.syncId+","+click.slotId+","+click.button+","+click.actionType);
177188
thisClickIsBotted = true;
178-
client.interactionManager.clickSlot(syncId, click.slotId, click.button, click.actionType, client.player);
189+
if(click.action == ActionType.BUNDLE_SELECT){
190+
client.player.networkHandler.sendPacket(new BundleItemSelectedC2SPacket(click.slot, click.button));
191+
}
192+
else client.interactionManager.clickSlot(syncId, click.slot, click.button, click.action.action, client.player);
179193
thisClickIsBotted = false;
180194
}
181195
catch(NullPointerException e){
@@ -216,8 +230,8 @@ public final void executeClicks(Queue<ClickEvent> clicks, Function<ClickEvent, B
216230

217231
public static void executeClicksLEGACY(
218232
MinecraftClient client,
219-
Queue<ClickEvent> clicks, final int MILLIS_BETWEEN_CLICKS, final int MAX_CLICKS_PER_SECOND,
220-
Function<ClickEvent, Boolean> canProceed, Runnable onComplete)
233+
Queue<InvAction> clicks, final int MILLIS_BETWEEN_CLICKS, final int MAX_CLICKS_PER_SECOND,
234+
Function<InvAction, Boolean> canProceed, Runnable onComplete)
221235
{
222236
if(clicks.isEmpty()){
223237
Main.LOGGER.warn("executeClicks() called with an empty ClickEvent list");
@@ -237,9 +251,12 @@ public static void executeClicksLEGACY(
237251
@Override public void run(){
238252
int clicksThisStep = 0;
239253
while(clicksInLastSecond < MAX_CLICKS_PER_SECOND && canProceed.apply(clicks.peek())){
240-
ClickEvent click = clicks.remove();
254+
InvAction click = clicks.remove();
241255
try{
242-
client.interactionManager.clickSlot(syncId, click.slotId, click.button, click.actionType, client.player);
256+
if(click.action == ActionType.BUNDLE_SELECT){
257+
client.player.networkHandler.sendPacket(new BundleItemSelectedC2SPacket(click.slot, click.button));
258+
}
259+
else client.interactionManager.clickSlot(syncId, click.slot, click.button, click.action.action, client.player);
243260
}
244261
catch(NullPointerException e){
245262
Main.LOGGER.error("executeClicks()-MODE:c/ms(array) failure due to null client. Clicks left: "+clicks.size());
@@ -259,9 +276,12 @@ else if(MILLIS_BETWEEN_CLICKS > 1000){
259276
new Timer().schedule(new TimerTask(){@Override public void run(){
260277
if(clicks.isEmpty()){cancel(); onComplete.run(); return;}
261278
if(!canProceed.apply(clicks.peek())) return;
262-
ClickEvent click = clicks.remove();
279+
InvAction click = clicks.remove();
263280
try{
264-
client.interactionManager.clickSlot(syncId, click.slotId, click.button, click.actionType, client.player);
281+
if(click.action == ActionType.BUNDLE_SELECT){
282+
client.player.networkHandler.sendPacket(new BundleItemSelectedC2SPacket(click.slot, click.button));
283+
}
284+
else client.interactionManager.clickSlot(syncId, click.slot, click.button, click.action.action, client.player);
265285
}
266286
catch(NullPointerException e){
267287
Main.LOGGER.error("executeClicks()-MODE:c/ms(simple) failure due to null client. Clicks left: "+clicks.size());
@@ -275,10 +295,13 @@ else new Timer().schedule(new TimerTask(){
275295
int clicksInLastSecondArrIndex = 0;
276296
@Override public void run(){
277297
if(clicksInLastSecond < MAX_CLICKS_PER_SECOND && canProceed.apply(clicks.peek())){
278-
ClickEvent click = clicks.remove();
298+
InvAction click = clicks.remove();
279299
//Main.LOGGER.info("click: "+click.syncId+","+click.slotId+","+click.button+","+click.actionType);
280300
try{
281-
client.interactionManager.clickSlot(syncId, click.slotId, click.button, click.actionType, client.player);
301+
if(click.action == ActionType.BUNDLE_SELECT){
302+
client.player.networkHandler.sendPacket(new BundleItemSelectedC2SPacket(click.slot, click.button));
303+
}
304+
else client.interactionManager.clickSlot(syncId, click.slot, click.button, click.action.action, client.player);
282305
}
283306
catch(NullPointerException e){
284307
Main.LOGGER.error("executeClicks()-MODE:ms/c failure due to null client. Clicks left: "+clicks.size());

src/main/java/net/evmodder/evmod/keybinds/KeybindInventoryOrganize.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
import java.util.stream.IntStream;
99
import net.evmodder.evmod.Configs;
1010
import net.evmodder.evmod.Main;
11-
import net.evmodder.evmod.apis.ClickUtils.ClickEvent;
11+
import net.evmodder.evmod.apis.ClickUtils.ActionType;
12+
import net.evmodder.evmod.apis.ClickUtils.InvAction;
1213
import net.evmodder.evmod.config.OptionInventoryRestockLimit;
1314
import net.minecraft.client.MinecraftClient;
1415
import net.minecraft.client.gui.screen.ingame.HandledScreen;
@@ -17,7 +18,6 @@
1718
import net.minecraft.item.ItemStack;
1819
import net.minecraft.item.Items;
1920
import net.minecraft.registry.Registries;
20-
import net.minecraft.screen.slot.SlotActionType;
2121
import net.minecraft.util.Identifier;
2222

2323
public final class KeybindInventoryOrganize{
@@ -141,7 +141,7 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
141141
// Main.LOGGER.info("InvOrganize: "+layoutMap.size()+" mappings, isInvScreen="+isInvScreen+", numSlots="+simSlots.length
142142
// +", hotbarStart="+HOTBAR_START+", invStart="+MAIN_INV_START);
143143

144-
ArrayDeque<ClickEvent> clicks = new ArrayDeque<>();
144+
ArrayDeque<InvAction> clicks = new ArrayDeque<>();
145145
checkDoneSlots(simSlots, doneSlots, isInvScreen);
146146
boolean[] plannedSlots;
147147
if(isInvScreen){
@@ -169,10 +169,10 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
169169
return;
170170
}
171171
//client.player.sendMessage(Text.literal("Click: Unequipping armor"), false);
172-
clicks.add(new ClickEvent(p.slot, 0, SlotActionType.QUICK_MOVE));
172+
clicks.add(new InvAction(p.slot, 0, ActionType.SHIFT_CLICK));
173173
}
174174
//client.player.sendMessage(Text.literal("Click: "+dstSlot+" Equipping armor"), false);
175-
clicks.add(new ClickEvent(srcSlot, 0, SlotActionType.QUICK_MOVE));
175+
clicks.add(new InvAction(srcSlot, 0, ActionType.SHIFT_CLICK));
176176
swapSlots(simSlots, emptySlots, srcSlot, dstSlot);
177177
doneSlots[dstSlot] = true;
178178
plannedSlots[srcSlot] = false;
@@ -202,8 +202,8 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
202202
//if(srcSlot == -1) continue;
203203
if(srcSlot < HOTBAR_START) continue; // We want items coming FROM hotbar/offhand
204204
// client.player.sendMessage(Text.literal("Click: "+srcSlot+"->"+dstSlot+", Hotbar->Anywhere (sorting)"), false);
205-
if(isInvScreen && srcSlot == 45) clicks.add(new ClickEvent(dstSlot, 40, SlotActionType.SWAP));
206-
else clicks.add(new ClickEvent(dstSlot, srcSlot-HOTBAR_START, SlotActionType.SWAP));
205+
if(isInvScreen && srcSlot == 45) clicks.add(new InvAction(dstSlot, 40, ActionType.HOTBAR_SWAP));
206+
else clicks.add(new InvAction(dstSlot, srcSlot-HOTBAR_START, ActionType.HOTBAR_SWAP));
207207

208208
swapSlots(simSlots, emptySlots, srcSlot, dstSlot);
209209
doneSlots[dstSlot] = true;
@@ -218,7 +218,7 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
218218
final int originalCount = simSlots[i].getCount();
219219
if(simulateShiftClick(simSlots, emptySlots, /*fromArmor=*/false, i) < originalCount){
220220
// client.player.sendMessage(Text.literal("Click: "+i+" Hotbar->UpperInv (cleaning)"), false);
221-
clicks.add(new ClickEvent(i, 0, SlotActionType.QUICK_MOVE));
221+
clicks.add(new InvAction(i, 0, ActionType.SHIFT_CLICK));
222222
}
223223
}
224224
checkDoneSlots(simSlots, doneSlots, isInvScreen);
@@ -311,12 +311,12 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
311311
}
312312
}
313313
// client.player.sendMessage(Text.literal("Click: "+srcSlot+"->"+dstSlot+" UpperInv->Hotbar->UpperInv"), false);
314-
clicks.add(new ClickEvent(srcSlot, hb, SlotActionType.SWAP));
315-
clicks.add(new ClickEvent(dstSlot, hb, SlotActionType.SWAP));
314+
clicks.add(new InvAction(srcSlot, hb, ActionType.HOTBAR_SWAP));
315+
clicks.add(new InvAction(dstSlot, hb, ActionType.HOTBAR_SWAP));
316316
if(!emptySlots[dstSlot] || !emptySlots[hb == 40 ? 45 : hb+36]){
317317
//Main.LOGGER.info("putting back original displaced item");
318318
// Put back the displaced hotbar/offhand item
319-
clicks.add(new ClickEvent(srcSlot, hb, SlotActionType.SWAP));
319+
clicks.add(new InvAction(srcSlot, hb, ActionType.HOTBAR_SWAP));
320320
}
321321
swapSlots(simSlots, emptySlots, srcSlot, dstSlot);
322322
if(RESTOCK_ONLY_1_SLOT_PER_TYPE && !isInvScreen) alreadyRestockedItems.add(simSlots[dstSlot].getItem());
@@ -357,8 +357,8 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
357357
}
358358
}
359359
// client.player.sendMessage(Text.literal("Click: "+srcSlot+"->"+dstSlot+" UpperInv->Hotbar"), false);
360-
if(isInvScreen && dstSlot == 45) clicks.add(new ClickEvent(srcSlot, 40, SlotActionType.SWAP));
361-
else clicks.add(new ClickEvent(srcSlot, dstSlot-HOTBAR_START, SlotActionType.SWAP));
360+
if(isInvScreen && dstSlot == 45) clicks.add(new InvAction(srcSlot, 40, ActionType.HOTBAR_SWAP));
361+
else clicks.add(new InvAction(srcSlot, dstSlot-HOTBAR_START, ActionType.HOTBAR_SWAP));
362362

363363
swapSlots(simSlots, emptySlots, srcSlot, dstSlot);
364364
if(RESTOCK_ONLY_1_SLOT_PER_TYPE && !isInvScreen) alreadyRestockedItems.add(simSlots[dstSlot].getItem());
@@ -391,7 +391,7 @@ public void organizeInventory(final boolean RESTOCK_ONLY, Runnable onComplete){
391391
}
392392
}
393393
// client.player.sendMessage(Text.literal("Click: "+srcSlot+" Container->Inventory (armor slot unavailable)"), false);
394-
clicks.add(new ClickEvent(srcSlot, 0, SlotActionType.QUICK_MOVE));
394+
clicks.add(new InvAction(srcSlot, 0, ActionType.SHIFT_CLICK));
395395
}
396396

397397
final int numClicks = clicks.size();

src/main/java/net/evmodder/evmod/keybinds/KeybindInventoryRestock.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import net.evmodder.evmod.Configs;
1212
import net.evmodder.evmod.KeyCallbacks;
1313
import net.evmodder.evmod.Main;
14-
import net.evmodder.evmod.apis.ClickUtils.ClickEvent;
14+
import net.evmodder.evmod.apis.ClickUtils.ActionType;
15+
import net.evmodder.evmod.apis.ClickUtils.InvAction;
1516
import net.evmodder.evmod.config.OptionInventoryRestockLimit;
1617
import net.evmodder.evmod.keybinds.KeybindInventoryOrganize.SlotAndItemName;
1718
import net.minecraft.client.MinecraftClient;
@@ -22,7 +23,6 @@
2223
import net.minecraft.item.Item;
2324
import net.minecraft.item.ItemStack;
2425
import net.minecraft.registry.Registries;
25-
import net.minecraft.screen.slot.SlotActionType;
2626
import net.minecraft.util.Identifier;
2727

2828
//TODO: Shift-click (only 2 clicks intead of 3) when possible
@@ -47,7 +47,7 @@ public final void doRestock(){
4747
//
4848
final ItemStack[] slots = hs.getScreenHandler().slots.stream().map(s -> s.getStack().copy()).toArray(ItemStack[]::new);
4949

50-
ArrayDeque<ClickEvent> clicks = new ArrayDeque<>();
50+
ArrayDeque<InvAction> clicks = new ArrayDeque<>();
5151
HashMap<Item, Integer> supply = new HashMap<>();
5252

5353

@@ -107,26 +107,26 @@ else for(KeybindInventoryOrganize kio : organizationLayouts)
107107
final boolean needToLeave1 = limits == OptionInventoryRestockLimit.LEAVE_ONE_ITEM
108108
&& combinedCount <= maxCount && (totalInContainer -= slots[j].getCount()) == 0;
109109

110-
if(needToLeave1 || combinedCount != maxCount) clicks.add(new ClickEvent(j, 0, SlotActionType.PICKUP)); // Pickup all
110+
if(needToLeave1 || combinedCount != maxCount) clicks.add(new InvAction(j, 0, ActionType.CLICK)); // Pickup all
111111
else{
112-
clicks.add(new ClickEvent(j, 0, SlotActionType.QUICK_MOVE)); // Shift-click
112+
clicks.add(new InvAction(j, 0, ActionType.SHIFT_CLICK)); // Shift-click
113113
totalInContainer -= slots[j].getCount();
114114
slots[i].setCount(maxCount);
115115
slots[j] = ItemStack.EMPTY;
116116
break;
117117
}
118118
if(needToLeave1){
119-
clicks.add(new ClickEvent(j, 1, SlotActionType.PICKUP)); // Leave 1
119+
clicks.add(new InvAction(j, 1, ActionType.CLICK)); // Leave 1
120120
--combinedCount;
121121
}
122-
clicks.add(new ClickEvent(i, 0, SlotActionType.PICKUP)); // Place as many as possible
122+
clicks.add(new InvAction(i, 0, ActionType.CLICK)); // Place as many as possible
123123
if(combinedCount <= maxCount){
124124
totalInContainer -= (combinedCount - slots[i].getCount());
125125
slots[i].setCount(combinedCount);
126126
slots[j] = ItemStack.EMPTY;
127127
}
128128
else{
129-
clicks.add(new ClickEvent(j, 0, SlotActionType.PICKUP)); // Put back extras
129+
clicks.add(new InvAction(j, 0, ActionType.CLICK)); // Put back extras
130130
totalInContainer -= (maxCount - slots[i].getCount());
131131
slots[i].setCount(maxCount);
132132
slots[j].setCount(combinedCount - maxCount);

0 commit comments

Comments
 (0)