This commit is contained in:
Felix Cravic 2020-04-19 14:57:27 +02:00
parent d53cb49648
commit 07a0ba2f54
4 changed files with 152 additions and 149 deletions

View File

@ -2,6 +2,7 @@ package fr.themode.minestom.inventory;
import fr.themode.minestom.Viewable;
import fr.themode.minestom.entity.Player;
import fr.themode.minestom.inventory.click.InventoryClickLoopHandler;
import fr.themode.minestom.inventory.click.InventoryClickProcessor;
import fr.themode.minestom.inventory.click.InventoryClickResult;
import fr.themode.minestom.inventory.condition.InventoryCondition;
@ -372,109 +373,36 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
@Override
public void doubleClick(Player player, int slot) {
PlayerInventory playerInventory = player.getInventory();
boolean isInWindow = isClickInWindow(slot);
ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); // Isn't used in the algorithm
ItemStack cursorItem = getCursorItem(player);
ItemStack cursor = getCursorItem(player);
// Start condition
InventoryCondition inventoryCondition = getInventoryCondition();
if (inventoryCondition != null) {
InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem);
inventoryCondition.accept(player, slot, result);
cursorItem = result.getCursorItem();
clicked = result.getClickedItem();
InventoryClickResult clickResult = clickProcessor.doubleClick(getInventoryCondition(), player, slot, cursor,
// Start by looping through the opened inventory
new InventoryClickLoopHandler(0, itemStacks.length, 1,
i -> i,
index -> itemStacks[index],
(index, itemStack) -> setItemStack(index, itemStack)),
// Looping through player inventory
new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE - 9, 1,
i -> playerInventory.convertToPacketSlot(i),
index -> playerInventory.getItemStack(index, offset),
(index, itemStack) -> playerInventory.setItemStack(index, offset, itemStack)),
// Player hotbar
new InventoryClickLoopHandler(0, 9, 1,
i -> playerInventory.convertToPacketSlot(i),
index -> playerInventory.getItemStack(index, offset),
(index, itemStack) -> {
playerInventory.setItemStack(index, offset, itemStack);
System.out.println("try: " + index);
}));
if (result.isCancel()) {
//System.out.println(clicked.getMaterial() + " + " + cursorItem.getMaterial());
if (isInWindow) {
setItemStack(slot, clicked);
setCursorPlayerItem(player, cursorItem);
} else {
playerInventory.setItemStack(slot, offset, clicked);
setCursorPlayerItem(player, cursorItem);
}
// Refresh client window
player.getPlayerConnection().sendPacket(getWindowItemsPacket());
return;
}
}
// End condition
if (cursorItem.isAir())
if (clickResult == null)
return;
int amount = cursorItem.getAmount();
if (clickResult.doRefresh())
update();
StackingRule cursorRule = cursorItem.getStackingRule();
int maxSize = cursorRule.getMaxSize();
if (amount == maxSize)
return;
// Start by looping through the opened inventory
for (int i = 0; i < itemStacks.length; i++) {
if (i == slot)
continue;
if (amount == maxSize)
break;
ItemStack item = itemStacks[i];
if (cursorRule.canBeStacked(cursorItem, item)) {
int totalAmount = amount + item.getAmount();
if (!cursorRule.canApply(cursorItem, totalAmount)) {
cursorItem = cursorRule.apply(cursorItem, maxSize);
item = cursorRule.apply(item, totalAmount - maxSize);
setItemStack(i, item);
} else {
cursorItem = cursorRule.apply(cursorItem, totalAmount);
setItemStack(i, ItemStack.AIR_ITEM);
}
amount = cursorItem.getAmount();
}
}
// Looping through player inventory
for (int i = 9; i < PlayerInventory.INVENTORY_SIZE - 9; i++) { // Inventory
if (playerInventory.convertToPacketSlot(i) == slot)
continue;
if (amount == maxSize)
break;
ItemStack item = playerInventory.getItemStack(i);
if (cursorRule.canBeStacked(cursorItem, item)) {
int totalAmount = amount + item.getAmount();
if (!cursorRule.canApply(cursorItem, totalAmount)) {
cursorItem = cursorRule.apply(cursorItem, maxSize);
item = cursorRule.apply(item, totalAmount - maxSize);
playerInventory.setItemStack(i, offset, item);
} else {
cursorItem = cursorRule.apply(cursorItem, totalAmount);
playerInventory.setItemStack(i, offset, ItemStack.AIR_ITEM);
}
amount = cursorItem.getAmount();
}
}
for (int i = 0; i < 9; i++) { // Hotbar
if (playerInventory.convertToPacketSlot(i) == slot)
continue;
if (amount == maxSize)
break;
ItemStack item = playerInventory.getItemStack(i);
if (cursorRule.canBeStacked(cursorItem, item)) {
int totalAmount = amount + item.getAmount();
if (!cursorRule.canApply(cursorItem, totalAmount)) {
cursorItem = cursorRule.apply(cursorItem, maxSize);
item = cursorRule.apply(item, totalAmount - maxSize);
playerInventory.setItemStack(i, offset, item);
} else {
cursorItem = cursorRule.apply(cursorItem, totalAmount);
playerInventory.setItemStack(i, offset, ItemStack.AIR_ITEM);
}
amount = cursorItem.getAmount();
}
}
setCursorPlayerItem(player, cursorItem);
setCursorPlayerItem(player, clickResult.getCursor());
playerInventory.update();
}
}

