TabooLib/src/main/scala/io/izzel/taboolib/util/item/ItemStacker.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 +
'}';
}
}
}