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);
+ }
}