mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-29 15:07:36 +02:00
Simplify double click handling
This commit is contained in:
parent
e9b5779b24
commit
5390cd14f0
@ -55,8 +55,7 @@ public abstract class AbstractInventory implements InventoryClickHandler, DataCo
|
|||||||
public synchronized <T> @NotNull T processItemStack(@NotNull ItemStack itemStack,
|
public synchronized <T> @NotNull T processItemStack(@NotNull ItemStack itemStack,
|
||||||
@NotNull TransactionType type,
|
@NotNull TransactionType type,
|
||||||
@NotNull TransactionOption<T> option) {
|
@NotNull TransactionOption<T> option) {
|
||||||
var pair = type.process(this, itemStack);
|
return option.fill(type, this, itemStack);
|
||||||
return option.fill(this, pair.left(), pair.right());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized <T> @NotNull List<@NotNull T> processItemStacks(@NotNull List<@NotNull ItemStack> itemStacks,
|
public synchronized <T> @NotNull List<@NotNull T> processItemStacks(@NotNull List<@NotNull ItemStack> itemStacks,
|
||||||
|
@ -4,7 +4,6 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.ClickType;
|
||||||
import net.minestom.server.inventory.click.InventoryClickLoopHandler;
|
|
||||||
import net.minestom.server.inventory.click.InventoryClickResult;
|
import net.minestom.server.inventory.click.InventoryClickResult;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.network.packet.server.play.OpenWindowPacket;
|
import net.minestom.server.network.packet.server.play.OpenWindowPacket;
|
||||||
@ -468,17 +467,8 @@ public class Inventory extends AbstractInventory implements Viewable {
|
|||||||
final ItemStack cursor = getCursorItem(player);
|
final ItemStack cursor = getCursorItem(player);
|
||||||
final boolean isInWindow = isClickInWindow(slot);
|
final boolean isInWindow = isClickInWindow(slot);
|
||||||
|
|
||||||
final InventoryClickResult clickResult = clickProcessor.doubleClick(isInWindow ? this : null, player, slot, cursor,
|
final InventoryClickResult clickResult = clickProcessor.doubleClick(isInWindow ? this : playerInventory,
|
||||||
// Start by looping through the opened inventory
|
this, player, slot, cursor);
|
||||||
new InventoryClickLoopHandler(0, getSize(), 1,
|
|
||||||
i -> i,
|
|
||||||
this::getItemStack,
|
|
||||||
this::setItemStack),
|
|
||||||
// Looping through player inventory
|
|
||||||
new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE, 1,
|
|
||||||
PlayerInventoryUtils::convertToPacketSlot,
|
|
||||||
index -> playerInventory.getItemStack(index, PlayerInventoryUtils.OFFSET),
|
|
||||||
(index, itemStack) -> playerInventory.setItemStack(index, PlayerInventoryUtils.OFFSET, itemStack)));
|
|
||||||
|
|
||||||
if (clickResult == null)
|
if (clickResult == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -3,7 +3,6 @@ package net.minestom.server.inventory;
|
|||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.item.ArmorEquipEvent;
|
import net.minestom.server.event.item.ArmorEquipEvent;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.ClickType;
|
||||||
import net.minestom.server.inventory.click.InventoryClickLoopHandler;
|
|
||||||
import net.minestom.server.inventory.click.InventoryClickResult;
|
import net.minestom.server.inventory.click.InventoryClickResult;
|
||||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
@ -406,12 +405,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
|
|||||||
@Override
|
@Override
|
||||||
public boolean doubleClick(@NotNull Player player, int slot) {
|
public boolean doubleClick(@NotNull Player player, int slot) {
|
||||||
final ItemStack cursor = getCursorItem();
|
final ItemStack cursor = getCursorItem();
|
||||||
|
final InventoryClickResult clickResult = clickProcessor.doubleClick(this, null, player, slot, cursor);
|
||||||
final InventoryClickResult clickResult = clickProcessor.doubleClick(null, player, slot, cursor,
|
|
||||||
new InventoryClickLoopHandler(0, itemStacks.length, 1,
|
|
||||||
i -> i < 9 ? i + 9 : i - 9,
|
|
||||||
index -> itemStacks[index],
|
|
||||||
this::setItemStack));
|
|
||||||
|
|
||||||
if (clickResult == null)
|
if (clickResult == null)
|
||||||
return false;
|
return false;
|
||||||
@ -419,6 +413,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
|
|||||||
if (clickResult.doRefresh())
|
if (clickResult.doRefresh())
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
setItemStack(slot, OFFSET, clickResult.getClicked());
|
||||||
setCursorItem(clickResult.getCursor());
|
setCursorItem(clickResult.getCursor());
|
||||||
|
|
||||||
return !clickResult.isCancel();
|
return !clickResult.isCancel();
|
||||||
|
@ -44,4 +44,11 @@ public interface TransactionOption<T> {
|
|||||||
@NotNull T fill(@NotNull AbstractInventory inventory,
|
@NotNull T fill(@NotNull AbstractInventory inventory,
|
||||||
@NotNull ItemStack result,
|
@NotNull ItemStack result,
|
||||||
@NotNull Map<@NotNull Integer, @NotNull ItemStack> itemChangesMap);
|
@NotNull Map<@NotNull Integer, @NotNull ItemStack> itemChangesMap);
|
||||||
|
|
||||||
|
default @NotNull T fill(@NotNull TransactionType type,
|
||||||
|
@NotNull AbstractInventory inventory,
|
||||||
|
@NotNull ItemStack itemStack) {
|
||||||
|
var pair = type.process(inventory, itemStack);
|
||||||
|
return fill(inventory, pair.left(), pair.right());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.minestom.server.inventory.click;
|
package net.minestom.server.inventory.click;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
@ -9,6 +8,7 @@ import net.minestom.server.event.inventory.InventoryClickEvent;
|
|||||||
import net.minestom.server.event.inventory.InventoryPreClickEvent;
|
import net.minestom.server.event.inventory.InventoryPreClickEvent;
|
||||||
import net.minestom.server.inventory.AbstractInventory;
|
import net.minestom.server.inventory.AbstractInventory;
|
||||||
import net.minestom.server.inventory.Inventory;
|
import net.minestom.server.inventory.Inventory;
|
||||||
|
import net.minestom.server.inventory.TransactionOption;
|
||||||
import net.minestom.server.inventory.TransactionType;
|
import net.minestom.server.inventory.TransactionType;
|
||||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||||
import net.minestom.server.inventory.condition.InventoryConditionResult;
|
import net.minestom.server.inventory.condition.InventoryConditionResult;
|
||||||
@ -21,7 +21,9 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
public class InventoryClickProcessor {
|
public class InventoryClickProcessor {
|
||||||
|
|
||||||
@ -342,8 +344,8 @@ public class InventoryClickProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public InventoryClickResult doubleClick(@Nullable Inventory inventory, @NotNull Player player, int slot,
|
public InventoryClickResult doubleClick(@NotNull AbstractInventory clickedInventory, @Nullable Inventory inventory, @NotNull Player player, int slot,
|
||||||
@NotNull ItemStack cursor, @NotNull InventoryClickLoopHandler... loopHandlers) {
|
@NotNull final ItemStack cursor) {
|
||||||
InventoryClickResult clickResult = startCondition(inventory, player, slot, ClickType.START_DOUBLE_CLICK, ItemStack.AIR, cursor);
|
InventoryClickResult clickResult = startCondition(inventory, player, slot, ClickType.START_DOUBLE_CLICK, ItemStack.AIR, cursor);
|
||||||
|
|
||||||
if (clickResult.isCancel()) {
|
if (clickResult.isCancel()) {
|
||||||
@ -354,49 +356,46 @@ public class InventoryClickProcessor {
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
final StackingRule cursorRule = cursor.getStackingRule();
|
final StackingRule cursorRule = cursor.getStackingRule();
|
||||||
int amount = cursorRule.getAmount(cursor);
|
final int amount = cursorRule.getAmount(cursor);
|
||||||
|
final int remainingAmount = cursorRule.getMaxSize() - amount;
|
||||||
|
|
||||||
if (!cursorRule.canApply(cursor, amount + 1))
|
ItemStack remain = cursorRule.apply(cursor, remainingAmount);
|
||||||
return null;
|
|
||||||
|
|
||||||
for (InventoryClickLoopHandler loopHandler : loopHandlers) {
|
BiFunction<AbstractInventory, ItemStack, ItemStack> func = (inv, rest) -> {
|
||||||
final Int2IntFunction indexModifier = loopHandler.getIndexModifier();
|
var pair = TransactionType.TAKE.process(inv, rest, (index, itemStack) -> {
|
||||||
final Int2ObjectFunction<ItemStack> itemGetter = loopHandler.getItemGetter();
|
if (index == slot) // Prevent item lose/duplication
|
||||||
final BiConsumer<Integer, ItemStack> itemSetter = loopHandler.getItemSetter();
|
return false;
|
||||||
|
InventoryClickResult result = startCondition(inventory, player, index, ClickType.DOUBLE_CLICK, itemStack, cursor);
|
||||||
|
return !result.isCancel();
|
||||||
|
});
|
||||||
|
var itemResult = pair.left();
|
||||||
|
var map = pair.right();
|
||||||
|
return TransactionOption.ALL.fill(inv, itemResult, map);
|
||||||
|
};
|
||||||
|
|
||||||
for (int i = loopHandler.getStart(); i < loopHandler.getEnd(); i += loopHandler.getStep()) {
|
var playerInventory = player.getInventory();
|
||||||
final int index = indexModifier.apply(i);
|
|
||||||
if (index == slot)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ItemStack item = itemGetter.apply(index);
|
if (Objects.equals(clickedInventory, inventory)) {
|
||||||
final StackingRule itemRule = item.getStackingRule();
|
// Clicked inside inventory
|
||||||
if (!cursorRule.canApply(cursor, amount + 1))
|
remain = func.apply(inventory, remain);
|
||||||
break;
|
if (!remain.isAir()) {
|
||||||
if (cursorRule.canBeStacked(cursor, item)) {
|
remain = func.apply(playerInventory, remain);
|
||||||
clickResult = startCondition(inventory, player, index, ClickType.DOUBLE_CLICK, item, cursor);
|
|
||||||
if (clickResult.isCancel())
|
|
||||||
break;
|
|
||||||
|
|
||||||
final int totalAmount = amount + cursorRule.getAmount(item);
|
|
||||||
if (!cursorRule.canApply(cursor, totalAmount)) {
|
|
||||||
cursor = cursorRule.apply(cursor, cursorRule.getMaxSize());
|
|
||||||
|
|
||||||
item = itemRule.apply(item, totalAmount - itemRule.getMaxSize());
|
|
||||||
} else {
|
|
||||||
cursor = cursorRule.apply(cursor, totalAmount);
|
|
||||||
item = itemRule.apply(item, 0);
|
|
||||||
}
|
|
||||||
itemSetter.accept(index, item);
|
|
||||||
amount = cursorRule.getAmount(cursor);
|
|
||||||
|
|
||||||
callClickEvent(player, inventory, index, ClickType.DOUBLE_CLICK, item, cursor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (inventory != null && clickedInventory == playerInventory) {
|
||||||
|
// Clicked inside player inventory, but with another inventory open
|
||||||
|
remain = func.apply(playerInventory, remain);
|
||||||
|
if (!remain.isAir()) {
|
||||||
|
remain = func.apply(inventory, remain);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Clicked inside player inventory
|
||||||
|
remain = func.apply(playerInventory, remain);
|
||||||
}
|
}
|
||||||
|
|
||||||
clickResult.setCursor(cursor);
|
final int tookAmount = remainingAmount - cursorRule.getAmount(remain);
|
||||||
|
|
||||||
|
ItemStack resultCursor = cursorRule.apply(cursor, amount + tookAmount);
|
||||||
|
clickResult.setCursor(resultCursor);
|
||||||
return clickResult;
|
return clickResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user