From 0bd3deef9ef6aee5f9556f30222eaf1de0ab3b3f Mon Sep 17 00:00:00 2001 From: fullwall Date: Sun, 31 Jan 2021 23:40:20 +0800 Subject: [PATCH] Bugfixes for inventory GUI --- .../api/gui/CitizensInventoryClickEvent.java | 3 +- .../citizensnpcs/api/gui/InventoryMenu.java | 53 +++++++++++++++++-- .../api/gui/InventoryMenuPage.java | 6 ++- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/citizensnpcs/api/gui/CitizensInventoryClickEvent.java b/src/main/java/net/citizensnpcs/api/gui/CitizensInventoryClickEvent.java index 5d6558e5..f146ed1d 100644 --- a/src/main/java/net/citizensnpcs/api/gui/CitizensInventoryClickEvent.java +++ b/src/main/java/net/citizensnpcs/api/gui/CitizensInventoryClickEvent.java @@ -35,7 +35,8 @@ public ItemStack getCursorNonNull() { } private ItemStack getResult(InventoryClickEvent event) { - ItemStack stack = event.getCurrentItem() == null ? new ItemStack(event.getCursor().getType(), 0) + ItemStack stack = event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR + ? new ItemStack(event.getCursor().getType(), 0) : event.getCurrentItem().clone(); switch (event.getAction()) { case PICKUP_ONE: diff --git a/src/main/java/net/citizensnpcs/api/gui/InventoryMenu.java b/src/main/java/net/citizensnpcs/api/gui/InventoryMenu.java index 1f565536..429960de 100644 --- a/src/main/java/net/citizensnpcs/api/gui/InventoryMenu.java +++ b/src/main/java/net/citizensnpcs/api/gui/InventoryMenu.java @@ -15,6 +15,7 @@ import java.util.WeakHashMap; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.Event.Result; import org.bukkit.event.EventHandler; @@ -26,6 +27,7 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -34,11 +36,11 @@ import net.citizensnpcs.api.util.Colorizer; import net.citizensnpcs.api.util.Messaging; -// TODO: class-based injection? runnables? translations for titles/lore etc. sub-inventory pages +// TODO: class-based injection? sub-inventory pages /** * A container class for Inventory GUIs. Expects {@link #onInventoryClick(InventoryClickEvent)} and * {@link #onInventoryClose(InventoryCloseEvent)} to be called by the user (or registered with the event listener - * system). + * system). Optionally, {@link #run()} can also be called every tick. * * Inventory GUIs are defined as a stack of {@link InventoryMenuPage}s, each of which represents a distinct inventory * that is transitioned between using either code or user clicks using the {@link InventoryMenuTransition} class. Each @@ -56,7 +58,7 @@ * Instances of global/contextual variables can be injected dynamically via {@link InjectContext} which sources * variables from the {@link MenuContext}. */ -public class InventoryMenu implements Listener { +public class InventoryMenu implements Listener, Runnable { private PageContext page; private final Queue stack = Queues.newArrayDeque(); private Collection views = Lists.newArrayList(); @@ -172,8 +174,46 @@ public void onInventoryClick(InventoryClickEvent event) { if (event.getInventory().equals(page.ctx.getInventory()) && event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) { event.setCancelled(true); // TODO: treat this as a move-to-slot click event + if (false && (event.getCursor() == null || event.getCursor().getType() == Material.AIR)) { + int amount = event.getCurrentItem().getAmount(); + ItemStack merging = new ItemStack(event.getCurrentItem().clone()); + ItemStack[] contents = page.ctx.getInventory().getContents(); + for (int i = 0; i < page.ctx.getInventory().getSize(); i++) { + if (contents[i] == null || contents[i].getType() == Material.AIR) { + merging.setAmount(amount); + event.getView().setCursor(merging); + InventoryClickEvent e = new InventoryClickEvent(event.getView(), event.getSlotType(), i, + event.getClick(), InventoryAction.PLACE_ALL); + onInventoryClick(e); + event.getView().setCursor(null); + if (!e.isCancelled() && e.getResult() != Result.DENY) { + page.ctx.getInventory().setItem(i, merging); + event.setCurrentItem(null); + break; + } + } else if (contents[i].getType() == event.getCurrentItem().getType()) { + ItemStack stack = contents[i].clone(); + merging.setAmount(Math.min(amount, stack.getType().getMaxStackSize() - stack.getAmount())); + event.getView().setCursor(merging); + InventoryClickEvent e = new InventoryClickEvent(event.getView(), event.getSlotType(), i, + event.getClick(), amount - merging.getAmount() <= 0 ? InventoryAction.PLACE_ALL + : InventoryAction.PLACE_SOME); + onInventoryClick(e); + event.getView().setCursor(null); + if (!e.isCancelled() && e.getResult() != Result.DENY) { + stack.setAmount(stack.getAmount() + merging.getAmount()); + page.ctx.getInventory().setItem(i, stack); + amount -= merging.getAmount(); + event.getCurrentItem().setAmount(amount); + if (amount <= 0) { + break; + } + } + } + } + } } - if (page == null || !clicked.equals(page.ctx.getInventory())) + if (!clicked.equals(page.ctx.getInventory())) return; switch (event.getAction()) { case COLLECT_TO_CURSOR: @@ -291,6 +331,11 @@ public void present(Player player) { views.add(view); } + @Override + public void run() { + page.page.run(); + } + /** * Transition to another page. Adds the previous page to a stack which will be returned to when the current page is * closed. diff --git a/src/main/java/net/citizensnpcs/api/gui/InventoryMenuPage.java b/src/main/java/net/citizensnpcs/api/gui/InventoryMenuPage.java index f9823b51..dc0bc514 100644 --- a/src/main/java/net/citizensnpcs/api/gui/InventoryMenuPage.java +++ b/src/main/java/net/citizensnpcs/api/gui/InventoryMenuPage.java @@ -10,7 +10,7 @@ * * @see InventoryMenu */ -public abstract class InventoryMenuPage { +public abstract class InventoryMenuPage implements Runnable { public InventoryType getInventoryType() { return null; } @@ -22,4 +22,8 @@ public void onClick(InventoryMenuSlot slot, InventoryClickEvent event) { public void onClose(HumanEntity player) { } + + @Override + public void run() { + } }