View File

@ -2,6 +2,7 @@ package fr.themode.minestom.inventory;
import fr.themode.minestom.entity.Player;
import fr.themode.minestom.event.ArmorEquipEvent;
import fr.themode.minestom.inventory.click.InventoryClickLoopHandler;
import fr.themode.minestom.inventory.click.InventoryClickProcessor;
import fr.themode.minestom.inventory.click.InventoryClickResult;
import fr.themode.minestom.inventory.condition.InventoryCondition;
@ -422,66 +423,28 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
if (clickResult == null)
return;
if (clickResult.doRefresh())
update();
setCursorItem(clickResult.getCursor());
}
@Override
public void doubleClick(Player player, int slot) {
ItemStack cursorItem = getCursorItem();
ItemStack clicked = getItemStack(slot, OFFSET);
ItemStack cursor = getCursorItem();
// Start condition
InventoryCondition inventoryCondition = getInventoryCondition();
if (inventoryCondition != null) {
InventoryConditionResult result = new InventoryConditionResult(clicked, cursorItem);
inventoryCondition.accept(player, slot, result);
InventoryClickResult clickResult = clickProcessor.doubleClick(getInventoryCondition(), player, slot, cursor,
new InventoryClickLoopHandler(0, items.length, 1,
i -> i < 9 ? i + 9 : i - 9,
index -> items[index],
(index, itemStack) -> setItemStack(index, itemStack)));
cursorItem = result.getCursorItem();
clicked = result.getClickedItem();
if (result.isCancel()) {
setItemStack(slot, OFFSET, clicked);
setCursorItem(cursorItem);
// Refresh client slot
sendSlotRefresh((short) slot, clicked);
return;
}
}
// End condition
if (cursorItem.isAir())
if (clickResult == null)
return;
StackingRule cursorRule = cursorItem.getStackingRule();
int amount = cursorItem.getAmount();
if (clickResult.doRefresh())
update();
if (!cursorRule.canApply(cursorItem, amount + 1))
return;
for (int i = 0; i < items.length; i++) {
int index = i < 9 ? i + 9 : i - 9;
if (index == slot)
continue;
ItemStack item = items[index];
StackingRule itemRule = item.getStackingRule();
if (!cursorRule.canApply(cursorItem, amount + 1))
break;
if (cursorRule.canBeStacked(cursorItem, item)) {
int totalAmount = amount + item.getAmount();
if (!cursorRule.canApply(cursorItem, totalAmount)) {
cursorItem = cursorRule.apply(cursorItem, cursorRule.getMaxSize());
item = itemRule.apply(item, totalAmount - itemRule.getMaxSize());
setItemStack(index, item);
} else {
cursorItem = cursorRule.apply(cursorItem, totalAmount);
item = itemRule.apply(item, 0);
setItemStack(index, item);
}
amount = cursorItem.getAmount();
}
}
setCursorItem(cursorItem);
setCursorItem(clickResult.getCursor());
}
}

