33import io .papermc .paper .datacomponent .DataComponentTypes ;
44import org .bukkit .GameMode ;
55import org .bukkit .entity .Player ;
6+ import org .bukkit .event .inventory .InventoryAction ;
67import org .bukkit .inventory .ItemStack ;
78import org .bukkit .inventory .PlayerInventory ;
89import org .jetbrains .annotations .Unmodifiable ;
@@ -117,9 +118,6 @@ private void handleInvSlotElementClick(SlotElement.InventoryLink element, Click
117118 Inventory inventory = element .inventory ();
118119 int slot = element .slot ();
119120
120- if (inventory .callClickEvent (slot , click ))
121- return ;
122-
123121 switch (click .clickType ()) {
124122 case LEFT -> handleInvLeftClick (click , inventory , slot );
125123 case RIGHT -> handleInvRightClick (click , inventory , slot );
@@ -128,7 +126,7 @@ private void handleInvSlotElementClick(SlotElement.InventoryLink element, Click
128126 case SWAP_OFFHAND -> handleInvOffHandKey (click , inventory , slot );
129127 case DROP -> handleInvDrop (false , click , inventory , slot );
130128 case CONTROL_DROP -> handleInvDrop (true , click , inventory , slot );
131- case DOUBLE_CLICK -> handleInvDoubleClick (click );
129+ case DOUBLE_CLICK -> handleInvDoubleClick (click , inventory , slot );
132130 case MIDDLE -> handleInvMiddleClick (click , inventory , slot );
133131 }
134132 }
@@ -139,25 +137,36 @@ private void handleInvLeftClick(Click click, Inventory inventory, int slot) {
139137 ItemStack clicked = inventory .getItem (slot );
140138
141139 // nothing happens if both cursor and clicked stack are empty
142- if (clicked == null && cursor == null )
140+ if (clicked == null && cursor == null ) {
141+ inventory .callClickEvent (slot , click , InventoryAction .NOTHING );
143142 return ;
143+ }
144144
145145 UpdateReason updateReason = new PlayerUpdateReason .Click (player , click );
146146
147147 if (cursor == null ) {
148148 // if the cursor is empty, pick the stack up
149+ if (inventory .callClickEvent (slot , click , InventoryAction .PICKUP_SOME ))
150+ return ;
151+
149152 int amount = -inventory .addItemAmount (updateReason , slot , -clicked .getAmount ());
150153 clicked .setAmount (amount );
151154 player .setItemOnCursor (clicked );
152155 } else if (clicked != null && ItemUtils2 .isBundle (cursor )) {
153156 // insert clicked item into bundle on cursor
157+ if (inventory .callClickEvent (slot , click , InventoryAction .PICKUP_SOME_INTO_BUNDLE ))
158+ return ;
159+
154160 int toAdd = ItemUtils2 .getMaxAmountToAddToBundle (cursor , clicked );
155161 toAdd = -inventory .addItemAmount (updateReason , slot , -toAdd );
156162 clicked .setAmount (toAdd );
157163 ItemUtils2 .tryMoveIntoBundle (cursor , clicked ); // writes back into clicked and cursor
158164 player .setItemOnCursor (cursor );
159165 } else if (clicked != null && ItemUtils2 .isBundle (clicked )) {
160166 // insert cursor item into clicked bundle
167+ if (inventory .callClickEvent (slot , click , InventoryAction .PLACE_SOME_INTO_BUNDLE ))
168+ return ;
169+
161170 ItemStack bundle = clicked .clone ();
162171 if (ItemUtils2 .tryMoveIntoBundle (bundle , cursor .clone ())) { // writes back into bundle
163172 // some items were inserted, now try to place the updated bundle into the inventory
@@ -171,6 +180,9 @@ private void handleInvLeftClick(Click click, Inventory inventory, int slot) {
171180 }
172181 } else if (clicked == null || cursor .isSimilar (clicked )) {
173182 // if there are no items, or they're similar to the cursor, add the cursor items to the stack
183+ if (inventory .callClickEvent (slot , click , InventoryAction .PLACE_SOME ))
184+ return ;
185+
174186 int remains = inventory .putItem (updateReason , slot , cursor );
175187 if (remains == 0 ) {
176188 player .setItemOnCursor (null );
@@ -180,6 +192,9 @@ private void handleInvLeftClick(Click click, Inventory inventory, int slot) {
180192 }
181193 } else if (!cursor .isSimilar (clicked )) {
182194 // if the stacks are not similar, swap them
195+ if (inventory .callClickEvent (slot , click , InventoryAction .SWAP_WITH_CURSOR ))
196+ return ;
197+
183198 if (inventory .setItem (updateReason , slot , cursor ))
184199 player .setItemOnCursor (clicked );
185200 }
@@ -191,13 +206,18 @@ private void handleInvRightClick(Click click, Inventory inventory, int slot) {
191206 ItemStack clicked = inventory .getItem (slot );
192207
193208 // nothing happens if both cursor and clicked stack are empty
194- if (clicked == null && cursor == null )
209+ if (clicked == null && cursor == null ) {
210+ inventory .callClickEvent (slot , click , InventoryAction .NOTHING );
195211 return ;
212+ }
196213
197214 UpdateReason updateReason = new PlayerUpdateReason .Click (player , click );
198215
199216 if (cursor == null && ItemUtils2 .isBundle (clicked )) {
200217 // take the selected item from the bundle
218+ if (inventory .callClickEvent (slot , click , InventoryAction .PICKUP_FROM_BUNDLE ))
219+ return ;
220+
201221 ItemStack bundle = clicked .clone ();
202222 ItemStack taken = ItemUtils2 .takeSelectedFromBundle (bundle ); // writes back to bundle
203223 if (taken != null ) {
@@ -213,13 +233,19 @@ private void handleInvRightClick(Click click, Inventory inventory, int slot) {
213233 } else if (cursor == null ) {
214234 // if the cursor is empty, split the stack to the cursor
215235 // if the stack is not divisible by 2, give the cursor the bigger part
236+ if (inventory .callClickEvent (slot , click , InventoryAction .PICKUP_HALF ))
237+ return ;
238+
216239 int newCursorAmount = (int ) Math .ceil (clicked .getAmount () / 2.0 );
217240 newCursorAmount = -inventory .addItemAmount (updateReason , slot , -newCursorAmount );
218241 ItemStack newCursor = clicked .clone ();
219242 newCursor .setAmount (newCursorAmount );
220243 player .setItemOnCursor (newCursor );
221244 } else if (clicked == null && ItemUtils2 .isBundle (cursor )) {
222245 // if the player right-clicked on an empty slot with a bundle, place the first item from the bundle there
246+ if (inventory .callClickEvent (slot , click , InventoryAction .PLACE_FROM_BUNDLE ))
247+ return ;
248+
223249 ItemStack toTake = ItemUtils2 .getFirstFromBundle (cursor );
224250 if (toTake != null ) {
225251 int amountTaken = toTake .getAmount () - inventory .putItem (updateReason , slot , toTake );
@@ -231,6 +257,9 @@ private void handleInvRightClick(Click click, Inventory inventory, int slot) {
231257 }
232258 } else if (clicked == null || cursor .isSimilar (clicked )) {
233259 // put one item from the cursor in the inventory
260+ if (inventory .callClickEvent (slot , click , InventoryAction .PLACE_ONE ))
261+ return ;
262+
234263 ItemStack toAdd = cursor .clone ();
235264 toAdd .setAmount (1 );
236265 int remains = inventory .putItem (updateReason , slot , toAdd );
@@ -240,6 +269,9 @@ private void handleInvRightClick(Click click, Inventory inventory, int slot) {
240269 }
241270 } else {
242271 // swap cursor and clicked
272+ if (inventory .callClickEvent (slot , click , InventoryAction .SWAP_WITH_CURSOR ))
273+ return ;
274+
243275 if (inventory .setItem (updateReason , slot , cursor ))
244276 player .setItemOnCursor (clicked );
245277 }
@@ -249,7 +281,12 @@ private void handleInvItemShift(Click click, Inventory inventory, int slot) {
249281 Player player = click .player ();
250282 ItemStack clicked = inventory .getItem (slot );
251283
252- if (clicked == null )
284+ if (clicked == null ) {
285+ inventory .callClickEvent (slot , click , InventoryAction .NOTHING );
286+ return ;
287+ }
288+
289+ if (inventory .callClickEvent (slot , click , InventoryAction .MOVE_TO_OTHER_INVENTORY ))
253290 return ;
254291
255292 UpdateReason updateReason = new PlayerUpdateReason .Click (player , click );
@@ -293,6 +330,14 @@ private void handleInvNumberKey(Click click, Inventory inventory, int slot) {
293330 return ;
294331
295332 ItemStack hotbar = otherInventory .getItem (otherSlot );
333+ if (clicked == null && hotbar == null ) {
334+ inventory .callClickEvent (slot , click , InventoryAction .NOTHING );
335+ return ;
336+ }
337+
338+ if (inventory .callClickEvent (slot , click , InventoryAction .HOTBAR_SWAP ))
339+ return ;
340+
296341 var updateReason = new PlayerUpdateReason .Click (click );
297342
298343 // check if clicked inventory would allow hotbar swap
@@ -316,6 +361,14 @@ private void handleInvOffHandKey(Click click, Inventory inventory, int slot) {
316361 ItemStack clicked = inventory .getItem (slot );
317362 ItemStack offhandItem = ItemUtils .takeUnlessEmpty (playerInventory .getItemInOffHand ());
318363
364+ if (clicked == null && offhandItem == null ) {
365+ inventory .callClickEvent (slot , click , InventoryAction .NOTHING );
366+ return ;
367+ }
368+
369+ if (inventory .callClickEvent (slot , click , InventoryAction .HOTBAR_SWAP ))
370+ return ;
371+
319372 if (inventory .setItem (new PlayerUpdateReason .Click (click ), slot , offhandItem ))
320373 playerInventory .setItemInOffHand (clicked );
321374 }
@@ -325,6 +378,9 @@ private void handleInvDrop(boolean ctrl, Click click, Inventory inventory, int s
325378 if (ItemUtils .isEmpty (clicked ))
326379 return ;
327380
381+ if (inventory .callClickEvent (slot , click , ctrl ? InventoryAction .DROP_ALL_SLOT : InventoryAction .DROP_ONE_SLOT ))
382+ return ;
383+
328384 Player player = click .player ();
329385 UpdateReason updateReason = new PlayerUpdateReason .Click (player , click );
330386
@@ -344,9 +400,14 @@ private void handleInvDrop(boolean ctrl, Click click, Inventory inventory, int s
344400 inventory .callPostUpdateEvent (updateReason , slot , clicked , newItem );
345401 }
346402
347- private void handleInvDoubleClick (Click click ) {
403+ private void handleInvDoubleClick (Click click , Inventory clickedinventory , int clickedSlot ) {
348404 Player player = click .player ();
349- if (ItemUtils .isEmpty (player .getItemOnCursor ()))
405+ if (ItemUtils .isEmpty (player .getItemOnCursor ())) {
406+ clickedinventory .callClickEvent (clickedSlot , click , InventoryAction .NOTHING );
407+ return ;
408+ }
409+
410+ if (clickedinventory .callClickEvent (clickedSlot , click , InventoryAction .COLLECT_TO_CURSOR ))
350411 return ;
351412
352413 // requires window as collect to cursor is a cross-gui operation
@@ -374,13 +435,14 @@ private void handleInvDoubleClick(Click click) {
374435
375436 private void handleInvMiddleClick (Click click , Inventory inventory , int slot ) {
376437 Player player = click .player ();
377- if (player .getGameMode () != GameMode .CREATIVE || !player .getItemOnCursor ().isEmpty ())
378- return ;
379-
380- ItemStack cursor = inventory .getItem (slot );
381- if (cursor != null ) {
382- cursor .setAmount (cursor .getMaxStackSize ());
383- player .setItemOnCursor (cursor );
438+ ItemStack target = inventory .getItem (slot );
439+ if (player .getGameMode () == GameMode .CREATIVE && target != null && ItemUtils .isEmpty (player .getItemOnCursor ())) {
440+ if (inventory .callClickEvent (slot , click , InventoryAction .CLONE_STACK ))
441+ return ;
442+ target .setAmount (target .getMaxStackSize ());
443+ player .setItemOnCursor (target );
444+ } else {
445+ inventory .callClickEvent (slot , click , InventoryAction .NOTHING );
384446 }
385447 }
386448
@@ -392,7 +454,7 @@ private void handleInvBundleSelect(Player player, Inventory inventory, int slot,
392454 inventory .setItem (new PlayerUpdateReason .BundleSelect (player , bundleSlot ), slot , bundle );
393455 }
394456 }
395-
457+
396458 /**
397459 * Puts the given {@link ItemStack} into the first inventory that accepts it of the given collection of inventories.
398460 * If one inventory accepts any amount of items, further inventories will not be queried, meaning that an item stack
0 commit comments