WIP shift tests

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2022-06-29 20:36:03 +02:00
parent 7da0aba66e
commit 6c093ff6c8
3 changed files with 170 additions and 11 deletions

View File

@ -250,16 +250,22 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
public boolean shiftClick(@NotNull Player player, int slot) {
final boolean isInWindow = isClickInWindow(slot);
final int clickSlot = isInWindow ? slot : PlayerInventoryUtils.convertSlot(slot, offset);
final AbstractInventory inventory = isInWindow ? this : player.getInventory();
final ItemStack item = getItemStack(clickSlot);
PlayerInventory playerInv = player.getInventory();
if (isInWindow) {
final ItemStack item = getItemStack(clickSlot);
return handleResult(ClickProcessor.shiftToPlayer(playerInv, item),
itemStack -> setItemStack(clickSlot, itemStack), player, playerInv, ClickType.SHIFT_CLICK);
} else {
final ItemStack item = playerInv.getItemStack(clickSlot);
return handleResult(ClickProcessor.shiftToInventory(this, item),
itemStack -> playerInv.setItemStack(clickSlot, itemStack), player, this, ClickType.SHIFT_CLICK);
}
final var tmp = handlePreClick(inventory, player, clickSlot, ClickType.START_SHIFT_CLICK,
getCursorItem(player), inventory.getItemStack(clickSlot));
if (tmp.cancelled()) {
update();
return false;
}
var result = isInWindow ? ClickProcessor.shiftToPlayer(playerInv, item) : ClickProcessor.shiftToInventory(this, item);
var inverseInv = isInWindow ? player.getInventory() : this;
// TODO call pre-click for each changed slot
return handleResult(result,
itemStack -> inventory.setItemStack(clickSlot, itemStack), player, inverseInv, ClickType.SHIFT_CLICK);
}
@Override

View File

@ -14,6 +14,7 @@ import net.minestom.server.network.packet.server.play.WindowItemsPacket;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import static net.minestom.server.utils.inventory.PlayerInventoryUtils.*;
@ -239,8 +240,27 @@ public non-sealed class PlayerInventory extends AbstractInventory implements Equ
public boolean shiftClick(@NotNull Player player, int slot) {
final int convertedSlot = convertPlayerInventorySlot(slot, OFFSET);
final ItemStack shifted = getItemStack(convertedSlot);
return handleResult(ClickProcessor.shiftWithinPlayer(this, convertedSlot, shifted),
itemStack -> setItemStack(convertedSlot, itemStack), ClickType.SHIFT_CLICK);
final var tmp = handlePreClick(this, player, convertedSlot, ClickType.START_SHIFT_CLICK,
getCursorItem(), shifted);
if (tmp.cancelled()) {
update();
return false;
}
var result = ClickProcessor.shiftWithinPlayer(this, convertedSlot, shifted);
AtomicBoolean modified = new AtomicBoolean();
result.changedSlots().forEach((updateSlot, itemStack) -> {
final var tmp2 = handlePreClick(this, player, updateSlot, ClickType.SHIFT_CLICK,
getCursorItem(), itemStack);
if (tmp2.cancelled()) {
modified.setPlain(true);
return;
}
setItemStack(updateSlot, itemStack);
callClickEvent(player, null, updateSlot, ClickType.SHIFT_CLICK, itemStack, getCursorItem());
});
setItemStack(convertedSlot, result.remaining());
if (modified.getPlain()) update();
return true;
}
@Override

View File

@ -0,0 +1,133 @@
package net.minestom.server.inventory.click.integration;
import net.minestom.server.api.Env;
import net.minestom.server.api.EnvTest;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.inventory.InventoryPreClickEvent;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.ClickType;
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.utils.inventory.PlayerInventoryUtils;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@EnvTest
public class ShiftClickIntegrationTest {
@Test
public void shiftSelf(Env env) {
var instance = env.createFlatInstance();
var player = env.createPlayer(instance, new Pos(0, 40, 0));
var inventory = player.getInventory();
var listener = env.listen(InventoryPreClickEvent.class);
// Drag to air
{
inventory.setItemStack(0, ItemStack.of(Material.STONE, 64));
List<InventoryPreClickEvent> events = new ArrayList<>();
listener.followup(events::add);
shift(player, 0);
// start->slot
assertEquals(2, events.size());
{
// Start
var event = events.get(0);
assertNull(event.getInventory());
assertEquals(ClickType.START_SHIFT_CLICK, event.getClickType());
assertEquals(0, event.getSlot());
assertEquals(ItemStack.AIR, event.getCursorItem());
assertEquals(ItemStack.of(Material.STONE, 64), event.getClickedItem());
}
{
// Slot
var event = events.get(1);
assertNull(event.getInventory());
assertEquals(ClickType.SHIFT_CLICK, event.getClickType());
assertEquals(9, event.getSlot());
assertEquals(ItemStack.AIR, event.getCursorItem());
assertEquals(ItemStack.of(Material.STONE, 64), event.getClickedItem());
}
assertEquals(ItemStack.AIR, inventory.getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(0));
assertEquals(ItemStack.of(Material.STONE, 64), inventory.getItemStack(9));
}
}
@Test
public void shiftExternal(Env env) {
var instance = env.createFlatInstance();
var player = env.createPlayer(instance, new Pos(0, 40, 0));
var inventory = new Inventory(InventoryType.HOPPER, "test");
player.openInventory(inventory);
var listener = env.listen(InventoryPreClickEvent.class);
// Drag to air
{
inventory.setItemStack(0, ItemStack.of(Material.STONE, 64));
List<InventoryPreClickEvent> events = new ArrayList<>();
listener.followup(events::add);
shiftOpenInventory(player, 0);
// start->slot
assertEquals(2, events.size());
{
// Start
var event = events.get(0);
assertEquals(inventory, event.getInventory());
assertEquals(ClickType.START_SHIFT_CLICK, event.getClickType());
assertEquals(0, event.getSlot());
assertEquals(ItemStack.AIR, event.getCursorItem());
assertEquals(ItemStack.of(Material.STONE, 64), event.getClickedItem());
}
{
// Slot
var event = events.get(1);
assertNull(event.getInventory());
assertEquals(ClickType.SHIFT_CLICK, event.getClickType());
assertEquals(9, event.getSlot());
assertEquals(ItemStack.AIR, event.getCursorItem());
assertEquals(ItemStack.of(Material.STONE, 64), event.getClickedItem());
}
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, inventory.getItemStack(0));
assertEquals(ItemStack.of(Material.STONE, 64), player.getInventory().getItemStack(8));
}
}
private void shiftOpenInventory(Player player, int slot) {
_shift(player.getOpenInventory(), true, player, slot);
}
private void shift(Player player, int slot) {
_shift(player.getOpenInventory(), false, player, slot);
}
private void _shift(Inventory openInventory, boolean clickOpenInventory, Player player, int slot) {
final byte windowId = openInventory != null ? openInventory.getWindowId() : 0;
if (clickOpenInventory) {
assert openInventory != null;
// Do not touch slot
} else {
int offset = openInventory != null ? openInventory.getInnerSize() : 0;
slot = PlayerInventoryUtils.convertToPacketSlot(slot);
if (openInventory != null) {
slot = slot - 9 + offset;
}
}
// button 0 = left
// button 1 = right
// They should have identical behavior
player.addPacketToQueue(new ClientClickWindowPacket(windowId, 0, (short) slot, (byte) 0,
ClientClickWindowPacket.ClickType.QUICK_MOVE, List.of(), ItemStack.AIR));
player.interpretPacketQueue();
}
}