View File

@ -0,0 +1,52 @@
package fr.themode.minestom.inventory.click;
import fr.themode.minestom.item.ItemStack;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class InventoryClickLoopHandler {
private int start;
private int end;
private int step;
private Function<Integer, Integer> indexModifier;
private Function<Integer, ItemStack> itemGetter;
private BiConsumer<Integer, ItemStack> itemSetter;
public InventoryClickLoopHandler(int start, int end, int step,
Function<Integer, Integer> indexModifier,
Function<Integer, ItemStack> itemGetter,
BiConsumer<Integer, ItemStack> itemSetter) {
this.start = start;
this.end = end;
this.step = step;
this.indexModifier = indexModifier;
this.itemGetter = itemGetter;
this.itemSetter = itemSetter;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public int getStep() {
return step;
}
public Function<Integer, Integer> getIndexModifier() {
return indexModifier;
}
public Function<Integer, ItemStack> getItemGetter() {
return itemGetter;
}
public BiConsumer<Integer, ItemStack> getItemSetter() {
return itemSetter;
}
}

View File

@ -227,21 +227,25 @@ public class InventoryClickProcessor {
for (Integer s : slots) {
ItemStack draggedItem = cursor.clone();
ItemStack slotItem = itemGetter.apply(s);
clickResult = startCondition(clickResult, inventoryCondition, player, s, slotItem, cursor);
if (clickResult.isCancel())
continue;
if (stackingRule.canBeStacked(draggedItem, slotItem)) {
int amount = slotItem.getAmount() + 1;
if (stackingRule.canApply(slotItem, amount)) {
slotItem = stackingRule.apply(slotItem, amount);
itemSetter.accept(s, slotItem);
cursorAmount -= 1;
}
} else if (slotItem.isAir()) {
draggedItem = stackingRule.apply(draggedItem, 1);
itemSetter.accept(s, draggedItem);
cursorAmount -= 1;
}
}
cursor = stackingRule.apply(cursor, cursorAmount - size);
cursor = stackingRule.apply(cursor, cursorAmount);
clickResult.setCursor(cursor);
rightDraggingMap.remove(player);
@ -266,6 +270,62 @@ public class InventoryClickProcessor {
return clickResult;
}
public InventoryClickResult doubleClick(InventoryCondition inventoryCondition, Player player, int slot,
ItemStack cursor, InventoryClickLoopHandler... loopHandlers) {
InventoryClickResult clickResult = new InventoryClickResult(ItemStack.AIR_ITEM, cursor);
if (clickResult.isCancel()) {
return clickResult;
}
if (cursor.isAir())
return null;
StackingRule cursorRule = cursor.getStackingRule();
int amount = cursorRule.getAmount(cursor);
if (!cursorRule.canApply(cursor, amount + 1))
return null;
for (InventoryClickLoopHandler loopHandler : loopHandlers) {
Function<Integer, Integer> indexModifier = loopHandler.getIndexModifier();
Function<Integer, ItemStack> itemGetter = loopHandler.getItemGetter();
BiConsumer<Integer, ItemStack> itemSetter = loopHandler.getItemSetter();
for (int i = loopHandler.getStart(); i < loopHandler.getEnd(); i += loopHandler.getStep()) {
int index = indexModifier.apply(i);
if (index == slot)
continue;
ItemStack item = itemGetter.apply(index);
StackingRule itemRule = item.getStackingRule();
if (!cursorRule.canApply(cursor, amount + 1))
break;
if (cursorRule.canBeStacked(cursor, item)) {
clickResult = startCondition(clickResult, inventoryCondition, player, index, item, cursor);
if (clickResult.isCancel())
continue;
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);
}
}
}
clickResult.setCursor(cursor);
return clickResult;
}
private InventoryClickResult startCondition(InventoryClickResult clickResult, InventoryCondition inventoryCondition, Player player, int slot, ItemStack clicked, ItemStack cursor) {
if (inventoryCondition != null) {
InventoryConditionResult result = new InventoryConditionResult(clicked, cursor);