mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-24 17:11:58 +01:00
Update
This commit is contained in:
parent
d53cb49648
commit
07a0ba2f54
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user