2023-05-30 11:20:31 +02:00
|
|
|
package com.craftaro.ultimatestacker.stackable.item;
|
|
|
|
|
2023-06-30 22:28:37 +02:00
|
|
|
import com.craftaro.core.compatibility.ServerVersion;
|
2023-05-30 11:20:31 +02:00
|
|
|
import com.craftaro.ultimatestacker.UltimateStacker;
|
2023-11-13 19:52:50 +01:00
|
|
|
import com.craftaro.ultimatestacker.api.events.entity.StackedItemSpawnEvent;
|
2023-05-30 11:20:31 +02:00
|
|
|
import com.craftaro.ultimatestacker.api.stack.item.ItemMergeCallback;
|
|
|
|
import com.craftaro.ultimatestacker.api.stack.item.StackedItem;
|
|
|
|
import com.craftaro.ultimatestacker.api.stack.item.StackedItemManager;
|
|
|
|
import com.craftaro.ultimatestacker.settings.Settings;
|
2023-06-05 16:25:37 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2023-05-30 11:20:31 +02:00
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.World;
|
|
|
|
import org.bukkit.entity.Item;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
|
|
|
|
import java.util.List;
|
2023-06-05 16:25:37 +02:00
|
|
|
import java.util.concurrent.Future;
|
2023-05-30 11:20:31 +02:00
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
|
|
public class StackedItemManagerImpl implements StackedItemManager {
|
|
|
|
|
2023-07-17 12:20:37 +02:00
|
|
|
private final static int MAX_INT = 1500000000;
|
|
|
|
|
2023-05-30 11:20:31 +02:00
|
|
|
@Override
|
2023-07-08 11:23:20 +02:00
|
|
|
public @NotNull StackedItem getStackedItem(Item item) {
|
|
|
|
return new StackedItemImpl(item);
|
2023-05-30 11:20:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public @Nullable StackedItem createStack(ItemStack item, Location location, int amount) {
|
|
|
|
if (item.getType() == Material.AIR) return null;
|
|
|
|
World world = location.getWorld();
|
|
|
|
if (world == null) return null;
|
2023-11-14 23:40:16 +01:00
|
|
|
StackedItemSpawnEvent event = new StackedItemSpawnEvent(null, item, amount);
|
2023-11-13 19:52:50 +01:00
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled()) return null;
|
|
|
|
|
2023-07-08 11:23:20 +02:00
|
|
|
Item dropped = world.dropItem(location, item);
|
|
|
|
if (dropped.getItemStack().getType() == Material.AIR) return null;
|
|
|
|
return new StackedItemImpl(dropped, amount);
|
2023-05-30 11:20:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-11-14 23:40:16 +01:00
|
|
|
public StackedItem createStack(Item item, int amount) {
|
|
|
|
StackedItemSpawnEvent event = new StackedItemSpawnEvent(item, item.getItemStack(), amount);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled()) return null;
|
2023-07-08 11:23:20 +02:00
|
|
|
return new StackedItemImpl(item, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public @NotNull StackedItem updateStack(Item item, int newAmount) {
|
|
|
|
StackedItem stackedItem = getStackedItem(item);
|
|
|
|
stackedItem.setAmount(newAmount);
|
|
|
|
return stackedItem;
|
2023-05-30 11:20:31 +02:00
|
|
|
}
|
|
|
|
|
2023-06-05 16:25:37 +02:00
|
|
|
@Override
|
|
|
|
public @Nullable Future<StackedItem> createStackSync(ItemStack item, Location location, int amount) {
|
|
|
|
return Bukkit.getScheduler().callSyncMethod(UltimateStacker.getInstance(), () -> createStack(item, location, amount));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-07-08 11:23:20 +02:00
|
|
|
public @NotNull Future<StackedItem> createStackSync(Item item, int amount) {
|
2023-06-05 16:25:37 +02:00
|
|
|
return Bukkit.getScheduler().callSyncMethod(UltimateStacker.getInstance(), () -> createStack(item, amount));
|
|
|
|
}
|
|
|
|
|
2023-07-08 11:23:20 +02:00
|
|
|
@Override
|
|
|
|
public @NotNull Future<StackedItem> updateStackSync(Item item, int newAmount) {
|
|
|
|
return Bukkit.getScheduler().callSyncMethod(UltimateStacker.getInstance(), () -> updateStack(item, newAmount));
|
|
|
|
}
|
|
|
|
|
2023-05-30 11:20:31 +02:00
|
|
|
@Override
|
|
|
|
public int getActualItemAmount(Item item) {
|
|
|
|
if (isStackedItem(item)) {
|
|
|
|
return item.getMetadata("US_AMT").get(0).asInt();
|
|
|
|
} else {
|
|
|
|
return item.getItemStack().getAmount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isStackedItem(Item item) {
|
|
|
|
if (item.hasMetadata("US_AMT")) {
|
|
|
|
return item.getItemStack().getAmount() != item.getMetadata("US_AMT").get(0).asInt();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-07-08 11:23:20 +02:00
|
|
|
public @Nullable StackedItem merge(Item from, Item to, boolean ignoreRestrictions) {
|
2023-05-30 11:20:31 +02:00
|
|
|
return merge(from, to, ignoreRestrictions, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-07-08 11:23:20 +02:00
|
|
|
public @Nullable StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback<Item, Item, StackedItem> callback) {
|
2023-05-30 11:20:31 +02:00
|
|
|
|
|
|
|
if (!ignoreRestrictions) {
|
|
|
|
if (!Settings.STACK_ITEMS.getBoolean()) return null;
|
|
|
|
List<String> disabledWorlds = Settings.DISABLED_WORLDS.getStringList();
|
|
|
|
if (disabledWorlds.stream().anyMatch(worldStr -> from.getWorld().getName().equalsIgnoreCase(worldStr))) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int maxItemStackSize = Settings.MAX_STACK_ITEMS.getInt();
|
2023-07-17 12:20:37 +02:00
|
|
|
if (maxItemStackSize > MAX_INT) maxItemStackSize = MAX_INT;
|
2023-05-30 11:20:31 +02:00
|
|
|
|
|
|
|
ItemStack fromItemStack = from.getItemStack();
|
|
|
|
ItemStack toItemStack = to.getItemStack();
|
|
|
|
|
|
|
|
if (fromItemStack.getType() != toItemStack.getType()) return null;
|
|
|
|
if (!ignoreRestrictions && UltimateStacker.isMaterialBlacklisted(fromItemStack)) return null;
|
|
|
|
|
2023-07-17 12:20:37 +02:00
|
|
|
long maxSize = UltimateStacker.getInstance().getItemFile().getInt("Items." + fromItemStack.getType().name() + ".Max Stack Size");
|
2023-05-30 11:20:31 +02:00
|
|
|
|
2023-07-08 11:23:20 +02:00
|
|
|
if (maxSize <= 0) {
|
|
|
|
maxSize = maxItemStackSize;
|
|
|
|
} else {
|
|
|
|
maxSize = Math.min(maxSize, maxItemStackSize);
|
|
|
|
}
|
|
|
|
|
2023-07-17 12:20:37 +02:00
|
|
|
long fromAmount = getActualItemAmount(from);
|
|
|
|
long toAmount = getActualItemAmount(to);
|
2023-05-30 11:20:31 +02:00
|
|
|
|
|
|
|
if (fromAmount + toAmount > maxSize) {
|
|
|
|
if (callback != null) callback.accept(from, to, null);
|
2023-07-08 11:23:20 +02:00
|
|
|
|
2023-05-30 11:20:31 +02:00
|
|
|
//merge was unsuccessful
|
|
|
|
return null;
|
|
|
|
} else {
|
2023-07-17 12:20:37 +02:00
|
|
|
StackedItem merged = new StackedItemImpl(to, (int) (fromAmount + toAmount));
|
2023-05-30 11:20:31 +02:00
|
|
|
if (callback != null) callback.accept(null, to, merged);
|
|
|
|
return merged;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isMaterialBlacklisted(ItemStack item) {
|
|
|
|
return UltimateStacker.isMaterialBlacklisted(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isMaterialBlacklisted(String type) {
|
|
|
|
return UltimateStacker.isMaterialBlacklisted(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isMaterialBlacklisted(Material type) {
|
|
|
|
return UltimateStacker.isMaterialBlacklisted(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isMaterialBlacklisted(Material type, byte data) {
|
|
|
|
return UltimateStacker.isMaterialBlacklisted(type, data);
|
|
|
|
}
|
|
|
|
}
|