Merge remote-tracking branch 'origin/master'
This commit is contained in:
		@@ -6,7 +6,7 @@ plugins {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
group = 'me.skymc'
 | 
			
		||||
version = '5.11'
 | 
			
		||||
version = '5.12'
 | 
			
		||||
 | 
			
		||||
sourceCompatibility = 1.8
 | 
			
		||||
targetCompatibility = 1.8
 | 
			
		||||
 
 | 
			
		||||
@@ -56,4 +56,8 @@ public enum Version {
 | 
			
		||||
            return vNull;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int getCurrentVersionInt() {
 | 
			
		||||
        return getCurrentVersion().versionInt;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +1,11 @@
 | 
			
		||||
package io.izzel.taboolib.util;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Maps;
 | 
			
		||||
import io.izzel.taboolib.util.item.ItemBuilder;
 | 
			
		||||
import io.izzel.taboolib.util.item.Items;
 | 
			
		||||
import io.izzel.taboolib.util.lite.Numbers;
 | 
			
		||||
import org.bukkit.inventory.ItemFlag;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.util.NumberConversions;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
@@ -82,6 +86,24 @@ public class TMap {
 | 
			
		||||
        return new String[] {v[0], r.toString().replace("`", "")};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ItemStack parseItem(String source) {
 | 
			
		||||
        TMap map = TMap.parse(source);
 | 
			
		||||
        ItemBuilder builder = new ItemBuilder(Items.asMaterial(map.get("material", "m", "type", "t")))
 | 
			
		||||
                .amount(map.getInt(new String[]{"amount", "a"}, 1))
 | 
			
		||||
                .damage(map.getInt("damage", "data", "d"))
 | 
			
		||||
                .name(map.get("displayname", "display", "name", "n"));
 | 
			
		||||
        if (map.getBoolean("shiny", "glowing", "glow")) {
 | 
			
		||||
            builder.shiny();
 | 
			
		||||
        }
 | 
			
		||||
        if (map.get("lore", "l") != null) {
 | 
			
		||||
            builder.lore(map.get("lore", "l").split("\\n"));
 | 
			
		||||
        }
 | 
			
		||||
        if (map.get("flag", "f") != null) {
 | 
			
		||||
            builder.flags(Arrays.stream(map.get("flag", "f").split("\\n")).map(Items::asItemFlag).filter(Objects::nonNull).toArray(ItemFlag[]::new));
 | 
			
		||||
        }
 | 
			
		||||
        return builder.colored().build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										165
									
								
								src/main/scala/io/izzel/taboolib/util/item/ItemStacker.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/main/scala/io/izzel/taboolib/util/item/ItemStacker.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
package io.izzel.taboolib.util.item;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.ArrayUtil;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.CraftingInventory;
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.PlayerInventory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author 坏黑
 | 
			
		||||
 * @Since 2019-02-07 23:53
 | 
			
		||||
 */
 | 
			
		||||
public class ItemStacker {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 从箱子里移动物品到玩家背包
 | 
			
		||||
     * 如果溢出则丢弃
 | 
			
		||||
     */
 | 
			
		||||
    public static void moveItemFromChest(ItemStack item, Player player) {
 | 
			
		||||
        AddResult result = addItemAndMerge(item, player.getInventory(), new Integer[0]);
 | 
			
		||||
        if (result.countOut > 0) {
 | 
			
		||||
            item.setAmount(result.countOut);
 | 
			
		||||
            if (!addItemAndSplit(item, player.getInventory(), 0, true)) {
 | 
			
		||||
                player.getWorld().dropItem(player.getLocation(), item);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean addItemAndSplit(ItemStack item, Inventory inventory, int start) {
 | 
			
		||||
        return addItemAndSplit(item, inventory, start, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 添加并拆分,但不合并
 | 
			
		||||
     * 返回值为是否添加完成
 | 
			
		||||
     *
 | 
			
		||||
     * desc = 快捷栏逆向添加,用于工作台拟真,会忽略 start 参数
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean addItemAndSplit(ItemStack item, Inventory inventory, int start, boolean desc) {
 | 
			
		||||
        int size = inventory instanceof PlayerInventory || inventory instanceof CraftingInventory ? 36 : inventory.getSize();
 | 
			
		||||
        if (desc) {
 | 
			
		||||
            // 8 ~ 0
 | 
			
		||||
            for (int i = 8; i >= 0; i--) {
 | 
			
		||||
                if (check(item, inventory, i)) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // 9 ~ 36
 | 
			
		||||
        for (int i = desc ? start + 9 : start; i < size; i++) {
 | 
			
		||||
            if (check(item, inventory, i)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean addItemFromChestToPlayer(ItemStack item, Inventory inventory) {
 | 
			
		||||
        for (int i = 8; i >= 0; i--) {
 | 
			
		||||
            if (Items.isNull(inventory.getItem(i))) {
 | 
			
		||||
                if (item.getAmount() > item.getType().getMaxStackSize()) {
 | 
			
		||||
                    ItemStack itemClone = item.clone();
 | 
			
		||||
                    itemClone.setAmount(item.getType().getMaxStackSize());
 | 
			
		||||
                    inventory.setItem(i, itemClone);
 | 
			
		||||
                    item.setAmount(item.getAmount() - item.getType().getMaxStackSize());
 | 
			
		||||
                } else {
 | 
			
		||||
                    ItemStack itemClone = item.clone();
 | 
			
		||||
                    itemClone.setAmount(item.getAmount());
 | 
			
		||||
                    inventory.setItem(i, itemClone);
 | 
			
		||||
                    item.setAmount(0);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 35; i >= 9; i--) {
 | 
			
		||||
            if (Items.isNull(inventory.getItem(i))) {
 | 
			
		||||
                if (item.getAmount() > item.getType().getMaxStackSize()) {
 | 
			
		||||
                    ItemStack itemClone = item.clone();
 | 
			
		||||
                    itemClone.setAmount(item.getType().getMaxStackSize());
 | 
			
		||||
                    inventory.setItem(i, itemClone);
 | 
			
		||||
                    item.setAmount(item.getAmount() - item.getType().getMaxStackSize());
 | 
			
		||||
                } else {
 | 
			
		||||
                    ItemStack itemClone = item.clone();
 | 
			
		||||
                    itemClone.setAmount(item.getAmount());
 | 
			
		||||
                    inventory.setItem(i, itemClone);
 | 
			
		||||
                    item.setAmount(0);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 合并物品,不新增
 | 
			
		||||
     */
 | 
			
		||||
    public static AddResult addItemAndMerge(ItemStack item, Inventory inventory, Integer[] ignore) {
 | 
			
		||||
        boolean changed = false;
 | 
			
		||||
        int count = item.getAmount();
 | 
			
		||||
        int size = inventory instanceof PlayerInventory || inventory instanceof CraftingInventory ? 36 : inventory.getSize();
 | 
			
		||||
        for (int i = 0; i < size; i++) {
 | 
			
		||||
            if (ArrayUtil.contains(ignore, i)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            ItemStack inventoryItem = inventory.getItem(i);
 | 
			
		||||
            if (!item.isSimilar(inventoryItem)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            while (count > 0 && inventoryItem.getAmount() < item.getType().getMaxStackSize()) {
 | 
			
		||||
                changed = true;
 | 
			
		||||
                inventoryItem.setAmount(inventoryItem.getAmount() + 1);
 | 
			
		||||
                count--;
 | 
			
		||||
            }
 | 
			
		||||
            if (count == 0) {
 | 
			
		||||
                return new AddResult(count, changed);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return new AddResult(count, changed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean check(ItemStack item, Inventory inventory, int i) {
 | 
			
		||||
        if (Items.isNull(inventory.getItem(i))) {
 | 
			
		||||
            // 如果物品数量过多
 | 
			
		||||
            if (item.getAmount() > item.getType().getMaxStackSize()) {
 | 
			
		||||
                ItemStack itemClone = item.clone();
 | 
			
		||||
                itemClone.setAmount(item.getType().getMaxStackSize());
 | 
			
		||||
                inventory.setItem(i, itemClone);
 | 
			
		||||
                item.setAmount(item.getAmount() - item.getType().getMaxStackSize());
 | 
			
		||||
            } else {
 | 
			
		||||
                inventory.setItem(i, item.clone());
 | 
			
		||||
                item.setAmount(0);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class AddResult {
 | 
			
		||||
 | 
			
		||||
        private int countOut;
 | 
			
		||||
        private boolean changed;
 | 
			
		||||
 | 
			
		||||
        public AddResult(int countOut, boolean changed) {
 | 
			
		||||
            this.countOut = countOut;
 | 
			
		||||
            this.changed = changed;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int getCountOut() {
 | 
			
		||||
            return countOut;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public boolean isChanged() {
 | 
			
		||||
            return changed;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String toString() {
 | 
			
		||||
            return "AddResult{" +
 | 
			
		||||
                    "countOut=" + countOut +
 | 
			
		||||
                    ", changed=" + changed +
 | 
			
		||||
                    '}';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
package io.izzel.taboolib.util.item.inventory;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author 坏黑
 | 
			
		||||
 * @Since 2019-05-21 18:14
 | 
			
		||||
 */
 | 
			
		||||
public interface BuildTask {
 | 
			
		||||
 | 
			
		||||
    void run(Inventory event);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -7,7 +7,9 @@ import org.bukkit.event.Cancellable;
 | 
			
		||||
import org.bukkit.event.Event;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryDragEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryInteractEvent;
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -28,6 +30,10 @@ public class ClickEvent {
 | 
			
		||||
        this.slot = slot;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<ItemStack> getAffectItems() {
 | 
			
		||||
        return clickType == ClickType.CLICK ? Servers.getAffectItemInClickEvent((InventoryClickEvent) event) : Lists.newArrayList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public InventoryClickEvent castClick() {
 | 
			
		||||
        return (InventoryClickEvent) event;
 | 
			
		||||
    }
 | 
			
		||||
@@ -52,8 +58,8 @@ public class ClickEvent {
 | 
			
		||||
        return (Player) ((InventoryInteractEvent) event).getWhoClicked();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<ItemStack> getAffectItems() {
 | 
			
		||||
        return clickType == ClickType.CLICK ? Servers.getAffectItemInClickEvent((InventoryClickEvent) event) : Lists.newArrayList();
 | 
			
		||||
    public Inventory getInventory() {
 | 
			
		||||
        return ((InventoryEvent) event).getInventory();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setCancelled(boolean c) {
 | 
			
		||||
@@ -63,4 +69,14 @@ public class ClickEvent {
 | 
			
		||||
    public boolean isCancelled() {
 | 
			
		||||
        return ((Cancellable) event).isCancelled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ItemStack getCurrentItem() {
 | 
			
		||||
        return clickType == ClickType.CLICK ? castClick().getCurrentItem() : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setCurrentItem(ItemStack item) {
 | 
			
		||||
        if (clickType == ClickType.CLICK) {
 | 
			
		||||
            castClick().setCurrentItem(item);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryCloseEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryDragEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryOpenEvent;
 | 
			
		||||
import org.bukkit.event.player.PlayerDropItemEvent;
 | 
			
		||||
import org.bukkit.event.player.PlayerItemHeldEvent;
 | 
			
		||||
import org.bukkit.event.server.PluginDisableEvent;
 | 
			
		||||
@@ -32,6 +33,14 @@ class ClickListener implements Listener {
 | 
			
		||||
        Bukkit.getOnlinePlayers().stream().filter(player -> player.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder && e.getPlugin().equals(((MenuHolder) player.getOpenInventory().getTopInventory().getHolder()).getBuilder().getPlugin())).forEach(HumanEntity::closeInventory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void e(InventoryOpenEvent e) {
 | 
			
		||||
        if (e.getInventory().getHolder() instanceof MenuHolder) {
 | 
			
		||||
            Bukkit.getScheduler().runTask(TabooLib.getPlugin(), () -> ((MenuHolder) e.getInventory().getHolder()).getBuilder().getBuildTask().run(e.getInventory()));
 | 
			
		||||
            Bukkit.getScheduler().runTaskAsynchronously(TabooLib.getPlugin(), () -> ((MenuHolder) e.getInventory().getHolder()).getBuilder().getBuildTaskAsync().run(e.getInventory()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void e(InventoryClickEvent e) {
 | 
			
		||||
        if (e.getInventory().getHolder() instanceof MenuHolder) {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import io.izzel.taboolib.TabooLib;
 | 
			
		||||
import io.izzel.taboolib.util.Ref;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
@@ -24,6 +25,8 @@ public class MenuBuilder {
 | 
			
		||||
    private char[][] items = new char[0][0];
 | 
			
		||||
    private ClickTask clickTask;
 | 
			
		||||
    private CloseTask closeTask;
 | 
			
		||||
    private BuildTask buildTask;
 | 
			
		||||
    private BuildTask buildTaskAsync;
 | 
			
		||||
    private boolean lockHand;
 | 
			
		||||
 | 
			
		||||
    public MenuBuilder(Plugin plugin) {
 | 
			
		||||
@@ -43,6 +46,11 @@ public class MenuBuilder {
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MenuBuilder lockHand(boolean value) {
 | 
			
		||||
        this.lockHand = value;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MenuBuilder event(ClickTask clickTask) {
 | 
			
		||||
        this.clickTask = clickTask;
 | 
			
		||||
        return this;
 | 
			
		||||
@@ -53,6 +61,16 @@ public class MenuBuilder {
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MenuBuilder build(BuildTask buildTask) {
 | 
			
		||||
        this.buildTask = buildTask;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MenuBuilder buildAsync(BuildTask buildTask) {
 | 
			
		||||
        this.buildTaskAsync = buildTask;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MenuBuilder title(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        return this;
 | 
			
		||||
@@ -76,6 +94,10 @@ public class MenuBuilder {
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void open(Player player) {
 | 
			
		||||
        player.openInventory(build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Inventory build() {
 | 
			
		||||
        Inventory inventory = Bukkit.createInventory(new MenuHolder(this), rows, String.valueOf(title));
 | 
			
		||||
        for (int i = 0; i < items.length && i < rows; i++) {
 | 
			
		||||
@@ -133,6 +155,14 @@ public class MenuBuilder {
 | 
			
		||||
        return closeTask;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BuildTask getBuildTask() {
 | 
			
		||||
        return buildTask;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BuildTask getBuildTaskAsync() {
 | 
			
		||||
        return buildTaskAsync;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isLockHand() {
 | 
			
		||||
        return lockHand;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
package io.izzel.taboolib.util.item.inventory.stored;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.ClickEvent;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
public abstract class Action {
 | 
			
		||||
 | 
			
		||||
    public abstract ItemStack getCurrent(ClickEvent e);
 | 
			
		||||
 | 
			
		||||
    public abstract void setCurrent(ClickEvent e, ItemStack item);
 | 
			
		||||
 | 
			
		||||
    public abstract int getCurrentSlot(ClickEvent e);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
package io.izzel.taboolib.util.item.inventory.stored;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.ClickEvent;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-12-03 19:17
 | 
			
		||||
 */
 | 
			
		||||
public class ActionClick extends Action{
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ItemStack getCurrent(ClickEvent e) {
 | 
			
		||||
        return e.getClicker().getItemOnCursor();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setCurrent(ClickEvent e, ItemStack item) {
 | 
			
		||||
        e.getClicker().setItemOnCursor(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getCurrentSlot(ClickEvent e) {
 | 
			
		||||
        return e.getRawSlot();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
package io.izzel.taboolib.util.item.inventory.stored;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.ClickEvent;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-12-03 19:20
 | 
			
		||||
 */
 | 
			
		||||
public class ActionKeyboard extends Action {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ItemStack getCurrent(ClickEvent e) {
 | 
			
		||||
        return e.getClicker().getInventory().getItem(e.castClick().getHotbarButton());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setCurrent(ClickEvent e, ItemStack item) {
 | 
			
		||||
        e.getClicker().getInventory().setItem(e.castClick().getHotbarButton(), item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getCurrentSlot(ClickEvent e) {
 | 
			
		||||
        return e.getRawSlot();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
package io.izzel.taboolib.util.item.inventory.stored;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.item.ItemStacker;
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.ClickEvent;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-12-03 19:20
 | 
			
		||||
 */
 | 
			
		||||
public class ActionQuickTake extends Action {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ItemStack getCurrent(ClickEvent e) {
 | 
			
		||||
        return e.getClicker().getItemOnCursor();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setCurrent(ClickEvent e, ItemStack item) {
 | 
			
		||||
        if (item != null) {
 | 
			
		||||
            ItemStacker.moveItemFromChest(item, e.getClicker());
 | 
			
		||||
        }
 | 
			
		||||
        e.getClicker().setItemOnCursor(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getCurrentSlot(ClickEvent e) {
 | 
			
		||||
        return e.getRawSlot();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,164 @@
 | 
			
		||||
package io.izzel.taboolib.util.item.inventory.stored;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.item.Items;
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.ClickEvent;
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.ClickType;
 | 
			
		||||
import io.izzel.taboolib.util.item.inventory.MenuBuilder;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryCloseEvent;
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-12-03 13:24
 | 
			
		||||
 */
 | 
			
		||||
public abstract class MenuStored {
 | 
			
		||||
 | 
			
		||||
    protected Player player;
 | 
			
		||||
 | 
			
		||||
    public MenuStored(Player player) {
 | 
			
		||||
        this.player = player;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void open() {
 | 
			
		||||
        MenuBuilder.builder()
 | 
			
		||||
                .lockHand(isLockHand())
 | 
			
		||||
                .title(getTitle())
 | 
			
		||||
                .rows(getRows())
 | 
			
		||||
                .event(this::onClick)
 | 
			
		||||
                .close(this::onClose)
 | 
			
		||||
                .build(this::refresh)
 | 
			
		||||
                .buildAsync(this::refreshAsync)
 | 
			
		||||
                .open(player);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isLockHand() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return player.getName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getRows() {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onClick(ClickEvent e) {
 | 
			
		||||
        if (e.getClickType() == ClickType.CLICK) {
 | 
			
		||||
            // 自动装填
 | 
			
		||||
            if (e.castClick().getClick().isShiftClick() && e.getRawSlot() >= e.getInventory().getSize() && Items.nonNull(e.getCurrentItem())) {
 | 
			
		||||
                e.setCancelled(true);
 | 
			
		||||
                // 获取有效位置
 | 
			
		||||
                int validSlot = getIntoSlot(e.getInventory(), e.getCurrentItem());
 | 
			
		||||
                if (validSlot >= 0) {
 | 
			
		||||
                    // 设置物品
 | 
			
		||||
                    intoItem(e.getInventory(), e.getCurrentItem(), validSlot);
 | 
			
		||||
                    // 移除物品
 | 
			
		||||
                    e.setCurrentItem(null);
 | 
			
		||||
                    onClicked();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // 手动装填
 | 
			
		||||
            else {
 | 
			
		||||
                Action action;
 | 
			
		||||
                if (e.castClick().getClick().isShiftClick() && e.getRawSlot() >= 0 && e.getRawSlot() < e.getInventory().getSize()) {
 | 
			
		||||
                    action = new ActionQuickTake();
 | 
			
		||||
                } else if (e.castClick().getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY) {
 | 
			
		||||
                    action = new ActionKeyboard();
 | 
			
		||||
                } else {
 | 
			
		||||
                    action = new ActionClick();
 | 
			
		||||
                }
 | 
			
		||||
                // 点击有效位置
 | 
			
		||||
                if (isIntoSlot(e.getInventory(), action.getCurrent(e), action.getCurrentSlot(e))) {
 | 
			
		||||
                    e.setCancelled(true);
 | 
			
		||||
                    // 提取动作
 | 
			
		||||
                    if (Items.isNull(action.getCurrent(e)) && existsItem(e.getInventory(), action.getCurrentSlot(e))) {
 | 
			
		||||
                        // 提取物品
 | 
			
		||||
                        action.setCurrent(e, getItem(e.getInventory(), action.getCurrentSlot(e)));
 | 
			
		||||
                        // 删除物品
 | 
			
		||||
                        intoItem(e.getInventory(), null, action.getCurrentSlot(e));
 | 
			
		||||
                        onClicked();
 | 
			
		||||
                    }
 | 
			
		||||
                    // 合法的位置
 | 
			
		||||
                    else if (shouldIntoSlot(e.getInventory(), action.getCurrent(e), action.getCurrentSlot(e))) {
 | 
			
		||||
                        ItemStack current = action.getCurrent(e);
 | 
			
		||||
                        // 提取物品
 | 
			
		||||
                        action.setCurrent(e, getItem(e.getInventory(), action.getCurrentSlot(e)));
 | 
			
		||||
                        // 写入物品
 | 
			
		||||
                        intoItem(e.getInventory(), current, action.getCurrentSlot(e));
 | 
			
		||||
                        onClicked();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 当点击动作完成时
 | 
			
		||||
     */
 | 
			
		||||
    public void onClicked() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 当界面关闭时
 | 
			
		||||
     */
 | 
			
		||||
    public void onClose(InventoryCloseEvent e) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 当界面刷新时
 | 
			
		||||
     */
 | 
			
		||||
    public void refresh(Inventory inventory) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 当界面刷新时(异步)
 | 
			
		||||
     */
 | 
			
		||||
    public void refreshAsync(Inventory inventory) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 物品是否可以放入该位置
 | 
			
		||||
     */
 | 
			
		||||
    public boolean shouldIntoSlot(Inventory inventory, ItemStack item, int slot) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否为有效的位置
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isIntoSlot(Inventory inventory, ItemStack item, int slot) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取界面中有效的位置
 | 
			
		||||
     * 用于 shift 点击时的自动装填
 | 
			
		||||
     */
 | 
			
		||||
    public int getIntoSlot(Inventory inventory, ItemStack item) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 物品存入界面
 | 
			
		||||
     */
 | 
			
		||||
    public void intoItem(Inventory inventory, ItemStack item, int slot) {
 | 
			
		||||
        inventory.setItem(slot, item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否存在物品
 | 
			
		||||
     */
 | 
			
		||||
    public boolean existsItem(Inventory inventory, int slot) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取物品
 | 
			
		||||
     */
 | 
			
		||||
    public ItemStack getItem(Inventory inventory, int slot) {
 | 
			
		||||
        return inventory.getItem(slot);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
 | 
			
		||||
package io.izzel.taboolib.util.lite;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user