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