From c944e6add7085c5171eec6299c27f704b6404e15 Mon Sep 17 00:00:00 2001 From: ceze88 Date: Tue, 30 May 2023 11:20:31 +0200 Subject: [PATCH] Finish StackedItem manager --- .../UltimateStacker.java | 142 ++---------------- .../commands/CommandRemoveAll.java | 3 +- .../listeners/entity/EntityListeners.java | 9 +- .../listeners/item/ItemCurrentListener.java | 11 +- .../listeners/item/ItemLegacyListener.java | 5 +- .../listeners/item/ItemListeners.java | 87 +++++------ .../block/BlockStackManagerImpl.java | 34 +++++ .../stackable/item/ItemStackImpl.java | 35 ----- .../stackable/item/ItemStackManagerImpl.java | 18 --- .../stackable/item/StackedItemImpl.java | 123 +++++++++++++++ .../item/StackedItemManagerImpl.java | 135 +++++++++++++++++ .../utils/Methods.java | 48 +----- UltimateStackerAPI/pom.xml | 6 + .../api/UltimateStackerAPI.java | 20 ++- .../api/stack/block/BlockStackManager.java | 36 +++++ .../api/stack/item/ItemMergeCallback.java | 16 ++ .../api/stack/item/ItemStack.java | 7 - .../api/stack/item/ItemStackManager.java | 11 -- .../api/stack/item/StackedItem.java | 20 +++ .../api/stack/item/StackedItemManager.java | 111 ++++++++++++++ 20 files changed, 572 insertions(+), 305 deletions(-) delete mode 100644 UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackImpl.java delete mode 100644 UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackManagerImpl.java create mode 100644 UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemImpl.java create mode 100644 UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemManagerImpl.java create mode 100644 UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemMergeCallback.java delete mode 100644 UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStack.java delete mode 100644 UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStackManager.java create mode 100644 UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItem.java create mode 100644 UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItemManager.java diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/UltimateStacker.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/UltimateStacker.java index 0960f20..71fb9f6 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/UltimateStacker.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/UltimateStacker.java @@ -5,7 +5,7 @@ import com.craftaro.ultimatestacker.api.stack.block.BlockStack; import com.craftaro.ultimatestacker.api.stack.block.BlockStackManager; import com.craftaro.ultimatestacker.api.stack.entity.EntityStack; import com.craftaro.ultimatestacker.api.stack.entity.EntityStackManager; -import com.craftaro.ultimatestacker.api.stack.item.ItemStackManager; +import com.craftaro.ultimatestacker.api.stack.item.StackedItemManager; import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStack; import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStackManager; import com.craftaro.ultimatestacker.commands.CommandConvert; @@ -32,10 +32,9 @@ import com.craftaro.ultimatestacker.lootables.LootablesManager; import com.craftaro.ultimatestacker.stackable.block.BlockStackImpl; import com.craftaro.ultimatestacker.stackable.entity.EntityStackManagerImpl; import com.craftaro.ultimatestacker.stackable.entity.custom.CustomEntityManager; -import com.craftaro.ultimatestacker.stackable.item.ItemStackManagerImpl; +import com.craftaro.ultimatestacker.stackable.item.StackedItemManagerImpl; import com.craftaro.ultimatestacker.stackable.spawner.SpawnerStackImpl; import com.craftaro.ultimatestacker.utils.Async; -import com.craftaro.ultimatestacker.utils.Methods; import com.songoda.core.SongodaCore; import com.songoda.core.SongodaPlugin; import com.songoda.core.commands.CommandManager; @@ -67,14 +66,10 @@ import com.craftaro.ultimatestacker.stackable.spawner.SpawnerStackManagerImpl; import com.craftaro.ultimatestacker.tasks.StackingTask; import org.apache.commons.lang.WordUtils; import org.bukkit.Bukkit; -import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.entity.EntityType; -import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.plugin.PluginManager; import java.util.ArrayList; @@ -98,7 +93,7 @@ public class UltimateStacker extends SongodaPlugin { private EntityStackManager entityStackManager; private SpawnerStackManager spawnerStackManager; private BlockStackManager blockStackManager; - private ItemStackManager itemStackManager; + private StackedItemManager stackedItemManager; private LootablesManager lootablesManager; private CommandManager commandManager; private CustomEntityManager customEntityManager; @@ -195,7 +190,7 @@ public class UltimateStacker extends SongodaPlugin { this.spawnerStackManager = new SpawnerStackManagerImpl(); this.entityStackManager = new EntityStackManagerImpl(this); this.blockStackManager = new BlockStackManagerImpl(); - this.itemStackManager = new ItemStackManagerImpl(); + this.stackedItemManager = new StackedItemManagerImpl(); this.customEntityManager = new CustomEntityManager(); guiManager.init(); @@ -212,21 +207,24 @@ public class UltimateStacker extends SongodaPlugin { pluginManager.registerEvents(new EntityListeners(this), this); pluginManager.registerEvents(new ItemListeners(this), this); - if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) { pluginManager.registerEvents(new ItemCurrentListener(), this); - else + } else { pluginManager.registerEvents(new ItemLegacyListener(), this); + } pluginManager.registerEvents(new TameListeners(this), this); pluginManager.registerEvents(new SpawnerListeners(this), this); pluginManager.registerEvents(new SheepDyeListeners(this), this); - if (Settings.CLEAR_LAG.getBoolean() && pluginManager.isPluginEnabled("ClearLag")) + if (Settings.CLEAR_LAG.getBoolean() && pluginManager.isPluginEnabled("ClearLag")) { pluginManager.registerEvents(new ClearLagListeners(this), this); + } // Register Hooks - if (pluginManager.isPluginEnabled("Jobs")) + if (pluginManager.isPluginEnabled("Jobs")) { stackerHooks.add(new JobsHook()); + } HologramManager.load(this); EntityStackerManager.load(); @@ -261,7 +259,7 @@ public class UltimateStacker extends SongodaPlugin { new _6_RemoveStackedEntityTable()); this.dataMigrationManager.runMigrations(); - API = new UltimateStackerAPI(entityStackManager, itemStackManager, spawnerStackManager, blockStackManager); + API = new UltimateStackerAPI(entityStackManager, stackedItemManager, spawnerStackManager, blockStackManager); } @Override @@ -384,8 +382,8 @@ public class UltimateStacker extends SongodaPlugin { return entityStackManager; } - public ItemStackManager getItemStackManager() { - return itemStackManager; + public StackedItemManager getStackedItemManager() { + return stackedItemManager; } public SpawnerStackManager getSpawnerStackManager() { @@ -420,118 +418,6 @@ public class UltimateStacker extends SongodaPlugin { //////// Convenient API ////////// - /** - * Spawn a stacked item at a location - * - * @param item The item to spawn - * @param amount The amount of items to spawn - * @param location The location to spawn the item - */ - public static void spawnStackedItem(ItemStack item, int amount, Location location) { - if (item.getType() == Material.AIR) return; - World world = location.getWorld(); - if (world == null) return; - if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17)) { - world.dropItem(location, item, dropped -> { - if (dropped.getItemStack().getType() == Material.AIR) return; - updateItemMeta(dropped, item, amount); - }); - } else { - Item dropped = world.dropItem(location, item); - if (dropped.getItemStack().getType() == Material.AIR) return; - updateItemMeta(dropped, item, amount); - } - } - - /** - * Change the stacked amount for this item - * - * @param item item entity to update - * @param newAmount number of items this item represents - */ - public static void updateItemAmount(Item item, int newAmount) { - updateItemAmount(item, item.getItemStack(), newAmount); - } - - /** - * Change the stacked amount for this item - * - * @param item item entity to update - * @param itemStack ItemStack that will represent this item - * @param newAmount number of items this item represents - */ - public static void updateItemAmount(Item item, ItemStack itemStack, int newAmount) { - boolean blacklisted = isMaterialBlacklisted(itemStack); - - if (newAmount > (itemStack.getMaxStackSize() / 2) && !blacklisted) - itemStack.setAmount(Math.max(1, itemStack.getMaxStackSize() / 2)); - else - itemStack.setAmount(newAmount); - - // If amount is 0, Minecraft change the type to AIR - if (itemStack.getType() == Material.AIR) - return; - - updateItemMeta(item, itemStack, newAmount); - } - - public static void updateItemMeta(Item item, ItemStack itemStack, int newAmount) { - Material material = itemStack.getType(); - if (material == Material.AIR) - return; - - String name = TextUtils.convertToInvisibleString("IS") + Methods.compileItemName(itemStack, newAmount); - - boolean blacklisted = isMaterialBlacklisted(itemStack); - - if (newAmount > (itemStack.getMaxStackSize() / 2) && !blacklisted) { - item.setMetadata("US_AMT", new FixedMetadataValue(INSTANCE, newAmount)); - } else { - item.removeMetadata("US_AMT", INSTANCE); - } - item.setItemStack(itemStack); - - if ((blacklisted && !Settings.ITEM_HOLOGRAM_BLACKLIST.getBoolean()) - || !INSTANCE.getItemFile().getBoolean("Items." + material + ".Has Hologram") - || !Settings.ITEM_HOLOGRAMS.getBoolean() - || newAmount < Settings.ITEM_MIN_HOLOGRAM_SIZE.getInt()) - return; - - item.setCustomName(name); - item.setCustomNameVisible(true); - } - - /** - * Lookup the stacked size of this item - * - * @param item item to check - * @return stacker-corrected value for the stack size - */ - public static int getActualItemAmount(Item item) { - ItemStack itemStack = item.getItemStack(); - int amount = itemStack.getAmount(); - if (/*amount >= (itemStack.getMaxStackSize() / 2) && */item.hasMetadata("US_AMT")) { - return item.getMetadata("US_AMT").get(0).asInt(); - } else { - return amount; - } - } - - /** - * Check to see if the amount stored in this itemstack is not the stacked - * amount - * - * @param item item to check - * @return true if Item.getItemStack().getAmount() is different from the - * stacked amount - */ - public static boolean hasCustomAmount(Item item) { - if (item.hasMetadata("US_AMT")) { - return item.getItemStack().getAmount() != item.getMetadata("US_AMT").get(0).asInt(); - } - return false; - } - /** * Check to see if this material is not permitted to stack * diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/commands/CommandRemoveAll.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/commands/CommandRemoveAll.java index 3c11cf5..f2a38d8 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/commands/CommandRemoveAll.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/commands/CommandRemoveAll.java @@ -5,7 +5,6 @@ import com.craftaro.ultimatestacker.api.stack.entity.EntityStackManager; import com.songoda.core.commands.AbstractCommand; import com.songoda.core.utils.TextUtils; import com.craftaro.ultimatestacker.UltimateStacker; -import com.craftaro.ultimatestacker.stackable.entity.EntityStackManagerImpl; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.CommandSender; @@ -54,7 +53,7 @@ public class CommandRemoveAll extends AbstractCommand { stack.destroy(); amountRemoved++; } else if (entityO.getType() == EntityType.DROPPED_ITEM && type.equalsIgnoreCase("items")) { - if (!UltimateStacker.hasCustomAmount((Item)entityO) && !all) + if (!UltimateStacker.getInstance().getStackedItemManager().isStackedItem((Item)entityO) && !all) continue; entityO.remove(); amountRemoved++; diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/entity/EntityListeners.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/entity/EntityListeners.java index 538e24d..6b35e31 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/entity/EntityListeners.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/entity/EntityListeners.java @@ -4,6 +4,7 @@ import com.craftaro.ultimatestacker.UltimateStacker; import com.craftaro.ultimatestacker.api.UltimateStackerAPI; import com.craftaro.ultimatestacker.api.stack.entity.EntityStack; import com.craftaro.ultimatestacker.api.stack.entity.EntityStackManager; +import com.craftaro.ultimatestacker.api.stack.item.StackedItem; import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStack; import com.craftaro.ultimatestacker.settings.Settings; import com.craftaro.ultimatestacker.utils.Methods; @@ -70,8 +71,12 @@ public class EntityListeners implements Listener { int amount = (stack.getAmount() - 1) + item.getAmount(); if (amount < 1) return; item.setAmount(Math.min(amount, item.getMaxStackSize())); - if (amount > item.getMaxStackSize()) - UltimateStacker.updateItemAmount(event.getEntity(), amount); + if (amount > item.getMaxStackSize()) { + StackedItem stackedItem = UltimateStackerAPI.getStackedItemManager().getStackedItem(event.getEntity()); + if (stackedItem != null) { + stackedItem.setAmount(amount - item.getMaxStackSize()); + } + } event.getEntity().setItemStack(item); } diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemCurrentListener.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemCurrentListener.java index 064eb1d..fed5d1c 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemCurrentListener.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemCurrentListener.java @@ -1,5 +1,7 @@ package com.craftaro.ultimatestacker.listeners.item; +import com.craftaro.ultimatestacker.api.UltimateStackerAPI; +import com.craftaro.ultimatestacker.api.stack.item.StackedItem; import com.songoda.core.compatibility.CompatibleSound; import com.craftaro.ultimatestacker.UltimateStacker; import com.craftaro.ultimatestacker.settings.Settings; @@ -20,9 +22,10 @@ public class ItemCurrentListener implements Listener { // Amount here is not the total amount of item (32 if more than 32) but the amount of item the player can retrieve // ie there is x64 diamonds blocks (so 32), the player pick 8 items so the amount is 8 and not 32 - Item item = event.getItem(); - ItemStack stack = item.getItemStack(); - int amount = UltimateStacker.getActualItemAmount(item); + StackedItem stackedItem = UltimateStackerAPI.getStackedItemManager().getStackedItem(event.getItem()); + if (stackedItem == null) return; + ItemStack stack = stackedItem.getItem().getItemStack(); + int amount = stackedItem.getAmount(); if (event.getEntity() instanceof Player) { if (amount < (stack.getMaxStackSize() / 2)) return; @@ -31,7 +34,7 @@ public class ItemCurrentListener implements Listener { player.playSound(player.getLocation(), CompatibleSound.ENTITY_ITEM_PICKUP.getSound(), .2f, (float) (1 + Math.random())); Methods.updateInventory(event.getItem(), player.getInventory()); } else { - UltimateStacker.updateItemMeta(item, stack, amount - 1); + stackedItem.setAmount(amount - 1); } } } diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemLegacyListener.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemLegacyListener.java index f10dcee..458302e 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemLegacyListener.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemLegacyListener.java @@ -1,5 +1,6 @@ package com.craftaro.ultimatestacker.listeners.item; +import com.craftaro.ultimatestacker.api.UltimateStackerAPI; import com.songoda.core.compatibility.CompatibleSound; import com.craftaro.ultimatestacker.UltimateStacker; import com.craftaro.ultimatestacker.settings.Settings; @@ -13,6 +14,8 @@ import org.bukkit.inventory.ItemStack; public class ItemLegacyListener implements Listener { + //TODO Do we need this? + @EventHandler public void onPickup(PlayerPickupItemEvent event) { if (!Settings.STACK_ITEMS.getBoolean() || event.getItem() instanceof Arrow) return; @@ -21,7 +24,7 @@ public class ItemLegacyListener implements Listener { Item item = event.getItem(); ItemStack stack = item.getItemStack(); - int amount = UltimateStacker.getActualItemAmount(item); + int amount = UltimateStackerAPI.getStackedItemManager().getActualItemAmount(item); if (amount < (stack.getMaxStackSize() / 2)) return; event.setCancelled(true); diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemListeners.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemListeners.java index fb91db7..c1d7f2f 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemListeners.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/listeners/item/ItemListeners.java @@ -1,5 +1,8 @@ package com.craftaro.ultimatestacker.listeners.item; +import com.craftaro.ultimatestacker.api.UltimateStackerAPI; +import com.craftaro.ultimatestacker.api.stack.item.StackedItem; +import com.craftaro.ultimatestacker.api.stack.item.StackedItemManager; import com.songoda.core.nms.NmsManager; import com.craftaro.ultimatestacker.UltimateStacker; import com.craftaro.ultimatestacker.settings.Settings; @@ -7,7 +10,6 @@ import com.craftaro.ultimatestacker.utils.Methods; import org.apache.commons.lang.StringUtils; import org.bukkit.block.Block; import org.bukkit.block.BlockState; -import org.bukkit.entity.Item; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.ItemMergeEvent; @@ -30,37 +32,18 @@ public class ItemListeners implements Listener { int maxItemStackSize = Settings.MAX_STACK_ITEMS.getInt(); if (!Settings.STACK_ITEMS.getBoolean()) return; - List disabledWorlds = Settings.DISABLED_WORLDS.getStringList(); - if (disabledWorlds.stream().anyMatch(worldStr -> event.getEntity().getWorld().getName().equalsIgnoreCase(worldStr))) - return; - - Item item = event.getTarget(); - ItemStack itemStack = item.getItemStack(); - - event.setCancelled(true); - - int specific = plugin.getItemFile().getInt("Items." + itemStack.getType().name() + ".Max Stack Size"); - int max; - - if (UltimateStacker.isMaterialBlacklisted(itemStack)) - max = new ItemStack(itemStack.getType()).getMaxStackSize(); - else - max = specific == -1 && new ItemStack(itemStack.getType()).getMaxStackSize() != 1 ? maxItemStackSize : specific; - - if (max == -1) max = 1; - - int newAmount = UltimateStacker.getActualItemAmount(event.getEntity()) - + UltimateStacker.getActualItemAmount(item); - - if (newAmount > max) return; - - UltimateStacker.updateItemAmount(item, itemStack, newAmount); - event.getEntity().remove(); + StackedItem stackedItem = UltimateStacker.getInstance().getStackedItemManager().merge(event.getEntity(), event.getTarget(), false, (fromStack, toStack, merged) -> { + if (fromStack == null && merged != null) { + //merge was successful + event.setCancelled(true); + event.getEntity().remove(); //remove the item that was merged + } + }); } @EventHandler public void onInvPickup(InventoryPickupItemEvent event) { - if (!Settings.STACK_ITEMS.getBoolean() || !UltimateStacker.hasCustomAmount(event.getItem())) { + if (!Settings.STACK_ITEMS.getBoolean() || !UltimateStacker.getInstance().getStackedItemManager().isStackedItem(event.getItem())) { return; } @@ -73,26 +56,32 @@ public class ItemListeners implements Listener { } } - @EventHandler - public void onExist(ItemSpawnEvent event) { - if (!Settings.STACK_ITEMS.getBoolean()) return; + //Do we need this? - List disabledWorlds = Settings.DISABLED_WORLDS.getStringList(); - if (disabledWorlds.stream().anyMatch(worldStr -> event.getEntity().getWorld().getName().equalsIgnoreCase(worldStr))) - return; - - ItemStack itemStack = event.getEntity().getItemStack(); - - if (itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName() && - StringUtils.substring(itemStack.getItemMeta().getDisplayName(), 0, 3).equals("***")) { - return; //Compatibility with Shop instance: https://www.spigotmc.org/resources/shop-a-simple-intuitive-shop-instance.9628/ - } - - if (UltimateStacker.hasCustomAmount(event.getEntity())) { - UltimateStacker.updateItemAmount(event.getEntity(), itemStack, UltimateStacker.getActualItemAmount(event.getEntity()) + itemStack.getAmount()); - } else { - UltimateStacker.updateItemAmount(event.getEntity(), itemStack, itemStack.getAmount()); - } - - } + //@EventHandler +// public void onExist(ItemSpawnEvent event) { +// if (!Settings.STACK_ITEMS.getBoolean()) return; +// +// List disabledWorlds = Settings.DISABLED_WORLDS.getStringList(); +// if (disabledWorlds.stream().anyMatch(worldStr -> event.getEntity().getWorld().getName().equalsIgnoreCase(worldStr))) +// return; +// +// ItemStack itemStack = event.getEntity().getItemStack(); +// +// if (itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName() && +// StringUtils.substring(itemStack.getItemMeta().getDisplayName(), 0, 3).equals("***")) { +// return; //Compatibility with Shop instance: https://www.spigotmc.org/resources/shop-a-simple-intuitive-shop-instance.9628/ +// } +// +// StackedItemManager itemStackManager = UltimateStackerAPI.getStackedItemManager(); +// +// if (itemStackManager.isStackedItem(event.getEntity())) { +// StackedItem stackedItem = UltimateStacker.getInstance().getStackedItemManager().getStackedItem(event.getEntity()); +// stackedItem.setAmount(stackedItem.getAmount() + itemStack.getAmount()); +// UltimateStacker.updateItemAmount(event.getEntity(), itemStack, UltimateStacker.getActualItemAmount(event.getEntity()) + itemStack.getAmount()); +// } else { +// UltimateStacker.updateItemAmount(event.getEntity(), itemStack, itemStack.getAmount()); +// } +// +// } } diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/block/BlockStackManagerImpl.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/block/BlockStackManagerImpl.java index 34d8228..82bc0a3 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/block/BlockStackManagerImpl.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/block/BlockStackManagerImpl.java @@ -1,10 +1,14 @@ package com.craftaro.ultimatestacker.stackable.block; +import com.craftaro.ultimatestacker.UltimateStacker; import com.craftaro.ultimatestacker.api.stack.block.BlockStack; import com.craftaro.ultimatestacker.api.stack.block.BlockStackManager; import com.songoda.core.compatibility.CompatibleMaterial; +import com.songoda.core.compatibility.ServerVersion; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; import java.util.Collection; import java.util.Collections; @@ -15,43 +19,73 @@ public class BlockStackManagerImpl implements BlockStackManager { private final Map registeredBlocks = new HashMap<>(); + @Override public void addBlocks(Map blocks) { this.registeredBlocks.putAll(blocks); } + @Override public BlockStack addBlock(BlockStack blockStack) { this.registeredBlocks.put(roundLocation(blockStack.getLocation()), blockStack); return blockStack; } + @Override public BlockStack removeBlock(Location location) { return registeredBlocks.remove(roundLocation(location)); } + @Override public BlockStack getBlock(Location location) { return this.registeredBlocks.get(location); } + @Override public BlockStack getBlock(Block block, CompatibleMaterial material) { return this.getBlock(block.getLocation()); } + @Override public BlockStack createBlock(Location location, CompatibleMaterial material) { return this.registeredBlocks.computeIfAbsent(location, b -> new BlockStackImpl(material, location)); } + @Override public BlockStack createBlock(Block block) { return this.createBlock(block.getLocation(), CompatibleMaterial.getMaterial(block)); } + @Override public boolean isBlock(Location location) { return this.registeredBlocks.get(location) != null; } + @Override public Collection getStacks() { return Collections.unmodifiableCollection(this.registeredBlocks.values()); } + @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); + } + + private Location roundLocation(Location location) { location = location.clone(); location.setX(location.getBlockX()); diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackImpl.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackImpl.java deleted file mode 100644 index 704ee4e..0000000 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.craftaro.ultimatestacker.stackable.item; - -import com.craftaro.ultimatestacker.api.stack.item.ItemStack; -import com.songoda.core.compatibility.CompatibleMaterial; -import org.bukkit.entity.Item; - -public class ItemStackImpl implements ItemStack { - - private CompatibleMaterial material; - private Item item; - private int amount; - - public ItemStackImpl() { - } - - @Override - public int getAmount() { - return 0; - } - - @Override - public void setAmount(int amount) { - - } - - @Override - public void add(int amount) { - - } - - @Override - public void take(int amount) { - - } -} diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackManagerImpl.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackManagerImpl.java deleted file mode 100644 index 7374cc5..0000000 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/ItemStackManagerImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.craftaro.ultimatestacker.stackable.item; - -import com.craftaro.ultimatestacker.api.stack.item.ItemStack; -import com.craftaro.ultimatestacker.api.stack.item.ItemStackManager; -import org.bukkit.entity.Item; - -public class ItemStackManagerImpl implements ItemStackManager { - - @Override - public ItemStack getItem(Item item) { - return null; - } - - @Override - public ItemStack createStack(Item item, int amount) { - return null; - } -} diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemImpl.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemImpl.java new file mode 100644 index 0000000..ab03c33 --- /dev/null +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemImpl.java @@ -0,0 +1,123 @@ +package com.craftaro.ultimatestacker.stackable.item; + +import com.craftaro.ultimatestacker.UltimateStacker; +import com.craftaro.ultimatestacker.api.stack.item.StackedItem; +import com.craftaro.ultimatestacker.settings.Settings; +import com.craftaro.ultimatestacker.utils.Methods; +import com.songoda.core.utils.TextUtils; +import org.bukkit.Material; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +public class StackedItemImpl implements StackedItem { + + private final Item item; + + public StackedItemImpl(Item item) { + this.item = item; + } + + public StackedItemImpl(Item item, int amount) { + this.item = item; + setAmount(amount); + } + + @Override + public int getAmount() { + ItemStack itemStack = item.getItemStack(); + int amount = itemStack.getAmount(); + if (item.hasMetadata("US_AMT")) { + return item.getMetadata("US_AMT").get(0).asInt(); + } else { + return amount; + } + } + + @Override + public void setAmount(int amount) { + updateItemAmount(item, amount); + } + + @Override + public void add(int amount) { + updateItemAmount(item, getAmount() + amount); + } + + @Override + public void take(int amount) { + //check that amount not go below 0 + if (getAmount() - amount < 0) { + amount = 0; + } + + updateItemAmount(item, getAmount() - amount); + } + + private void updateItemAmount(Item item, int newAmount) { + updateItemAmount(item, item.getItemStack(), newAmount); + } + + /** + * Change the stacked amount for this item + * + * @param item item entity to update + * @param itemStack StackedItem that will represent this item + * @param newAmount number of items this item represents + */ + private void updateItemAmount(Item item, ItemStack itemStack, int newAmount) { + boolean blacklisted = UltimateStacker.isMaterialBlacklisted(itemStack); + + if (newAmount > (itemStack.getMaxStackSize() / 2) && !blacklisted) { + itemStack.setAmount(Math.max(1, itemStack.getMaxStackSize() / 2)); + } else { + itemStack.setAmount(newAmount); + } + + // If amount is 0, Minecraft change the type to AIR + if (itemStack.getType() == Material.AIR) { + return; + } + + updateItemMeta(item, itemStack, newAmount); + } + + private void updateItemMeta(Item item, ItemStack itemStack, int newAmount) { + Material material = itemStack.getType(); + if (material == Material.AIR) + return; + + String name = TextUtils.convertToInvisibleString("IS") + Methods.compileItemName(itemStack, newAmount); + + boolean blacklisted = UltimateStacker.isMaterialBlacklisted(itemStack); + + if (newAmount > (itemStack.getMaxStackSize() / 2) && !blacklisted) { + item.setMetadata("US_AMT", new FixedMetadataValue(UltimateStacker.getInstance(), newAmount)); + } else { + item.removeMetadata("US_AMT", UltimateStacker.getInstance()); + } + item.setItemStack(itemStack); + + if ((blacklisted && !Settings.ITEM_HOLOGRAM_BLACKLIST.getBoolean()) + || !UltimateStacker.getInstance().getItemFile().getBoolean("Items." + material + ".Has Hologram") + || !Settings.ITEM_HOLOGRAMS.getBoolean() + || newAmount < Settings.ITEM_MIN_HOLOGRAM_SIZE.getInt()) + return; + + item.setCustomName(name); + item.setCustomNameVisible(true); + } + + @Override + public Item getItem() { + return item; + } + + @Override + public Item destroy() { + item.removeMetadata("US_AMT", UltimateStacker.getInstance()); + item.setCustomName(null); + item.setCustomNameVisible(true); + return item; + } +} diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemManagerImpl.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemManagerImpl.java new file mode 100644 index 0000000..ea91033 --- /dev/null +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/stackable/item/StackedItemManagerImpl.java @@ -0,0 +1,135 @@ +package com.craftaro.ultimatestacker.stackable.item; + +import com.craftaro.ultimatestacker.UltimateStacker; +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; +import com.songoda.core.compatibility.ServerVersion; +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; +import java.util.concurrent.atomic.AtomicReference; + +public class StackedItemManagerImpl implements StackedItemManager { + + @Override + public @Nullable StackedItem getStackedItem(Item item) { + if (item.hasMetadata("US_AMT")) { + return new StackedItemImpl(item); + } + return null; + } + + @Override + public @NotNull StackedItem getStackedItem(Item item, boolean create) { + return null; + } + + @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; + AtomicReference stack = new AtomicReference<>(null); + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17)) { + world.dropItem(location, item, dropped -> { + if (dropped.getItemStack().getType() == Material.AIR) return; + stack.set(new StackedItemImpl(dropped, amount)); + }); + } else { + Item dropped = world.dropItem(location, item); + if (dropped.getItemStack().getType() == Material.AIR) return null; + stack.set(new StackedItemImpl(dropped, amount)); + } + return stack.get(); + } + + @Override + public @Nullable StackedItem createStack(Item item, int amount) { + return null; + } + + @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 + public StackedItem merge(Item from, Item to, boolean ignoreRestrictions) { + return merge(from, to, ignoreRestrictions, null); + } + + @Override + public StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback callback) { + + if (!ignoreRestrictions) { + if (!Settings.STACK_ITEMS.getBoolean()) return null; + List disabledWorlds = Settings.DISABLED_WORLDS.getStringList(); + if (disabledWorlds.stream().anyMatch(worldStr -> from.getWorld().getName().equalsIgnoreCase(worldStr))) { + return null; + } + } + + int maxItemStackSize = Settings.MAX_STACK_ITEMS.getInt(); + + ItemStack fromItemStack = from.getItemStack(); + ItemStack toItemStack = to.getItemStack(); + + if (fromItemStack.getType() != toItemStack.getType()) return null; + if (!ignoreRestrictions && UltimateStacker.isMaterialBlacklisted(fromItemStack)) return null; + + int maxSize = UltimateStacker.getInstance().getItemFile().getInt("Items." + fromItemStack.getType().name() + ".Max Stack Size"); + + int fromAmount = getActualItemAmount(from); + int toAmount = getActualItemAmount(to); + + if (fromAmount + toAmount > maxSize) { + if (callback != null) callback.accept(from, to, null); + //merge was unsuccessful + return null; + } else { + StackedItem merged = new StackedItemImpl(to, fromAmount + toAmount); + 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); + } +} diff --git a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/utils/Methods.java b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/utils/Methods.java index efe2c4f..05e4b9c 100644 --- a/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/utils/Methods.java +++ b/UltimateStacker/src/main/java/com.craftaro.ultimatestacker/utils/Methods.java @@ -1,5 +1,7 @@ package com.craftaro.ultimatestacker.utils; +import com.craftaro.ultimatestacker.api.UltimateStackerAPI; +import com.craftaro.ultimatestacker.api.stack.item.StackedItem; import com.songoda.core.compatibility.CompatibleMaterial; import com.songoda.core.third_party.de.tr7zw.nbtapi.NBTItem; import com.songoda.core.utils.TextUtils; @@ -22,7 +24,8 @@ import java.util.Map; public class Methods { public static void updateInventory(Item item, Inventory inventory) { - int amount = UltimateStacker.getActualItemAmount(item); + StackedItem stackedItem = UltimateStackerAPI.getStackedItemManager().getStackedItem(item); + int amount = stackedItem.getAmount(); ItemStack itemStack = item.getItemStack(); final int maxStack = itemStack.getMaxStackSize(); @@ -38,46 +41,11 @@ public class Methods { } } - if (amount <= 0) + if (amount <= 0) { item.remove(); - else - UltimateStacker.updateItemAmount(item, itemStack, amount); - } - - // Do not touch! API for older plugins - @Deprecated - public static boolean isMaterialBlacklisted(Material type) { - return UltimateStacker.isMaterialBlacklisted(type); - } - - // Do not touch! API for older plugins - @Deprecated - public static boolean isMaterialBlacklisted(Material type, byte data) { - return UltimateStacker.isMaterialBlacklisted(type, data); - } - - // Do not touch! API for older plugins - @Deprecated - public static void updateItemAmount(Item item, int newAmount) { - UltimateStacker.updateItemAmount(item, newAmount); - } - - // Do not touch! API for older plugins - @Deprecated - public static void updateItemAmount(Item item, ItemStack itemStack, int newAmount) { - UltimateStacker.updateItemAmount(item, itemStack, newAmount); - } - - // Do not touch! API for older plugins - @Deprecated - public static int getActualItemAmount(Item item) { - return UltimateStacker.getActualItemAmount(item); - } - - // Do not touch! API for older plugins - @Deprecated - public static boolean hasCustomAmount(Item item) { - return UltimateStacker.hasCustomAmount(item); + } else { + stackedItem.setAmount(amount); + } } public static String compileItemName(ItemStack item, int amount) { diff --git a/UltimateStackerAPI/pom.xml b/UltimateStackerAPI/pom.xml index eae0c8f..9470c01 100644 --- a/UltimateStackerAPI/pom.xml +++ b/UltimateStackerAPI/pom.xml @@ -74,5 +74,11 @@ 2.6.22 provided + + + org.jetbrains + annotations + 24.0.1 + diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/UltimateStackerAPI.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/UltimateStackerAPI.java index b6a223a..bdb7e14 100644 --- a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/UltimateStackerAPI.java +++ b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/UltimateStackerAPI.java @@ -2,23 +2,23 @@ package com.craftaro.ultimatestacker.api; import com.craftaro.ultimatestacker.api.stack.block.BlockStackManager; import com.craftaro.ultimatestacker.api.stack.entity.EntityStackManager; -import com.craftaro.ultimatestacker.api.stack.item.ItemStackManager; +import com.craftaro.ultimatestacker.api.stack.item.StackedItemManager; import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStackManager; public final class UltimateStackerAPI { private static EntityStackManager entityStackManager; - private static ItemStackManager itemStackManager; + private static StackedItemManager stackedItemManager; private static SpawnerStackManager spawnerStackManager; private static BlockStackManager blockStackManager; private static UltimateStackerAPI instance; - public UltimateStackerAPI(EntityStackManager entityStackManager, ItemStackManager itemStackManager, SpawnerStackManager spawnerStackManager, BlockStackManager blockStackManager) { - if (UltimateStackerAPI.entityStackManager != null || UltimateStackerAPI.itemStackManager != null || UltimateStackerAPI.spawnerStackManager != null || UltimateStackerAPI.blockStackManager != null) { + public UltimateStackerAPI(EntityStackManager entityStackManager, StackedItemManager itemStackManager, SpawnerStackManager spawnerStackManager, BlockStackManager blockStackManager) { + if (UltimateStackerAPI.entityStackManager != null || UltimateStackerAPI.stackedItemManager != null || UltimateStackerAPI.spawnerStackManager != null || UltimateStackerAPI.blockStackManager != null) { throw new IllegalStateException("UltimateStackerAPI has already been initialized!"); } UltimateStackerAPI.entityStackManager = entityStackManager; - UltimateStackerAPI.itemStackManager = itemStackManager; + UltimateStackerAPI.stackedItemManager = itemStackManager; UltimateStackerAPI.spawnerStackManager = spawnerStackManager; UltimateStackerAPI.blockStackManager = blockStackManager; instance = this; @@ -38,10 +38,10 @@ public final class UltimateStackerAPI { /** * Used to interact with ItemStacks - * @return The ItemStackManager + * @return The StackedItemManager */ - public static ItemStackManager getItemStackManager() { - return itemStackManager; + public static StackedItemManager getStackedItemManager() { + return stackedItemManager; } /** @@ -52,6 +52,10 @@ public final class UltimateStackerAPI { return spawnerStackManager; } + /** + * Used to interact with BlockStacks + * @return The BlockStackManager + */ public static BlockStackManager getBlockStackManager() { return blockStackManager; } diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/block/BlockStackManager.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/block/BlockStackManager.java index 202fa44..1648a38 100644 --- a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/block/BlockStackManager.java +++ b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/block/BlockStackManager.java @@ -1,8 +1,11 @@ package com.craftaro.ultimatestacker.api.stack.block; import com.songoda.core.compatibility.CompatibleMaterial; +import com.songoda.core.compatibility.ServerVersion; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; import java.util.Collection; import java.util.Map; @@ -26,4 +29,37 @@ public interface BlockStackManager { boolean isBlock(Location location); Collection getStacks(); + + /** + * Check to see if this material is not permitted to stack + * + * @param item Item material to check + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(ItemStack item); + + /** + * Check to see if this material is not permitted to stack + * + * @param type Material to check + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(String type); + + /** + * Check to see if this material is not permitted to stack + * + * @param type Material to check + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(Material type); + + /** + * Check to see if this material is not permitted to stack + * + * @param type Material to check + * @param data data value for this item (for 1.12 and older servers) + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(Material type, byte data); } diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemMergeCallback.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemMergeCallback.java new file mode 100644 index 0000000..d2b771d --- /dev/null +++ b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemMergeCallback.java @@ -0,0 +1,16 @@ +package com.craftaro.ultimatestacker.api.stack.item; + +import org.bukkit.entity.Item; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface ItemMergeCallback { + + /** + * Called when two items are merged + * @param from The item that was merged into another (null if the merge was successful) + * @param to The item that was merged into + * @param stack The item that was created from the merge (null if the merge was unsuccessful) + */ + void accept(@Nullable F from, @NotNull T to, @Nullable S stack); +} diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStack.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStack.java deleted file mode 100644 index aae61e6..0000000 --- a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStack.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.craftaro.ultimatestacker.api.stack.item; - -import com.craftaro.ultimatestacker.api.utils.StackableEntity; - -public interface ItemStack extends StackableEntity { - -} diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStackManager.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStackManager.java deleted file mode 100644 index 4beee00..0000000 --- a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/ItemStackManager.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.craftaro.ultimatestacker.api.stack.item; - -import org.bukkit.entity.Item; - -public interface ItemStackManager { - - ItemStack getItem(Item item); - - ItemStack createStack(Item item, int amount); - -} diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItem.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItem.java new file mode 100644 index 0000000..d98f644 --- /dev/null +++ b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItem.java @@ -0,0 +1,20 @@ +package com.craftaro.ultimatestacker.api.stack.item; + +import com.craftaro.ultimatestacker.api.utils.StackableEntity; +import org.bukkit.entity.Item; + +public interface StackedItem extends StackableEntity { + + /** + * Get the Item entity for this StackedItem + * @return The Item entity for this StackedItem + */ + Item getItem(); + + /** + * Removes the custom amount from the item + * while not destroying the actual item + */ + Item destroy(); + +} diff --git a/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItemManager.java b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItemManager.java new file mode 100644 index 0000000..17fd7e6 --- /dev/null +++ b/UltimateStackerAPI/src/main/java/com/craftaro/ultimatestacker/api/stack/item/StackedItemManager.java @@ -0,0 +1,111 @@ +package com.craftaro.ultimatestacker.api.stack.item; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + + +public interface StackedItemManager { + + /** + * Get the StackedItem for the given Item + * @param item The Item to get the stack for + * @return The StackedItem for the given Item or null if not stacked + */ + @Nullable StackedItem getStackedItem(Item item); + + /** + * Get the StackedItem for the given Item + * @param item The Item to get the stack for + * @param create If true, will create a new stack if one does not exist + * @return The StackedItem for the given Item or null if not stacked + */ + @NotNull StackedItem getStackedItem(Item item, boolean create); + + /** + * Create a new StackedItem for the given item + * @param item The ItemStack to create the stack for + * @param amount The amount of items in the stack + * @param location The location to spawn the stack + * @return The StackedItem for the given Item or null if it could not be created + */ + @Nullable StackedItem createStack(ItemStack item, Location location, int amount); + + /** + * Create a new StackedItem for the given item + * @param item The item to create the stack for + * @param amount The amount of items in the stack + * @return The StackedItem for the given Item or null if it could not be created + */ + @Nullable StackedItem createStack(Item item, int amount); + + /** + * Get the actual amount of the given item + * @param item item to check + * @return The amount of items in the stacked item or vanilla stack size if not stacked + */ + int getActualItemAmount(Item item); + + /** + * Returns true if the given item is stacked + * + * @param item item to check + * @return true if the given item is stacked + */ + boolean isStackedItem(Item item); + + /** + * Merge two items together if they are the same type + * @param from first item + * @param to second item + * @param ignoreRestrictions ignore ignoreRestrictions such as max stack size, or blacklist + * @return The merged item or null if they merge was unsuccessful + */ + StackedItem merge(Item from, Item to, boolean ignoreRestrictions); + + /** + * Merge two items together if they are the same type + * @param from first item + * @param to second item + * @param ignoreRestrictions ignore ignoreRestrictions such as max stack size, or blacklist + * @param callback callback to be called when the merge is successful see {@link ItemMergeCallback#accept(Item, Item, StackedItem)} + * @return The merged item or null if they merge was unsuccessful + */ + StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback callback); + + /** + * Check to see if this material is not permitted to stack + * + * @param item Item material to check + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(ItemStack item); + + /** + * Check to see if this material is not permitted to stack + * + * @param type Material to check + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(String type); + + /** + * Check to see if this material is not permitted to stack + * + * @param type Material to check + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(Material type); + + /** + * Check to see if this material is not permitted to stack + * + * @param type Material to check + * @param data data value for this item (for 1.12 and older servers) + * @return true if this material will not stack + */ + boolean isMaterialBlacklisted(Material type, byte data); +}