mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-30 21:17:53 +01:00
Fix drag clicks
This commit is contained in:
parent
e5ecee2089
commit
a75910fe3f
@ -401,18 +401,7 @@ public class Inventory extends AbstractInventory implements Viewable {
|
||||
final InventoryClickResult clickResult = clickProcessor.dragging(player,
|
||||
slot != -999 ? (isInWindow ? this : playerInventory) : null,
|
||||
clickSlot, button,
|
||||
clicked, cursor,
|
||||
|
||||
s -> isClickInWindow(s) ? getItemStack(s) :
|
||||
playerInventory.getItemStack(PlayerInventoryUtils.convertSlot(s, offset)),
|
||||
|
||||
(s, item) -> {
|
||||
if (isClickInWindow(s)) {
|
||||
setItemStack(s, item);
|
||||
} else {
|
||||
playerInventory.setItemStack(PlayerInventoryUtils.convertSlot(s, offset), item);
|
||||
}
|
||||
});
|
||||
clicked, cursor);
|
||||
if (clickResult == null || clickResult.isCancel()) {
|
||||
updateAll(player);
|
||||
return false;
|
||||
|
@ -317,9 +317,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
|
||||
final ItemStack cursor = getCursorItem();
|
||||
final ItemStack clicked = slot != -999 ? getItemStackFromPacketSlot(slot) : ItemStack.AIR;
|
||||
final InventoryClickResult clickResult = clickProcessor.dragging(player, this,
|
||||
slot, button,
|
||||
clicked, cursor, this::getItemStackFromPacketSlot,
|
||||
this::setItemStackFromPacketSlot);
|
||||
convertPlayerInventorySlot(slot, OFFSET), button, clicked, cursor);
|
||||
if (clickResult == null || clickResult.isCancel()) {
|
||||
update();
|
||||
return false;
|
||||
|
@ -1,8 +1,5 @@
|
||||
package net.minestom.server.inventory.click;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import net.minestom.server.entity.EquipmentSlot;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.EventDispatcher;
|
||||
@ -18,18 +15,18 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class InventoryClickProcessor {
|
||||
// Dragging maps
|
||||
private final Map<Player, IntSet> leftDraggingMap = new ConcurrentHashMap<>();
|
||||
private final Map<Player, IntSet> rightDraggingMap = new ConcurrentHashMap<>();
|
||||
private final Map<Player, List<DragData>> leftDraggingMap = new ConcurrentHashMap<>();
|
||||
private final Map<Player, List<DragData>> rightDraggingMap = new ConcurrentHashMap<>();
|
||||
|
||||
public @NotNull InventoryClickResult leftClick(@NotNull Player player, @NotNull AbstractInventory inventory,
|
||||
int slot,
|
||||
@ -162,23 +159,21 @@ public final class InventoryClickProcessor {
|
||||
|
||||
public @Nullable InventoryClickResult dragging(@NotNull Player player, @Nullable AbstractInventory inventory,
|
||||
int slot, int button,
|
||||
@NotNull ItemStack clicked, @NotNull ItemStack cursor,
|
||||
@NotNull Int2ObjectFunction<ItemStack> itemGetter,
|
||||
@NotNull BiConsumer<Integer, ItemStack> itemSetter) {
|
||||
@NotNull ItemStack clicked, @NotNull ItemStack cursor) {
|
||||
InventoryClickResult clickResult = null;
|
||||
final StackingRule stackingRule = cursor.getStackingRule();
|
||||
if (slot != -999) {
|
||||
// Add slot
|
||||
if (button == 1) {
|
||||
// Add left
|
||||
IntSet left = leftDraggingMap.get(player);
|
||||
List<DragData> left = leftDraggingMap.get(player);
|
||||
if (left == null) return null;
|
||||
left.add(slot);
|
||||
left.add(new DragData(slot, inventory));
|
||||
} else if (button == 5) {
|
||||
// Add right
|
||||
IntSet right = rightDraggingMap.get(player);
|
||||
List<DragData> right = rightDraggingMap.get(player);
|
||||
if (right == null) return null;
|
||||
right.add(slot);
|
||||
right.add(new DragData(slot, inventory));
|
||||
} else if (button == 9) {
|
||||
// Add middle
|
||||
// TODO
|
||||
@ -188,18 +183,18 @@ public final class InventoryClickProcessor {
|
||||
if (button == 0) {
|
||||
// Start left
|
||||
clickResult = startCondition(player, inventory, slot, ClickType.START_LEFT_DRAGGING, clicked, cursor);
|
||||
if (!clickResult.isCancel()) this.leftDraggingMap.put(player, new IntOpenHashSet());
|
||||
if (!clickResult.isCancel()) this.leftDraggingMap.put(player, new ArrayList<>());
|
||||
} else if (button == 2) {
|
||||
// End left
|
||||
final IntSet slots = leftDraggingMap.remove(player);
|
||||
final List<DragData> slots = leftDraggingMap.remove(player);
|
||||
if (slots == null) return null;
|
||||
final int slotCount = slots.size();
|
||||
final int cursorAmount = stackingRule.getAmount(cursor);
|
||||
if (slotCount > cursorAmount) return null;
|
||||
for (int s : slots) {
|
||||
for (DragData s : slots) {
|
||||
// Apply each drag element
|
||||
final ItemStack slotItem = itemGetter.apply(s);
|
||||
clickResult = startCondition(player, inventory, s, ClickType.LEFT_DRAGGING, slotItem, cursor);
|
||||
final ItemStack slotItem = s.inventory.getItemStack(s.slot);
|
||||
clickResult = startCondition(player, s.inventory, s.slot, ClickType.LEFT_DRAGGING, slotItem, cursor);
|
||||
if (clickResult.isCancel()) {
|
||||
return clickResult;
|
||||
}
|
||||
@ -210,8 +205,10 @@ public final class InventoryClickProcessor {
|
||||
final int slotSize = (int) ((float) cursorAmount / (float) slotCount);
|
||||
// Place all waiting drag action
|
||||
int finalCursorAmount = cursorAmount;
|
||||
for (int s : slots) {
|
||||
ItemStack slotItem = itemGetter.apply(s);
|
||||
for (DragData dragData : slots) {
|
||||
final var inv = dragData.inventory;
|
||||
final int s = dragData.slot;
|
||||
ItemStack slotItem = inv.getItemStack(s);
|
||||
final StackingRule slotItemRule = slotItem.getStackingRule();
|
||||
final int amount = slotItemRule.getAmount(slotItem);
|
||||
if (stackingRule.canBeStacked(cursor, slotItem)) {
|
||||
@ -231,7 +228,7 @@ public final class InventoryClickProcessor {
|
||||
slotItem = stackingRule.apply(cursor, slotSize);
|
||||
finalCursorAmount -= slotSize;
|
||||
}
|
||||
itemSetter.accept(s, slotItem);
|
||||
inv.setItemStack(s, slotItem);
|
||||
callClickEvent(player, inventory, s, ClickType.LEFT_DRAGGING, slotItem, cursor);
|
||||
}
|
||||
// Update the cursor
|
||||
@ -239,18 +236,18 @@ public final class InventoryClickProcessor {
|
||||
} else if (button == 4) {
|
||||
// Start right
|
||||
clickResult = startCondition(player, inventory, slot, ClickType.START_RIGHT_DRAGGING, clicked, cursor);
|
||||
if (!clickResult.isCancel()) this.rightDraggingMap.put(player, new IntOpenHashSet());
|
||||
if (!clickResult.isCancel()) this.rightDraggingMap.put(player, new ArrayList<>());
|
||||
} else if (button == 6) {
|
||||
// End right
|
||||
final IntSet slots = rightDraggingMap.remove(player);
|
||||
final List<DragData> slots = rightDraggingMap.remove(player);
|
||||
if (slots == null) return null;
|
||||
final int size = slots.size();
|
||||
int cursorAmount = stackingRule.getAmount(cursor);
|
||||
if (size > cursorAmount) return null;
|
||||
// Verify if each slot can be modified (or cancel the whole drag)
|
||||
for (int s : slots) {
|
||||
ItemStack slotItem = itemGetter.apply(s);
|
||||
clickResult = startCondition(player, inventory, s, ClickType.RIGHT_DRAGGING, slotItem, cursor);
|
||||
for (DragData s : slots) {
|
||||
final ItemStack slotItem = s.inventory.getItemStack(s.slot);
|
||||
clickResult = startCondition(player, s.inventory, s.slot, ClickType.RIGHT_DRAGGING, slotItem, cursor);
|
||||
if (clickResult.isCancel()) {
|
||||
return clickResult;
|
||||
}
|
||||
@ -259,8 +256,10 @@ public final class InventoryClickProcessor {
|
||||
if (clickResult.isCancel()) return clickResult;
|
||||
// Place all waiting drag action
|
||||
int finalCursorAmount = cursorAmount;
|
||||
for (int s : slots) {
|
||||
ItemStack slotItem = itemGetter.apply(s);
|
||||
for (DragData dragData : slots) {
|
||||
final var inv = dragData.inventory;
|
||||
final int s = dragData.slot;
|
||||
ItemStack slotItem = inv.getItemStack(s);
|
||||
StackingRule slotItemRule = slotItem.getStackingRule();
|
||||
if (stackingRule.canBeStacked(cursor, slotItem)) {
|
||||
// Compatible item in the slot, increment by 1
|
||||
@ -274,7 +273,7 @@ public final class InventoryClickProcessor {
|
||||
slotItem = stackingRule.apply(cursor, 1);
|
||||
finalCursorAmount -= 1;
|
||||
}
|
||||
itemSetter.accept(s, slotItem);
|
||||
inv.setItemStack(s, slotItem);
|
||||
callClickEvent(player, inventory, s, ClickType.RIGHT_DRAGGING, slotItem, cursor);
|
||||
}
|
||||
// Update the cursor
|
||||
@ -462,4 +461,14 @@ public final class InventoryClickProcessor {
|
||||
this.leftDraggingMap.remove(player);
|
||||
this.rightDraggingMap.remove(player);
|
||||
}
|
||||
|
||||
private static final class DragData {
|
||||
private final int slot;
|
||||
private final AbstractInventory inventory;
|
||||
|
||||
public DragData(int slot, AbstractInventory inventory) {
|
||||
this.slot = slot;
|
||||
this.inventory = inventory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user