diff --git a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/AbstractGui.java b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/AbstractGui.java index 4836d1d..b745093 100644 --- a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/AbstractGui.java +++ b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/AbstractGui.java @@ -28,6 +28,7 @@ import java.util.*; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Predicate; /** * 2023/3/17
@@ -71,10 +72,13 @@ public abstract class AbstractGui<@NonNull G extends AbstractGui<@NonNull G>> im protected boolean cancelMoveHotBarItemToSelf = true; /** * 是否取消玩家用鼠标选中拿起的物品移动至当前gui + * 或者Shift点击将背包物品移动至当前gui * * @see #cancelClickBottom */ protected boolean cancelMoveItemToSelf = true; + protected boolean cancelMoveItemToBottom = true; + protected boolean enablePlayerInventory = false; protected boolean processingClickEvent; /** @@ -357,19 +361,22 @@ protected void setButton(@NonNull Slot slot, @Nullable Button button) { } @Nullable - public GuiButton getButton(int index) { + public GuiButton getButton(int index, Predicate predicate) { return editButtons .stream() + .filter(predicate) .filter(e -> e.getIndex() == index) .findFirst() .orElseGet( () -> buttons .stream() + .filter(predicate) .filter(e -> e.getIndex() == index) .findFirst() .orElseGet( () -> attachedButtons .stream() + .filter(predicate) .filter(e -> e.getIndex() == index) .findFirst() .orElse(null) @@ -377,6 +384,10 @@ public GuiButton getButton(int index) { ); } + public GuiButton getButton(int index) { + return getButton(index, t -> true); + } + public ItemStack getItem(int index) { return cacheInventory.getItem(index); } @@ -394,6 +405,9 @@ public ItemStack[] getItems(Slots slots) { protected G fillItems(@NonNull Inventory inventory, @Nullable boolean all) { if (all) { inventory.clear(); + if (enablePlayerInventory) { + player.getInventory().clear(); + } } Set fillItems = getFillItems(); fillItems.removeAll(editButtons); @@ -428,7 +442,11 @@ protected G fillItems(@NonNull Inventory inventory, @Nullable boolean all) { } private void setItem(@NotNull Inventory inventory, GuiButton guiButton, ItemStack itemStack) { - manager.guiHandler().onSetItem(this, inventory, guiButton, itemStack); + if (!guiButton.isPlayerInventory()) { + manager.guiHandler().onSetItem(this, inventory, guiButton, itemStack); + } else if (enablePlayerInventory) { + manager.guiHandler().onSetItem(this, player.getInventory(), guiButton, itemStack); + } } /** @@ -494,7 +512,7 @@ public void onClick(@NonNull InventoryClickEvent e) { } GuiButton item = manager.guiHandler().queryClickButton(e, this); if (item == null) { - item = getButton(slot); + item = getButton(slot, btn -> !btn.isPlayerInventory()); } if (item != null) { if (!allowClick(player, item, e.getClick(), e.getAction(), e.getSlotType(), slot, e.getHotbarButton(), e)) { @@ -528,6 +546,44 @@ public void onClick(@NonNull InventoryClickEvent e) { if (cancelClickBottom) { e.setCancelled(true); } + if (e.isShiftClick() && cancelMoveItemToSelf) { + e.setCancelled(true); + } + if (enablePlayerInventory) { + int slot = e.getSlot(); + if (slot == -999) { + e.setCancelled(true); + processingClickEvent = false; + return; + } + GuiButton item = manager.guiHandler().queryClickButton(e, this); + if (item == null) { + item = getButton(slot, GuiButton::isPlayerInventory); + } + if (item != null) { + if (!allowClick(player, item, e.getClick(), e.getAction(), e.getSlotType(), slot, e.getHotbarButton(), e)) { + processingClickEvent = false; + return; + } + Result result = item.onClick(this, player, e.getClick(), e.getAction(), e.getSlotType(), slot, e.getHotbarButton(), e); + if (result == null) { + result = Result.CANCEL; + } + if (result.isCancel()) { + e.setCancelled(true); + } + processResult(result, this, player, e.getClick(), e.getAction(), e.getSlotType(), slot, e.getHotbarButton(), e); + } else if (ItemUtil.isAir(e.getCurrentItem())) { + if (guiEmptyItemClick != null) { + if (guiEmptyItemClick.onClickEmptyButton(player, slot, e.getClick(), e.getAction(), e.getSlotType(), e.getHotbarButton(), e)) { + e.setCancelled(true); + } + } + } + if (!ItemUtil.isAir(e.getCursor()) && cancelMoveItemToBottom) { + e.setCancelled(true); + } + } if (guiBottomClick != null) { if (guiBottomClick.onClickBottom(player, view.getBottomInventory(), e.getClick(), e.getAction(), e.getSlotType(), e.getHotbarButton(), e)) { @@ -586,9 +642,14 @@ public void onDarg(@NonNull InventoryDragEvent e) { for (Map.Entry entry : e.getNewItems().entrySet()) { // fake event InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(e.getView(), InventoryType.SlotType.CONTAINER, entry.getKey(), ClickType.LEFT, InventoryAction.UNKNOWN); + ItemStack oldCursor = e.getOldCursor(); + inventoryClickEvent.setCursor(oldCursor); + boolean hasCursor = ItemUtil.isAir(oldCursor); onClick(inventoryClickEvent); if (inventoryClickEvent.isCancelled()) { e.setCancelled(true); + } else if (hasCursor) { + e.setCursor(null); } } } @@ -688,6 +749,13 @@ public G setCancelMoveItemToSelf(boolean cancelMoveItemToSelf) { return self(); } + @CanIgnoreReturnValue + public G setCancelMoveItemToBottom(boolean cancelMoveItemToBottom) { + this.cancelMoveItemToBottom = cancelMoveItemToBottom; + return self(); + } + + @CanIgnoreReturnValue public G setAllowReopen(boolean allowReopen) { this.allowReopen = allowReopen; @@ -711,6 +779,15 @@ public G customResultHandler(CustomResultHandler customResultHandler) { return self(); } + public boolean enablePlayerInventory() { + return enablePlayerInventory; + } + + public G enablePlayerInventory(boolean enablePlayerInventory) { + this.enablePlayerInventory = enablePlayerInventory; + return self(); + } + public GuiManager manager() { return this.manager; } @@ -739,6 +816,8 @@ protected AbstractGui copy(Object newGui) { gui.cancelClickBottom = cancelClickBottom; gui.cancelMoveHotBarItemToSelf = cancelMoveHotBarItemToSelf; gui.cancelMoveItemToSelf = cancelMoveItemToSelf; + gui.cancelMoveItemToBottom = cancelMoveItemToBottom; + gui.enablePlayerInventory = enablePlayerInventory; gui.disableClick = disableClick; gui.tickles = tickles; gui.intervalTick = intervalTick; diff --git a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/GuiButton.java b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/GuiButton.java index 172407f..8f2d817 100644 --- a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/GuiButton.java +++ b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/GuiButton.java @@ -2,6 +2,7 @@ import me.huanmeng.opensource.bukkit.gui.button.Button; import me.huanmeng.opensource.bukkit.gui.enums.Result; +import me.huanmeng.opensource.bukkit.gui.slot.PlayerSlot; import me.huanmeng.opensource.bukkit.gui.slot.Slot; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -27,10 +28,12 @@ public final class GuiButton { @NonNull private Button button; + private boolean isPlayerInventory; public GuiButton(@NonNull Slot slot, @Nullable Button button) { this.slot = slot; this.button = button == null ? Button.empty() : button; + this.isPlayerInventory = this.slot instanceof PlayerSlot; } /** @@ -69,18 +72,19 @@ public void setButton(@NonNull Button button) { this.button = button; } + public boolean isPlayerInventory() { + return isPlayerInventory; + } + @Override public boolean equals(Object o) { - if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - GuiButton guiButton = (GuiButton) o; - - return Objects.equals(slot.getIndex(), guiButton.slot.getIndex()); + return isPlayerInventory == guiButton.isPlayerInventory && Objects.equals(slot, guiButton.slot); } @Override public int hashCode() { - return slot.hashCode(); + return Objects.hash(slot, isPlayerInventory); } } diff --git a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/PlayerSlot.java b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/PlayerSlot.java new file mode 100644 index 0000000..a4b451c --- /dev/null +++ b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/PlayerSlot.java @@ -0,0 +1,49 @@ +package me.huanmeng.opensource.bukkit.gui.slot; + +import me.huanmeng.opensource.bukkit.gui.AbstractGui; +import me.huanmeng.opensource.bukkit.gui.button.Button; +import me.huanmeng.opensource.bukkit.gui.enums.Result; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * 代表玩家背包中的槽位 + * + * @author huanmeng_qwq + */ +public class PlayerSlot implements Slot { + @NonNull + private final Slot slot; + + public PlayerSlot(@NonNull Slot slot) { + this.slot = slot; + } + + @Override + public int getIndex() { + return slot.getIndex(); + } + + @Override + public @NonNull Result onClick(@NonNull AbstractGui gui, @NonNull Button button, @NonNull Player player, @NonNull ClickType click, @NonNull InventoryAction action, InventoryType.@NonNull SlotType slotType, int slot, int hotBarKey, @NonNull InventoryClickEvent e) { + return this.slot.onClick(gui, button, player, click, action, slotType, slot, hotBarKey, e); + } + + @Override + public boolean tryPlace(@NonNull Button button, @NonNull Player player) { + return slot.tryPlace(button, player); + } + + @Override + public PlayerSlot toPlayerSlot() { + return this; + } + + public Slot getSlot() { + return slot; + } +} diff --git a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/PlayerSlots.java b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/PlayerSlots.java new file mode 100644 index 0000000..3b68664 --- /dev/null +++ b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/PlayerSlots.java @@ -0,0 +1,36 @@ +package me.huanmeng.opensource.bukkit.gui.slot; + +import me.huanmeng.opensource.bukkit.gui.AbstractGui; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +/** + * 2024/12/28
+ * Bukkit-Gui-pom
+ * + * @author huanmeng_qwq + */ +public class PlayerSlots implements Slots { + @NonNull + private final Slots slots; + + public PlayerSlots(@NotNull Slots slots) { + this.slots = slots; + } + + @Override + public @NotNull > @NonNull Slot[] slots(@NonNull G gui) { + return Arrays.stream(slots.slots(gui)).map(Slot::toPlayerSlot).toArray(PlayerSlot[]::new); + } + + @Override + public PlayerSlots toPlayerSlots() { + return this; + } + + public Slots getSlots() { + return slots; + } +} diff --git a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slot.java b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slot.java index 0387738..b0a3582 100644 --- a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slot.java +++ b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slot.java @@ -109,9 +109,22 @@ static Slot forward(int i, Slot forwardSlot) { } @Nullable - default ItemStack getShowingItem(@NonNull AbstractGui gui, @NonNull Player player) { + default ItemStack getShowingItem(@NonNull AbstractGui gui, @NonNull Player player) { GuiButton button = gui.getButton(getIndex()); if (button == null) return null; return button.getButton().getShowItem(player); } + + /** + * 玩家背包槽位 + * + * @param index 背包槽位 + */ + static PlayerSlot playerSlot(int index) { + return new PlayerSlot(of(index)); + } + + default PlayerSlot toPlayerSlot() { + return new PlayerSlot(this); + } } diff --git a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slots.java b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slots.java index d370ac9..c6e5398 100644 --- a/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slots.java +++ b/core/src/main/java/me/huanmeng/opensource/bukkit/gui/slot/Slots.java @@ -148,4 +148,8 @@ static ExcludeSlots excludeRange(int min, int max) { static Slots full() { return FULL; } + + default PlayerSlots toPlayerSlots(){ + return new PlayerSlots(this); + } }