Switch Click.Result to List<Click.Change>

This commit is contained in:
GoldenStack 2024-04-13 21:35:40 -05:00 committed by mworzala
parent d417f42b74
commit 755f934448
No known key found for this signature in database
GPG Key ID: B148F922E64797C7
22 changed files with 390 additions and 419 deletions

View File

@ -9,6 +9,8 @@ import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.inventory.click.Click;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Called after {@link InventoryPreClickEvent} and before {@link InventoryPostClickEvent}.
*/
@ -18,12 +20,12 @@ public class InventoryClickEvent implements InventoryEvent, PlayerInstanceEvent,
private final Inventory inventory;
private final Player player;
private final Click.Info info;
private Click.Result changes;
private List<Click.Change> changes;
private boolean cancelled;
public InventoryClickEvent(@NotNull PlayerInventory playerInventory, @NotNull Inventory inventory,
@NotNull Player player, @NotNull Click.Info info, @NotNull Click.Result changes) {
@NotNull Player player, @NotNull Click.Info info, @NotNull List<Click.Change> changes) {
this.playerInventory = playerInventory;
this.inventory = inventory;
this.player = player;
@ -54,7 +56,7 @@ public class InventoryClickEvent implements InventoryEvent, PlayerInstanceEvent,
*
* @return the changes
*/
public @NotNull Click.Result getChanges() {
public @NotNull List<Click.Change> getChanges() {
return changes;
}
@ -63,7 +65,7 @@ public class InventoryClickEvent implements InventoryEvent, PlayerInstanceEvent,
*
* @param changes the new results
*/
public void setChanges(@NotNull Click.Result changes) {
public void setChanges(@NotNull List<Click.Change> changes) {
this.changes = changes;
}

View File

@ -7,6 +7,8 @@ import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.click.Click;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Called after {@link InventoryClickEvent}, this event cannot be cancelled and items related to the click
* are already moved.
@ -16,9 +18,9 @@ public class InventoryPostClickEvent implements InventoryEvent, PlayerInstanceEv
private final Player player;
private final Inventory inventory;
private final Click.Info info;
private final Click.Result changes;
private final List<Click.Change> changes;
public InventoryPostClickEvent(@NotNull Player player, @NotNull Inventory inventory, @NotNull Click.Info info, @NotNull Click.Result changes) {
public InventoryPostClickEvent(@NotNull Player player, @NotNull Inventory inventory, @NotNull Click.Info info, @NotNull List<Click.Change> changes) {
this.player = player;
this.inventory = inventory;
this.info = info;
@ -49,7 +51,7 @@ public class InventoryPostClickEvent implements InventoryEvent, PlayerInstanceEv
*
* @return the changes
*/
public @NotNull Click.Result getChanges() {
public @NotNull List<Click.Change> getChanges() {
return changes;
}

View File

@ -15,6 +15,7 @@ import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
@ -33,7 +34,7 @@ public non-sealed class ContainerInventory extends InventoryImpl {
* @param info the click info describing the click
* @return the click result, or null if the click did not occur
*/
public static @Nullable Click.Result handleClick(@NotNull Inventory inventory, @NotNull Player player, @NotNull Click.Info info,
public static @Nullable List<Click.Change> handleClick(@NotNull Inventory inventory, @NotNull Player player, @NotNull Click.Info info,
@NotNull ClickProcessors.InventoryProcessor processor) {
PlayerInventory playerInventory = player.getInventory();
@ -42,13 +43,13 @@ public non-sealed class ContainerInventory extends InventoryImpl {
if (!preClickEvent.isCancelled()) {
final Click.Info newInfo = preClickEvent.getClickInfo();
Click.Getter getter = new Click.Getter(inventory::getItemStack, playerInventory::getItemStack, playerInventory.getCursorItem(), inventory.getSize());
final Click.Result changes = processor.apply(newInfo, getter);
final List<Click.Change> changes = processor.apply(newInfo, getter);
InventoryClickEvent clickEvent = new InventoryClickEvent(playerInventory, inventory, player, newInfo, changes);
EventDispatcher.call(clickEvent);
if (!clickEvent.isCancelled()) {
final Click.Result newChanges = clickEvent.getChanges();
final List<Click.Change> newChanges = clickEvent.getChanges();
apply(newChanges, player, inventory);
@ -72,29 +73,22 @@ public non-sealed class ContainerInventory extends InventoryImpl {
return null;
}
public static void apply(@NotNull Click.Result result, @NotNull Player player, @NotNull Inventory inventory) {
public static void apply(@NotNull List<Click.Change> changes, @NotNull Player player, @NotNull Inventory inventory) {
PlayerInventory playerInventory = player.getInventory();
for (var change : result.changes()) {
if (change instanceof Click.Change.Main(int slot, ItemStack item)) {
if (slot < inventory.getSize()) {
inventory.setItemStack(slot, item);
} else {
int converted = PlayerInventoryUtils.protocolToMinestom(slot, inventory.getSize());
playerInventory.setItemStack(converted, item);
for (var change : changes) {
switch (change) {
case Click.Change.Main(int slot, ItemStack item) -> {
if (slot < inventory.getSize()) {
inventory.setItemStack(slot, item);
} else {
int converted = PlayerInventoryUtils.protocolToMinestom(slot, inventory.getSize());
playerInventory.setItemStack(converted, item);
}
}
} else if (change instanceof Click.Change.Player(int slot, ItemStack item)) {
playerInventory.setItemStack(slot, item);
}
}
if (result.newCursorItem() != null) {
playerInventory.setCursorItem(result.newCursorItem());
}
if (result.sideEffects() instanceof Click.SideEffect.DropFromPlayer drop) {
for (ItemStack item : drop.items()) {
player.dropItem(item);
case Click.Change.Player(int slot, ItemStack item) -> playerInventory.setItemStack(slot, item);
case Click.Change.Cursor(ItemStack item) -> playerInventory.setCursorItem(item);
case Click.Change.DropFromPlayer(ItemStack item) -> player.dropItem(item);
}
}
}
@ -152,7 +146,7 @@ public non-sealed class ContainerInventory extends InventoryImpl {
}
@Override
public @Nullable Click.Result handleClick(@NotNull Player player, Click.@NotNull Info info) {
public @Nullable List<Click.Change> handleClick(@NotNull Player player, Click.@NotNull Info info) {
return ContainerInventory.handleClick(this, player, info,
ClickProcessors.PROCESSORS_MAP.getOrDefault(inventoryType, ClickProcessors.GENERIC_PROCESSOR));
}

View File

@ -5,7 +5,6 @@ import net.minestom.server.entity.Player;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.tag.Taggable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -54,7 +53,7 @@ public sealed interface Inventory extends Taggable, Viewable permits InventoryIm
* @param info the information about the player's click
* @return the results of the click, or null if the click was cancelled or otherwise was not handled
*/
@Nullable Click.Result handleClick(@NotNull Player player, @NotNull Click.Info info);
@Nullable List<Click.Change> handleClick(@NotNull Player player, @NotNull Click.Info info);
/**
* Gets all the {@link ItemStack} in the inventory.

View File

@ -158,7 +158,7 @@ public non-sealed class PlayerInventory extends InventoryImpl {
}
@Override
public @Nullable Click.Result handleClick(@NotNull Player player, @NotNull Click.Info info) {
public @Nullable List<Click.Change> handleClick(@NotNull Player player, @NotNull Click.Info info) {
return ContainerInventory.handleClick(this, player, info, ClickProcessors.PLAYER_PROCESSOR);
}

View File

@ -205,70 +205,16 @@ public final class Click {
}
public sealed interface Change {
record Main(int slot, @NotNull ItemStack item) implements Change {}
record Player(int slot, @NotNull ItemStack item) implements Change {}
}
public static final class Setter {
private final List<Change> changes = new ArrayList<>();
private @Nullable ItemStack cursor;
private @Nullable SideEffect sideEffect;
Setter() {
record Main(int slot, @NotNull ItemStack item) implements Change {
}
public @NotNull Setter set(int slot, @NotNull ItemStack item) {
changes.add(new Change.Main(slot, item));
return this;
record Player(int slot, @NotNull ItemStack item) implements Change {
}
public @NotNull Setter setPlayer(int slot, @NotNull ItemStack item) {
changes.add(new Change.Player(slot, item));
return this;
record Cursor(@NotNull ItemStack item) implements Change {
}
public @NotNull Setter cursor(@Nullable ItemStack newCursorItem) {
this.cursor = newCursorItem;
return this;
}
public @NotNull Setter sideEffects(@Nullable SideEffect sideEffect) {
this.sideEffect = sideEffect;
return this;
}
public @NotNull Click.Result build() {
return new Result(changes, cursor, sideEffect);
}
}
/**
* Stores changes that occurred or will occur as the result of a click.
*
* @param changes the list of changes that will occur
* @param newCursorItem the player's cursor item after this click. Null indicates no change
* @param sideEffects the side effects of this click
*/
public record Result(@NotNull List<Change> changes, @Nullable ItemStack newCursorItem, @Nullable Click.SideEffect sideEffects) {
public static final Result NOTHING = new Result(List.of(), null, null);
public Result {
changes = List.copyOf(changes);
}
}
/**
* Represents side effects that may occur as the result of an inventory click.
*/
public sealed interface SideEffect {
record DropFromPlayer(@NotNull List<@NotNull ItemStack> items) implements SideEffect {
public DropFromPlayer {
items = List.copyOf(items);
}
public DropFromPlayer(@NotNull ItemStack @NotNull ... items) {
this(List.of(items));
}
record DropFromPlayer(@NotNull ItemStack item) implements Change {
}
}
}

View File

@ -8,6 +8,7 @@ import net.minestom.server.inventory.TransactionType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.StackingRule;
import net.minestom.server.inventory.click.Click.Change.*;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import org.jetbrains.annotations.NotNull;
@ -28,125 +29,123 @@ import static net.minestom.server.utils.inventory.PlayerInventoryUtils.*;
public final class ClickProcessors {
private static final @NotNull StackingRule RULE = StackingRule.get();
public static @NotNull Click.Result leftClick(int slot, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> leftClick(int slot, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
final ItemStack clickedItem = getter.get(slot);
Pair<ItemStack, ItemStack> pair = TransactionOperator.STACK_LEFT.apply(clickedItem, cursor);
if (pair != null) { // Stackable items, combine their counts
return new Click.Setter().set(slot, pair.left()).cursor(pair.right()).build();
return List.of(new Main(slot, pair.left()), new Cursor(pair.right()));
} else if (!RULE.canBeStacked(cursor, clickedItem)) { // If they're unstackable, switch them
return new Click.Setter().set(slot, cursor).cursor(clickedItem).build();
return List.of(new Main(slot, cursor), new Cursor(clickedItem));
} else {
return Click.Result.NOTHING;
return List.of();
}
}
public static @NotNull Click.Result rightClick(int slot, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> rightClick(int slot, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
final ItemStack clickedItem = getter.get(slot);
if (cursor.isAir() && clickedItem.isAir()) return Click.Result.NOTHING; // Both are air, no changes
if (cursor.isAir() && clickedItem.isAir()) return List.of(); // Both are air, no changes
if (cursor.isAir()) { // Take half (rounded up) of the clicked item
int newAmount = (int) Math.ceil(RULE.getAmount(clickedItem) / 2d);
Pair<ItemStack, ItemStack> cursorSlot = TransactionOperator.stackLeftN(newAmount).apply(cursor, clickedItem);
return cursorSlot == null ? Click.Result.NOTHING :
new Click.Setter().cursor(cursorSlot.left()).set(slot, cursorSlot.right()).build();
if (cursorSlot == null) return List.of();
return List.of(new Main(slot, cursorSlot.right()), new Cursor(cursorSlot.left()));
} else if (clickedItem.isAir() || RULE.canBeStacked(clickedItem, cursor)) { // Can add, transfer one over
Pair<ItemStack, ItemStack> slotCursor = TransactionOperator.stackLeftN(1).apply(clickedItem, cursor);
return slotCursor == null ? Click.Result.NOTHING :
new Click.Setter().set(slot, slotCursor.left()).cursor(slotCursor.right()).build();
if (slotCursor == null) return List.of();
return List.of(new Main(slot, slotCursor.left()), new Cursor(slotCursor.right()));
} else { // Two existing of items of different types, so switch
return new Click.Setter().cursor(clickedItem).set(slot, cursor).build();
return List.of(new Cursor(clickedItem), new Main(slot, cursor));
}
}
public static @NotNull Click.Result middleClick(int slot, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> middleClick(int slot, @NotNull Click.Getter getter) {
var item = getter.get(slot);
if (getter.cursor().isAir() && !item.isAir()) {
return new Click.Setter().cursor(RULE.apply(item, RULE.getMaxSize(item))).build();
} else {
return Click.Result.NOTHING;
}
if (!getter.cursor().isAir() || item.isAir()) return List.of();
return List.of(new Cursor(RULE.apply(item, RULE.getMaxSize(item))));
}
public static @NotNull Click.Result shiftClick(int slot, @NotNull List<Integer> slots, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> shiftClick(int slot, @NotNull List<Integer> slots, @NotNull Click.Getter getter) {
final ItemStack clicked = getter.get(slot);
slots = new ArrayList<>(slots);
slots.removeIf(i -> i == slot);
Pair<ItemStack, Map<Integer, ItemStack>> result = TransactionType.add(slots, slots).process(clicked, getter::get);
Click.Setter setter = new Click.Setter();
result.right().forEach(setter::set);
List<Click.Change> changes = new ArrayList<>();
result.right().forEach((slotId, item) -> changes.add(new Main(slotId, item)));
return !result.left().equals(clicked) ?
setter.set(slot, result.left()).build() :
setter.build();
if (!result.left().equals(clicked)) {
changes.add(new Main(slot, result.left()));
}
return changes;
}
public static @NotNull Click.Result doubleClick(@NotNull List<Integer> slots, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> doubleClick(@NotNull List<Integer> slots, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
if (cursor.isAir()) return Click.Result.NOTHING;
if (cursor.isAir()) return List.of();
var unstacked = TransactionType.general(TransactionOperator.filter(TransactionOperator.STACK_RIGHT, (left, right) -> RULE.getAmount(left) < RULE.getMaxSize(left)), slots);
var stacked = TransactionType.general(TransactionOperator.filter(TransactionOperator.STACK_RIGHT, (left, right) -> RULE.getAmount(left) == RULE.getMaxSize(left)), slots);
Pair<ItemStack, Map<Integer, ItemStack>> result = TransactionType.join(unstacked, stacked).process(cursor, getter::get);
Click.Setter setter = new Click.Setter();
result.right().forEach(setter::set);
List<Click.Change> changes = new ArrayList<>();
result.right().forEach((slotId, item) -> changes.add(new Main(slotId, item)));
return !result.left().equals(cursor) ?
setter.cursor(result.left()).build() :
setter.build();
if (!result.left().equals(cursor)) {
changes.add(new Cursor(result.left()));
}
return changes;
}
public static @NotNull Click.Result dragClick(int countPerSlot, @NotNull List<Integer> slots, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> dragClick(int countPerSlot, @NotNull List<Integer> slots, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
if (cursor.isAir()) return Click.Result.NOTHING;
if (cursor.isAir()) return List.of();
Pair<ItemStack, Map<Integer, ItemStack>> result = TransactionType.general(TransactionOperator.stackLeftN(countPerSlot), slots).process(cursor, getter::get);
Click.Setter setter = new Click.Setter();
result.right().forEach(setter::set);
List<Click.Change> changes = new ArrayList<>();
result.right().forEach((slotId, item) -> changes.add(new Main(slotId, item)));
return !result.left().equals(cursor) ?
setter.cursor(result.left()).build() :
setter.build();
}
public static @NotNull Click.Result middleDragClick(@NotNull List<Integer> slots, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
Click.Setter setter = new Click.Setter();
for (int slot : slots) {
if (getter.get(slot).isAir()) {
setter.set(slot, cursor);
}
if (!result.left().equals(cursor)) {
changes.add(new Cursor(result.left()));
}
return setter.build();
return changes;
}
public static @NotNull Click.Result dropFromCursor(int amount, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> middleDragClick(@NotNull List<Integer> slots, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
if (cursor.isAir()) return Click.Result.NOTHING; // Do nothing
return slots.stream()
.filter(slot -> getter.get(slot).isAir())
.map(slot -> (Click.Change) new Main(slot, cursor))
.toList();
}
public static @NotNull List<Click.Change> dropFromCursor(int amount, @NotNull Click.Getter getter) {
final ItemStack cursor = getter.cursor();
if (cursor.isAir()) return List.of(); // Do nothing
var pair = TransactionOperator.stackLeftN(amount).apply(ItemStack.AIR, cursor);
if (pair == null) return Click.Result.NOTHING;
if (pair == null) return List.of();
return new Click.Setter().cursor(pair.right())
.sideEffects(new Click.SideEffect.DropFromPlayer(pair.left()))
.build();
return List.of(new Cursor(pair.right()), new DropFromPlayer(pair.left()));
}
public static @NotNull Click.Result dropFromSlot(int slot, int amount, @NotNull Click.Getter getter) {
public static @NotNull List<Click.Change> dropFromSlot(int slot, int amount, @NotNull Click.Getter getter) {
final ItemStack item = getter.get(slot);
if (item.isAir()) return Click.Result.NOTHING; // Do nothing
if (item.isAir()) return List.of(); // Do nothing
var pair = TransactionOperator.stackLeftN(amount).apply(ItemStack.AIR, item);
if (pair == null) return Click.Result.NOTHING;
if (pair == null) return List.of();
return new Click.Setter().set(slot, pair.right())
.sideEffects(new Click.SideEffect.DropFromPlayer(pair.left()))
.build();
return List.of(new Main(slot, pair.right()), new DropFromPlayer(pair.left()));
}
/**
@ -181,28 +180,28 @@ public final class ClickProcessors {
dropFromSlot(slot, all ? RULE.getAmount(getter.get(slot)) : 1, getter);
case Click.Info.LeftDropCursor() -> dropFromCursor(getter.cursor().amount(), getter);
case Click.Info.RightDropCursor() -> dropFromCursor(1, getter);
case Click.Info.MiddleDropCursor() -> Click.Result.NOTHING;
case Click.Info.MiddleDropCursor() -> List.of();
case Click.Info.HotbarSwap(int hotbarSlot, int clickedSlot) -> {
var hotbarItem = getter.player().apply(hotbarSlot);
var selectedItem = getter.get(clickedSlot);
if (hotbarItem.equals(selectedItem)) yield Click.Result.NOTHING;
if (hotbarItem.equals(selectedItem)) yield List.of();
yield new Click.Setter().set(clickedSlot, hotbarItem).setPlayer(hotbarSlot, selectedItem).build();
yield List.of(new Main(clickedSlot, hotbarItem), new Player(hotbarSlot, selectedItem));
}
case Click.Info.OffhandSwap(int slot) -> {
var offhandItem = getter.player().apply(PlayerInventoryUtils.OFF_HAND_SLOT);
var selectedItem = getter.get(slot);
if (offhandItem.equals(selectedItem)) yield Click.Result.NOTHING;
if (offhandItem.equals(selectedItem)) yield List.of();
yield new Click.Setter().set(slot, offhandItem).setPlayer(PlayerInventoryUtils.OFF_HAND_SLOT, selectedItem).build();
yield List.of(new Main(slot, offhandItem), new Player(OFF_HAND_SLOT, selectedItem));
}
case Click.Info.CreativeSetItem(int slot, ItemStack item) -> new Click.Setter().set(slot, item).build();
case Click.Info.CreativeSetItem(int slot, ItemStack item) -> List.of(new Main(slot, item));
case Click.Info.CreativeDropItem(ItemStack item) ->
new Click.Setter().sideEffects(new Click.SideEffect.DropFromPlayer(item)).build();
List.of(new DropFromPlayer(item));
};
}
public interface InventoryProcessor extends BiFunction<Click.Info, Click.Getter, Click.Result> {
public interface InventoryProcessor extends BiFunction<Click.Info, Click.Getter, List<Click.Change>> {
}
/**

View File

@ -5,6 +5,7 @@ import net.minestom.server.inventory.ContainerInventory;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.client.play.ClientClickWindowPacket;
import net.minestom.server.network.packet.server.SendablePacket;
import net.minestom.server.network.player.PlayerConnection;
@ -14,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
import java.net.SocketAddress;
import java.util.*;
import java.util.function.UnaryOperator;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -31,6 +31,14 @@ public final class ClickUtils {
return new Click.Preprocessor();
}
public static @NotNull ItemStack magic(int amount) {
return ItemStack.of(Material.STONE, amount);
}
public static @NotNull ItemStack magic2(int amount) {
return ItemStack.of(Material.DIRT, amount);
}
public static @NotNull Player createPlayer() {
return new Player(UUID.randomUUID(), "TestPlayer", new PlayerConnection() {
@Override
@ -48,67 +56,56 @@ public final class ClickUtils {
});
}
public static void assertClick(@NotNull UnaryOperator<Click.Setter> initialChanges, @NotNull Click.Info info, @NotNull UnaryOperator<Click.Setter> expectedChanges) {
public static void assertClick(@NotNull List<Click.Change> initial, @NotNull Click.Info info, @NotNull List<Click.Change> expected) {
var player = createPlayer();
var inventory = createInventory();
var expected = expectedChanges.apply(new Click.Setter()).build();
ContainerInventory.apply(initialChanges.apply(new Click.Setter()).build(), player, inventory);
ContainerInventory.apply(initial, player, inventory);
var actual = inventory.handleClick(player, info);
assertChanges(expected, actual, inventory.getSize());
}
public static void assertPlayerClick(@NotNull UnaryOperator<Click.Setter> initialChanges, @NotNull Click.Info info, @NotNull UnaryOperator<Click.Setter> expectedChanges) {
public static void assertPlayerClick(@NotNull List<Click.Change> initial, @NotNull Click.Info info, @NotNull List<Click.Change> expected) {
var player = createPlayer();
var inventory = player.getInventory();
var expected = expectedChanges.apply(new Click.Setter()).build();
ContainerInventory.apply(initialChanges.apply(new Click.Setter()).build(), player, inventory);
ContainerInventory.apply(initial, player, inventory);
var actual = inventory.handleClick(player, info);
assertChanges(expected, actual, inventory.getSize());
}
public static void assertChanges(Click.Result expected, Click.Result actual, int size) {
if (expected == null || actual == null) {
assertEquals(expected, actual);
return;
}
assertEquals(foldMain(expected.changes(), size), foldMain(actual.changes(), size));
assertEquals(foldPlayer(expected.changes(), size), foldPlayer(actual.changes(), size));
assertEquals(expected.newCursorItem(), actual.newCursorItem());
assertEquals(expected.sideEffects(), actual.sideEffects());
public static void assertChanges(List<Click.Change> expected, List<Click.Change> actual, int size) {
assertEquals(ChangeResult.make(expected, size), ChangeResult.make(actual, size));
}
private static Map<Integer, ItemStack> foldMain(List<Click.Change> changes, int size) {
Map<Integer, ItemStack> map = new HashMap<>();
private record ChangeResult(Map<Integer, ItemStack> main, Map<Integer, ItemStack> player,
@Nullable ItemStack cursor, List<ItemStack> drops) {
private static ChangeResult make(@NotNull List<Click.Change> changes, int size) {
Map<Integer, ItemStack> main = new HashMap<>();
Map<Integer, ItemStack> player = new HashMap<>();
@Nullable ItemStack cursor = null;
List<ItemStack> drops = new ArrayList<>();
for (var change : changes) {
if (change instanceof Click.Change.Main(int slot, ItemStack item) && slot < size) {
map.put(slot, item);
for (var change : changes) {
switch (change) {
case Click.Change.Main(int slot, ItemStack item) -> {
if (slot < size) {
main.put(slot, item);
} else {
player.put(PlayerInventoryUtils.protocolToMinestom(slot, size), item);
}
}
case Click.Change.Player(int slot, ItemStack item) -> player.put(slot, item);
case Click.Change.Cursor(ItemStack item) -> cursor = item;
case Click.Change.DropFromPlayer(ItemStack item) -> drops.add(item);
}
}
return new ChangeResult(main, player, cursor, drops);
}
return map;
}
private static Map<Integer, ItemStack> foldPlayer(List<Click.Change> changes, int size) {
Map<Integer, ItemStack> map = new HashMap<>();
for (var change : changes) {
if (change instanceof Click.Change.Main(int slot, ItemStack item) && slot >= size) {
map.put(PlayerInventoryUtils.protocolToMinestom(slot, size), item);
} else if (change instanceof Click.Change.Player(int slot, ItemStack item)) {
map.put(slot, item);
}
}
return map;
}
public static void assertProcessed(@NotNull Click.Preprocessor preprocessor, @NotNull Player player, @Nullable Click.Info info, @NotNull ClientClickWindowPacket packet) {

View File

@ -2,11 +2,13 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.inventory.click.Click.Change.DropFromPlayer;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryCreativeDropItemTest {
@ -17,16 +19,16 @@ public class InventoryCreativeDropItemTest {
@Test
public void testDropItem() {
assertClick(
builder -> builder,
new Click.Info.CreativeDropItem(ItemStack.of(Material.DIRT, 64)),
builder -> builder.sideEffects(new Click.SideEffect.DropFromPlayer(ItemStack.of(Material.DIRT, 64)))
List.of(),
new Click.Info.CreativeDropItem(magic(64)),
List.of(new DropFromPlayer(magic(64)))
);
// Make sure it doesn't drop a full stack
assertClick(
builder -> builder,
new Click.Info.CreativeDropItem(ItemStack.of(Material.DIRT, 1)),
builder -> builder.sideEffects(new Click.SideEffect.DropFromPlayer(ItemStack.of(Material.DIRT, 1)))
List.of(),
new Click.Info.CreativeDropItem(magic(1)),
List.of(new DropFromPlayer(magic(1)))
);
}

View File

@ -2,11 +2,13 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.inventory.click.Click.Change.Main;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryCreativeSetItemTest {
@ -17,16 +19,16 @@ public class InventoryCreativeSetItemTest {
@Test
public void testSetItem() {
assertClick(
builder -> builder,
new Click.Info.CreativeSetItem(0, ItemStack.of(Material.DIRT, 64)),
builder -> builder.set(0, ItemStack.of(Material.DIRT, 64))
List.of(),
new Click.Info.CreativeSetItem(0, magic(64)),
List.of(new Main(0, magic(64)))
);
// Make sure it doesn't set a full stack
assertClick(
builder -> builder,
new Click.Info.CreativeSetItem(0, ItemStack.of(Material.DIRT, 1)),
builder -> builder.set(0, ItemStack.of(Material.DIRT, 1))
List.of(),
new Click.Info.CreativeSetItem(0, magic(1)),
List.of(new Main(0, magic(1)))
);
}

View File

@ -2,11 +2,15 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.Main;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryDoubleClickTest {
@ -16,75 +20,63 @@ public class InventoryDoubleClickTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.Double(0), builder -> builder);
assertClick(List.of(), new Click.Info.Double(0), List.of());
}
@Test
public void testCannotTakeAny() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.Double(0),
builder -> builder
List.of()
);
}
@Test
public void testPartialTake() {
assertClick(
builder -> builder.set(1, ItemStack.of(Material.STONE, 48)).cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(1, magic(48)), new Cursor(magic(32))),
new Click.Info.Double(0),
builder -> builder.set(1, ItemStack.of(Material.STONE, 16)).cursor(ItemStack.of(Material.STONE, 64))
List.of(new Main(1, magic(16)), new Cursor(magic(64)))
);
}
@Test
public void testTakeAll() {
assertClick(
builder -> builder.set(1, ItemStack.of(Material.STONE, 32)).cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(1, magic(32)), new Cursor(magic(32))),
new Click.Info.Double(0),
builder -> builder.set(1, ItemStack.AIR).cursor(ItemStack.of(Material.STONE, 64))
List.of(new Main(1, ItemStack.AIR), new Cursor(magic(64)))
);
assertClick(
builder -> builder.set(1, ItemStack.of(Material.STONE, 16)).cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(1, magic(16)), new Cursor(magic(32))),
new Click.Info.Double(0),
builder -> builder.set(1, ItemStack.AIR).cursor(ItemStack.of(Material.STONE, 48))
List.of(new Main(1, ItemStack.AIR), new Cursor(magic(48)))
);
}
@Test
public void testTakeSeparated() {
assertClick(
builder -> builder
.set(1, ItemStack.of(Material.STONE, 16))
.set(2, ItemStack.of(Material.STONE, 16))
.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(1, magic(16)), new Main(2, magic(16)), new Cursor(magic(32))),
new Click.Info.Double(0),
builder -> builder
.set(1, ItemStack.AIR)
.set(2, ItemStack.AIR)
.cursor(ItemStack.of(Material.STONE, 64))
List.of(new Main(1, ItemStack.AIR), new Main(2, ItemStack.AIR), new Cursor(magic(64)))
);
assertClick(
builder -> builder
.set(1, ItemStack.of(Material.STONE, 16))
.set(2, ItemStack.of(Material.STONE, 32))
.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(1, magic(16)), new Main(2, magic(32)), new Cursor(magic(32))),
new Click.Info.Double(0),
builder -> builder
.set(1, ItemStack.AIR)
.set(2, ItemStack.of(Material.STONE, 16))
.cursor(ItemStack.of(Material.STONE, 64))
List.of(new Main(1, ItemStack.AIR), new Main(2, magic(16)), new Cursor(magic(64)))
);
}
@Test
public void testCursorFull() {
assertClick(
builder -> builder.set(1, ItemStack.of(Material.STONE, 48)).cursor(ItemStack.of(Material.STONE, 64)),
List.of(new Main(1, magic(48)), new Cursor(magic(64))),
new Click.Info.Double(0),
builder -> builder
List.of()
);
}

View File

@ -2,11 +2,15 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.DropFromPlayer;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryDropCursorTest {
@ -16,35 +20,35 @@ public class InventoryDropCursorTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.LeftDropCursor(), builder -> builder);
assertClick(builder -> builder, new Click.Info.MiddleDropCursor(), builder -> builder);
assertClick(builder -> builder, new Click.Info.RightDropCursor(), builder -> builder);
assertClick(List.of(), new Click.Info.LeftDropCursor(), List.of());
assertClick(List.of(), new Click.Info.MiddleDropCursor(), List.of());
assertClick(List.of(), new Click.Info.RightDropCursor(), List.of());
}
@Test
public void testDropEntireStack() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.LeftDropCursor(),
builder -> builder.cursor(ItemStack.AIR).sideEffects(new Click.SideEffect.DropFromPlayer(ItemStack.of(Material.STONE, 32)))
List.of(new Cursor(ItemStack.AIR), new DropFromPlayer(magic(32)))
);
}
@Test
public void testDropSingleItem() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.RightDropCursor(),
builder -> builder.cursor(ItemStack.of(Material.STONE, 31)).sideEffects(new Click.SideEffect.DropFromPlayer(ItemStack.of(Material.STONE, 1)))
List.of(new Cursor(magic(31)), new DropFromPlayer(magic(1)))
);
}
@Test
public void testMiddleClickNoop() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.MiddleDropCursor(),
builder -> builder
List.of()
);
}

View File

@ -2,11 +2,15 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.DropFromPlayer;
import net.minestom.server.inventory.click.Click.Change.Main;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryDropSlotTest {
@ -16,25 +20,25 @@ public class InventoryDropSlotTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.DropSlot(0, false), builder -> builder);
assertClick(builder -> builder, new Click.Info.DropSlot(0, true), builder -> builder);
assertClick(List.of(), new Click.Info.DropSlot(0, false), List.of());
assertClick(List.of(), new Click.Info.DropSlot(0, true), List.of());
}
@Test
public void testDropEntireStack() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)),
List.of(new Main(0, magic(32))),
new Click.Info.DropSlot(0, true),
builder -> builder.set(0, ItemStack.AIR).sideEffects(new Click.SideEffect.DropFromPlayer(ItemStack.of(Material.STONE, 32)))
List.of(new Main(0, ItemStack.AIR), new DropFromPlayer(magic(32)))
);
}
@Test
public void testDropSingleItem() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)),
List.of(new Main(0, magic(32))),
new Click.Info.DropSlot(0, false),
builder -> builder.set(0, ItemStack.of(Material.STONE, 31)).sideEffects(new Click.SideEffect.DropFromPlayer(ItemStack.of(Material.STONE, 1)))
List.of(new Main(0, magic(31)), new DropFromPlayer(magic(1)))
);
}

View File

@ -2,11 +2,13 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.inventory.click.Click.Change.Main;
import net.minestom.server.inventory.click.Click.Change.Player;
import org.junit.jupiter.api.Test;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.*;
public class InventoryHotbarSwapTest {
@ -17,16 +19,16 @@ public class InventoryHotbarSwapTest {
@Test
public void testNoChanges() {
for (int i = 0; i < 9; i++) {
assertClick(builder -> builder, new Click.Info.HotbarSwap(i, 9), builder -> builder);
assertClick(List.of(), new Click.Info.HotbarSwap(i, 9), List.of());
}
}
@Test
public void testSwappedItems() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT)).setPlayer(0, ItemStack.of(Material.STONE)),
List.of(new Main(0, magic2(1)), new Player(0, magic(1))),
new Click.Info.HotbarSwap(0, 0),
builder -> builder.set(0, ItemStack.of(Material.STONE)).setPlayer(0, ItemStack.of(Material.DIRT))
List.of(new Main(0, magic(1)), new Player(0, magic2(1)))
);
}

View File

@ -2,11 +2,14 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.Main;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.junit.jupiter.api.Test;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.*;
public class InventoryLeftClickTest {
@ -16,33 +19,33 @@ public class InventoryLeftClickTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.Left(0), builder -> builder);
assertClick(List.of(), new Click.Info.Left(0), List.of());
}
@Test
public void testInsertEntireStack() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)).cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(0, magic(32)), new Click.Change.Cursor(magic(32))),
new Click.Info.Left(0),
builder -> builder.set(0, ItemStack.of(Material.STONE, 64)).cursor(ItemStack.AIR)
List.of(new Main(0, magic(64)), new Cursor(ItemStack.AIR))
);
}
@Test
public void testInsertPartialStack() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)).cursor(ItemStack.of(Material.STONE, 48)),
List.of(new Main(0, magic(32)), new Cursor(magic(48))),
new Click.Info.Left(0),
builder -> builder.set(0, ItemStack.of(Material.STONE, 64)).cursor(ItemStack.of(Material.STONE, 16))
List.of(new Main(0, magic(64)), new Cursor(magic(16)))
);
}
@Test
public void testSwitchItems() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE)).cursor(ItemStack.of(Material.DIRT)),
List.of(new Main(0, magic(1)), new Cursor(magic2(1))),
new Click.Info.Left(0),
builder -> builder.set(0, ItemStack.of(Material.DIRT)).cursor(ItemStack.of(Material.STONE))
List.of(new Main(0, magic2(1)), new Cursor(magic(1)))
);
}

View File

@ -3,11 +3,15 @@ package net.minestom.server.inventory.click.type;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.Main;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryLeftDragTest {
@ -17,85 +21,88 @@ public class InventoryLeftDragTest {
@Test
public void testNoCursor() {
assertClick(builder -> builder, new Click.Info.LeftDrag(IntList.of(0)), builder -> builder);
assertClick(List.of(), new Click.Info.LeftDrag(IntList.of(0)), List.of());
}
@Test
public void testDistributeNone() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.LeftDrag(IntList.of()),
builder -> builder
List.of()
);
}
@Test
public void testDistributeOne() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.LeftDrag(IntList.of(0)),
builder -> builder.set(0, ItemStack.of(Material.DIRT, 32)).cursor(ItemStack.of(Material.AIR))
List.of(new Main(0, magic(32)), new Cursor(ItemStack.AIR))
);
}
@Test
public void testDistributeExactlyEnough() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.LeftDrag(IntList.of(0, 1)),
builder -> builder.set(0, ItemStack.of(Material.DIRT, 16)).set(1, ItemStack.of(Material.DIRT, 16)).cursor(ItemStack.of(Material.AIR))
List.of(new Main(0, magic(16)), new Main(1, magic(16)), new Cursor(ItemStack.AIR))
);
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 30)),
List.of(new Cursor(magic(30))),
new Click.Info.LeftDrag(IntList.of(0, 1, 2)),
builder -> builder
.set(0, ItemStack.of(Material.DIRT, 10))
.set(1, ItemStack.of(Material.DIRT, 10))
.set(2, ItemStack.of(Material.DIRT, 10))
.cursor(ItemStack.of(Material.AIR))
List.of(
new Main(0, magic(10)),
new Main(1, magic(10)),
new Main(2, magic(10)),
new Cursor(ItemStack.AIR)
)
);
}
@Test
public void testRemainderItems() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.LeftDrag(IntList.of(0, 1, 2)),
builder -> builder
.set(0, ItemStack.of(Material.DIRT, 10))
.set(1, ItemStack.of(Material.DIRT, 10))
.set(2, ItemStack.of(Material.DIRT, 10))
.cursor(ItemStack.of(Material.DIRT, 2))
List.of(
new Main(0, magic(10)),
new Main(1, magic(10)),
new Main(2, magic(10)),
new Cursor(magic(2))
)
);
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 25)),
List.of(new Cursor(magic(25))),
new Click.Info.LeftDrag(IntList.of(0, 1, 2, 3)),
builder -> builder
.set(0, ItemStack.of(Material.DIRT, 6))
.set(1, ItemStack.of(Material.DIRT, 6))
.set(2, ItemStack.of(Material.DIRT, 6))
.set(3, ItemStack.of(Material.DIRT, 6))
.cursor(ItemStack.of(Material.DIRT, 1))
List.of(
new Main(0, magic(6)),
new Main(1, magic(6)),
new Main(2, magic(6)),
new Main(3, magic(6)),
new Cursor(magic(1))
)
);
}
@Test
public void testDistributeOverExisting() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT, 16)).cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Main(0, magic(16)), new Cursor(magic(32))),
new Click.Info.LeftDrag(IntList.of(0)),
builder -> builder.set(0, ItemStack.of(Material.DIRT, 48)).cursor(ItemStack.of(Material.AIR))
List.of(new Main(0, magic(48)), new Cursor(ItemStack.AIR))
);
}
@Test
public void testDistributeOverFull() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT, 64)).cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Main(0, magic(64)), new Cursor(magic(32))),
new Click.Info.LeftDrag(IntList.of(0)),
builder -> builder
List.of()
);
}

View File

@ -2,11 +2,14 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.Main;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryMiddleClickTest {
@ -16,24 +19,24 @@ public class InventoryMiddleClickTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.Middle(0), builder -> builder);
assertClick(List.of(), new Click.Info.Middle(0), List.of());
}
@Test
public void testCopy() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT, 64)),
List.of(new Main(0, magic(64))),
new Click.Info.Middle(0),
builder -> builder.cursor(ItemStack.of(Material.DIRT, 64))
List.of(new Cursor(magic(64)))
);
}
@Test
public void testCopyNotFull() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT, 32)),
List.of(new Main(0, magic(32))),
new Click.Info.Middle(0),
builder -> builder.cursor(ItemStack.of(Material.DIRT, 64))
List.of(new Cursor(magic(64)))
);
}

View File

@ -3,11 +3,13 @@ package net.minestom.server.inventory.click.type;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.Main;
import org.junit.jupiter.api.Test;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.*;
public class InventoryMiddleDragTest {
@ -17,33 +19,33 @@ public class InventoryMiddleDragTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.MiddleDrag(IntList.of()), builder -> builder);
assertClick(List.of(), new Click.Info.MiddleDrag(IntList.of()), List.of());
}
@Test
public void testExistingSlots() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE)).cursor(ItemStack.of(Material.DIRT)),
List.of(new Main(0, magic(1)), new Cursor(magic2(1))),
new Click.Info.MiddleDrag(IntList.of(0)),
builder -> builder
List.of()
);
}
@Test
public void testPartialExistingSlots() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE)).cursor(ItemStack.of(Material.DIRT)),
List.of(new Main(0, magic(1)), new Cursor(magic2(1))),
new Click.Info.MiddleDrag(IntList.of(0, 1)),
builder -> builder.set(1, ItemStack.of(Material.DIRT))
List.of(new Main(1, magic2(1)))
);
}
@Test
public void testFullCopy() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT)),
List.of(new Cursor(magic(1))),
new Click.Info.MiddleDrag(IntList.of(0, 1)),
builder -> builder.set(0, ItemStack.of(Material.DIRT)).set(1, ItemStack.of(Material.DIRT))
List.of(new Main(0, magic(1)), new Main(1, magic(1)))
);
}

View File

@ -2,12 +2,14 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import net.minestom.server.inventory.click.Click.Change.Main;
import net.minestom.server.inventory.click.Click.Change.Player;
import org.junit.jupiter.api.Test;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.*;
import static net.minestom.server.utils.inventory.PlayerInventoryUtils.OFF_HAND_SLOT;
public class InventoryOffhandSwapTest {
@ -17,15 +19,15 @@ public class InventoryOffhandSwapTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.OffhandSwap(0), builder -> builder);
assertClick(List.of(), new Click.Info.OffhandSwap(0), List.of());
}
@Test
public void testSwappedItems() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT)).setPlayer(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.of(Material.STONE)),
List.of(new Main(0, magic2(1)), new Player(OFF_HAND_SLOT, magic(1))),
new Click.Info.OffhandSwap(0),
builder -> builder.set(0, ItemStack.of(Material.STONE)).setPlayer(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.of(Material.DIRT))
List.of(new Main(0, magic(1)), new Player(OFF_HAND_SLOT, magic2(1)))
);
}

View File

@ -2,11 +2,13 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.inventory.click.Click.Change.Cursor;
import net.minestom.server.inventory.click.Click.Change.Main;
import org.junit.jupiter.api.Test;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.*;
public class InventoryRightClickTest {
@ -16,51 +18,51 @@ public class InventoryRightClickTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.Right(0), builder -> builder);
assertClick(List.of(), new Click.Info.Right(0), List.of());
}
@Test
public void testAddOne() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)).cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(0, magic(32)), new Cursor(magic(32))),
new Click.Info.Right(0),
builder -> builder.set(0, ItemStack.of(Material.STONE, 33)).cursor(ItemStack.of(Material.STONE, 31))
List.of(new Main(0, magic(33)), new Cursor(magic(31)))
);
}
@Test
public void testClickedStackFull() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 64)).cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Main(0, magic(64)), new Cursor(magic(32))),
new Click.Info.Right(0),
builder -> builder
List.of()
);
}
@Test
public void testTakeHalf() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)),
List.of(new Main(0, magic(32))),
new Click.Info.Right(0),
builder -> builder.set(0, ItemStack.of(Material.STONE, 16)).cursor(ItemStack.of(Material.STONE, 16))
List.of(new Main(0, magic(16)), new Cursor(magic(16)))
);
}
@Test
public void testLeaveOne() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.STONE, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.Right(0),
builder -> builder.set(0, ItemStack.of(Material.STONE, 1)).cursor(ItemStack.of(Material.STONE, 31))
List.of(new Main(0, magic(1)), new Cursor(magic(31)))
);
}
@Test
public void testSwitchItems() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.STONE)).cursor(ItemStack.of(Material.DIRT)),
List.of(new Main(0, magic(1)), new Cursor(magic2(1))),
new Click.Info.Right(0),
builder -> builder.set(0, ItemStack.of(Material.DIRT)).cursor(ItemStack.of(Material.STONE))
List.of(new Main(0, magic2(1)), new Cursor(magic(1)))
);
}

View File

@ -3,11 +3,14 @@ package net.minestom.server.inventory.click.type;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.*;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.assertClick;
import static net.minestom.server.inventory.click.ClickUtils.magic;
public class InventoryRightDragTest {
@ -17,60 +20,60 @@ public class InventoryRightDragTest {
@Test
public void testNoCursor() {
assertClick(builder -> builder, new Click.Info.RightDrag(IntList.of(0)), builder -> builder);
assertClick(List.of(), new Click.Info.RightDrag(IntList.of(0)), List.of());
}
@Test
public void testDistributeNone() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.RightDrag(IntList.of()),
builder -> builder
List.of()
);
}
@Test
public void testDistributeOne() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Cursor(magic(32))),
new Click.Info.RightDrag(IntList.of(0)),
builder -> builder.set(0, ItemStack.of(Material.DIRT)).cursor(ItemStack.of(Material.DIRT, 31))
List.of(new Main(0, magic(1)), new Cursor(magic(31)))
);
}
@Test
public void testDistributeExactlyEnough() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 2)),
List.of(new Cursor(magic(2))),
new Click.Info.RightDrag(IntList.of(0, 1)),
builder -> builder.set(0, ItemStack.of(Material.DIRT)).set(1, ItemStack.of(Material.DIRT)).cursor(ItemStack.of(Material.AIR))
List.of(new Main(0, magic(1)), new Main(1, magic(1)), new Cursor(ItemStack.AIR))
);
}
@Test
public void testTooManySlots() {
assertClick(
builder -> builder.cursor(ItemStack.of(Material.DIRT, 2)),
List.of(new Cursor(magic(2))),
new Click.Info.RightDrag(IntList.of(0, 1, 2)),
builder -> builder.set(0, ItemStack.of(Material.DIRT)).set(1, ItemStack.of(Material.DIRT)).cursor(ItemStack.of(Material.AIR))
List.of(new Main(0, magic(1)), new Main(1, magic(1)), new Cursor(ItemStack.AIR))
);
}
@Test
public void testDistributeOverExisting() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT, 16)).cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Main(0, magic(16)), new Cursor(magic(32))),
new Click.Info.RightDrag(IntList.of(0)),
builder -> builder.set(0, ItemStack.of(Material.DIRT, 17)).cursor(ItemStack.of(Material.DIRT, 31))
List.of(new Main(0, magic(17)), new Cursor(magic(31)))
);
}
@Test
public void testDistributeOverFull() {
assertClick(
builder -> builder.set(0, ItemStack.of(Material.DIRT, 64)).cursor(ItemStack.of(Material.DIRT, 32)),
List.of(new Main(0, magic(64)), new Cursor(magic(32))),
new Click.Info.RightDrag(IntList.of(0)),
builder -> builder
List.of()
);
}

View File

@ -2,11 +2,14 @@ package net.minestom.server.inventory.click.type;
import net.minestom.server.MinecraftServer;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.Click.Change.*;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import org.junit.jupiter.api.Test;
import java.util.List;
import static net.minestom.server.inventory.click.ClickUtils.*;
public class InventoryShiftClickTest {
@ -17,132 +20,133 @@ public class InventoryShiftClickTest {
@Test
public void testNoChanges() {
assertClick(builder -> builder, new Click.Info.LeftShift(0), builder -> builder);
assertClick(builder -> builder, new Click.Info.RightShift(0), builder -> builder);
assertClick(List.of(), new Click.Info.LeftShift(0), List.of());
assertClick(List.of(), new Click.Info.RightShift(0), List.of());
}
@Test
public void testSimpleTransfer() {
assertClick(
builder -> builder.setPlayer(9, ItemStack.of(Material.STONE, 32)),
List.of(new Player(9, magic(32))),
new Click.Info.LeftShift(SIZE),
builder -> builder.set(0, ItemStack.of(Material.STONE, 32)).setPlayer(9, ItemStack.AIR)
List.of(new Main(0, magic(32)), new Player(9, ItemStack.AIR))
);
}
@Test
public void testSeparatedTransfer() {
assertClick(
builder -> builder
.setPlayer(9, ItemStack.of(Material.STONE, 64))
.set(0, ItemStack.of(Material.STONE, 32))
.set(1, ItemStack.of(Material.STONE, 32))
,
List.of(
new Player(9, magic(64)),
new Main(0, magic(32)),
new Main(1, magic(32))
),
new Click.Info.LeftShift(SIZE),
builder -> builder
.setPlayer(9, ItemStack.AIR)
.set(0, ItemStack.of(Material.STONE, 64))
.set(1, ItemStack.of(Material.STONE, 64))
List.of(
new Player(9, ItemStack.AIR),
new Main(0, magic(64)),
new Main(1, magic(64))
)
);
}
@Test
public void testSeparatedAndNewTransfer() {
assertClick(
builder -> builder
.setPlayer(9, ItemStack.of(Material.STONE, 64))
.set(0, ItemStack.of(Material.STONE, 32)),
List.of(
new Player(9, magic(64)),
new Main(0, magic(32))
),
new Click.Info.LeftShift(SIZE),
builder -> builder
.setPlayer(9, ItemStack.AIR)
.set(0, ItemStack.of(Material.STONE, 64))
.set(1, ItemStack.of(Material.STONE, 32))
List.of(
new Player(9, ItemStack.AIR),
new Main(0, magic(64)),
new Main(1, magic(32))
)
);
}
@Test
public void testPartialTransfer() {
assertClick(
builder -> builder
.setPlayer(9, ItemStack.of(Material.STONE, 64))
.set(0, ItemStack.of(Material.STONE, 32))
.set(1, ItemStack.of(Material.DIRT))
.set(2, ItemStack.of(Material.DIRT))
.set(3, ItemStack.of(Material.DIRT))
.set(4, ItemStack.of(Material.DIRT)),
List.of(
new Player(9, magic(64)),
new Main(0, magic(32)),
new Main(1, magic2(1)),
new Main(2, magic2(1)),
new Main(3, magic2(1)),
new Main(4, magic2(1))
),
new Click.Info.LeftShift(SIZE),
builder -> builder
.setPlayer(9, ItemStack.of(Material.STONE, 32))
.set(0, ItemStack.of(Material.STONE, 64))
List.of(new Player(9, magic(32)), new Main(0, magic(64)))
);
}
@Test
public void testCannotTransfer() {
assertClick(
builder -> builder
.setPlayer(9, ItemStack.of(Material.STONE, 64))
.set(0, ItemStack.of(Material.STONE, 64))
.set(1, ItemStack.of(Material.DIRT))
.set(2, ItemStack.of(Material.DIRT))
.set(3, ItemStack.of(Material.DIRT))
.set(4, ItemStack.of(Material.DIRT)),
List.of(
new Player(9, magic(64)),
new Main(0, magic(64)),
new Main(1, magic2(1)),
new Main(2, magic2(1)),
new Main(3, magic2(1)),
new Main(4, magic2(1))
),
new Click.Info.LeftShift(SIZE), // Equivalent to player slot 9
builder -> builder
List.of()
);
assertClick(
builder -> builder
.setPlayer(9, ItemStack.of(Material.STONE, 64))
.set(0, ItemStack.of(Material.DIRT))
.set(1, ItemStack.of(Material.DIRT))
.set(2, ItemStack.of(Material.DIRT))
.set(3, ItemStack.of(Material.DIRT))
.set(4, ItemStack.of(Material.DIRT)),
List.of(
new Player(9, magic(64)),
new Main(0, magic2(1)),
new Main(1, magic2(1)),
new Main(2, magic2(1)),
new Main(3, magic2(1)),
new Main(4, magic2(1))
),
new Click.Info.LeftShift(SIZE), // Equivalent to player slot 9
builder -> builder
List.of()
);
}
@Test
public void testPlayerInteraction() {
assertPlayerClick(
builder -> builder.set(9, ItemStack.of(Material.STONE, 32)),
List.of(new Main(9, magic(32))),
new Click.Info.LeftShift(9),
builder -> builder.set(9, ItemStack.AIR).set(0, ItemStack.of(Material.STONE, 32))
List.of(new Main(9, ItemStack.AIR), new Main(0, magic(32)))
);
assertPlayerClick(
builder -> builder.set(8, ItemStack.of(Material.STONE, 32)),
List.of(new Main(8, magic(32))),
new Click.Info.LeftShift(8),
builder -> builder.set(8, ItemStack.AIR).set(9, ItemStack.of(Material.STONE, 32))
List.of(new Main(8, ItemStack.AIR), new Main(9, magic(32)))
);
assertPlayerClick(
builder -> builder.set(9, ItemStack.of(Material.IRON_CHESTPLATE)),
List.of(new Main(9, ItemStack.of(Material.IRON_CHESTPLATE))),
new Click.Info.LeftShift(9),
builder -> builder.set(9, ItemStack.AIR).set(PlayerInventoryUtils.CHESTPLATE_SLOT, ItemStack.of(Material.IRON_CHESTPLATE))
List.of(new Main(9, ItemStack.AIR), new Main(PlayerInventoryUtils.CHESTPLATE_SLOT, ItemStack.of(Material.IRON_CHESTPLATE)))
);
assertPlayerClick(
builder -> builder.set(PlayerInventoryUtils.CHESTPLATE_SLOT, ItemStack.of(Material.IRON_CHESTPLATE)),
List.of(new Main(PlayerInventoryUtils.CHESTPLATE_SLOT, ItemStack.of(Material.IRON_CHESTPLATE))),
new Click.Info.LeftShift(PlayerInventoryUtils.CHESTPLATE_SLOT),
builder -> builder.set(PlayerInventoryUtils.CHESTPLATE_SLOT, ItemStack.AIR).set(9, ItemStack.of(Material.IRON_CHESTPLATE))
List.of(new Main(PlayerInventoryUtils.CHESTPLATE_SLOT, ItemStack.AIR), new Main(9, ItemStack.of(Material.IRON_CHESTPLATE)))
);
assertPlayerClick(
builder -> builder.set(9, ItemStack.of(Material.SHIELD)),
List.of(new Main(9, ItemStack.of(Material.SHIELD))),
new Click.Info.LeftShift(9),
builder -> builder.set(9, ItemStack.AIR).set(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.of(Material.SHIELD))
List.of(new Main(9, ItemStack.AIR), new Main(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.of(Material.SHIELD)))
);
assertPlayerClick(
builder -> builder.set(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.of(Material.SHIELD)),
List.of(new Main(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.of(Material.SHIELD))),
new Click.Info.LeftShift(PlayerInventoryUtils.OFF_HAND_SLOT),
builder -> builder.set(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.AIR).set(9, ItemStack.of(Material.SHIELD))
List.of(new Main(PlayerInventoryUtils.OFF_HAND_SLOT, ItemStack.AIR), new Main(9, ItemStack.of(Material.SHIELD)))
);
}