166 lines
5.7 KiB
Java
166 lines
5.7 KiB
Java
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 +
|
|
'}';
|
|
}
|
|
}
|
|
}
|