diff --git a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java index f8efe2e..7c31e8c 100644 --- a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java +++ b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java @@ -166,8 +166,8 @@ public class UltimateStacker extends JavaPlugin { Bukkit.getPluginManager().registerEvents(new DeathListeners(this), this); Bukkit.getPluginManager().registerEvents(new ShearListeners(this), this); Bukkit.getPluginManager().registerEvents(new InteractListeners(this), this); - Bukkit.getPluginManager().registerEvents(new InventoryListeners(this), this); Bukkit.getPluginManager().registerEvents(new EntityListeners(this), this); + Bukkit.getPluginManager().registerEvents(new ItemListeners(this), this); // Register Hologram Plugin if (getConfig().getBoolean("Spawners.Holograms Enabled")) { diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/EntityListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/EntityListeners.java index 71b1b58..35f21c7 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/EntityListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/EntityListeners.java @@ -81,6 +81,7 @@ public class EntityListeners implements Listener { @EventHandler public void onPickup(PlayerPickupItemEvent event) { + /* event.getItem().setItemStack(instance.getStackingTask().setMax(event.getItem().getItemStack(), 0, true)); ItemStack item = event.getItem().getItemStack(); @@ -106,7 +107,7 @@ public class EntityListeners implements Listener { ItemStack newItem = new ItemStack(item); newItem.setAmount(amt); - event.getItem().getWorld().dropItemNaturally(event.getItem().getLocation(), newItem); + event.getItem().getWorld().dropItemNaturally(event.getItem().getLocation(), newItem); */ } } diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/InventoryListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/InventoryListeners.java deleted file mode 100644 index dc005bd..0000000 --- a/src/main/java/com/songoda/ultimatestacker/listeners/InventoryListeners.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.songoda.ultimatestacker.listeners; - -import com.songoda.ultimatestacker.UltimateStacker; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryMoveItemEvent; -import org.bukkit.event.inventory.InventoryPickupItemEvent; -import org.bukkit.inventory.ItemStack; - -public class InventoryListeners implements Listener { - - private final UltimateStacker instance; - - public InventoryListeners(UltimateStacker instance) { - this.instance = instance; - } - - @EventHandler - public void onMove(InventoryMoveItemEvent event) { - ItemStack item = event.getItem(); - if (new ItemStack(item.getType()).getMaxStackSize() == item.getMaxStackSize()) return; - - instance.getStackingTask().setMax(item, 0, true); - int amt = item.getAmount(); - int max = item.getMaxStackSize(); - - if (amt <= max) return; - - item.setAmount(max); - amt = amt - max; - - while (amt > max) { - ItemStack newItem = new ItemStack(item); - newItem.setAmount(max); - - event.getDestination().addItem(newItem); - amt = amt - max; - } - - ItemStack newItem = new ItemStack(item); - newItem.setAmount(amt); - - event.getDestination().addItem(newItem); - } - - @EventHandler - public void onAccept(InventoryPickupItemEvent event) { - ItemStack item = event.getItem().getItemStack(); - if (new ItemStack(item.getType()).getMaxStackSize() == item.getMaxStackSize()) return; - - instance.getStackingTask().setMax(item, 0, true); - int amt = item.getAmount(); - int max = item.getMaxStackSize(); - - if (amt <= max) return; - - item.setAmount(max); - amt = amt - max; - - while (amt > max) { - ItemStack newItem = new ItemStack(item); - newItem.setAmount(max); - - event.getInventory().addItem(newItem); - amt = amt - max; - } - - ItemStack newItem = new ItemStack(item); - newItem.setAmount(amt); - - event.getInventory().addItem(newItem); - } - -} diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/ItemListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/ItemListeners.java new file mode 100644 index 0000000..a991753 --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/listeners/ItemListeners.java @@ -0,0 +1,132 @@ +package com.songoda.ultimatestacker.listeners; + +import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.utils.Methods; +import com.songoda.ultimatestacker.utils.ServerVersion; +import com.songoda.ultimatestacker.utils.settings.Setting; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.entity.ItemMergeEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +import java.util.Map; + +public class ItemListeners implements Listener { + + private final UltimateStacker instance; + + public ItemListeners(UltimateStacker instance) { + this.instance = instance; + } + + // Make it so that the max allowed stack size on the map is 32 that way this event will always trigger. + // If an item in the game world is larger than 32 then set it to 32 and add metadata. The player shouldn't notice. + // Make it so that weighted pressure plates work. + // When picking up some of a stack the item will need to be updated to reflect that. + + @EventHandler + public void onMerge(ItemMergeEvent event) { + event.setCancelled(true); + + int maxItemStackSize = Setting.MAX_STACK_ITEMS.getInt(); + if (!Setting.STACK_ITEMS.getBoolean()) return; + + Item item = event.getTarget(); + + int specific = instance.getItemFile().getConfig().getInt("Items." + item.getItemStack().getType().name() + ".Max Stack Size"); + int max = specific == -1 && new ItemStack(item.getItemStack().getType()).getMaxStackSize() != 1 ? maxItemStackSize : specific; + + if (max == -1) max = 1; + + int newAmount = getActualAmount(event.getEntity()) + + getActualAmount(item); + + if (newAmount > max) return; + + updateAmount(item, newAmount); + event.getEntity().remove(); + } + @EventHandler + public void onInvPickup(InventoryPickupItemEvent event) { + event.setCancelled(true); + + updateInventory(event.getItem(), event.getInventory()); + } + + @EventHandler + public void onDispense(ItemSpawnEvent event) { + if (!Setting.STACK_ITEMS.getBoolean()) return; + + updateAmount(event.getEntity(), event.getEntity().getItemStack().getAmount()); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent event) { + if (event.getItem().getItemStack().getAmount() < 32) return; + event.setCancelled(true); + + event.getPlayer().playSound(event.getPlayer().getLocation(), + instance.isServerVersionAtLeast(ServerVersion.V1_9) ? Sound.ENTITY_ITEM_PICKUP + : Sound.valueOf("ITEM_PICKUP"), .2f, (float)(1 + Math.random())); + + updateInventory(event.getItem(), event.getPlayer().getInventory()); + } + + private void updateInventory(Item item, Inventory inventory) { + int amount = getActualAmount(item); + + while (amount > 0) { + int subtract = Math.min(amount, 64); + amount -= subtract; + ItemStack newItem = item.getItemStack().clone(); + newItem.setAmount(subtract); + Map result = inventory.addItem(newItem); + if (result.get(0) != null) { + amount += result.get(0).getAmount(); + break; + } + } + + if (amount <= 0) + item.remove(); + else + updateAmount(item, amount); + } + + private void updateAmount(Item item, int newAmount) { + Material material = item.getItemStack().getType(); + String name = Methods.convertToInvisibleString("IS") + + Methods.compileItemName(material, newAmount); + + if (newAmount > 32) { + item.setMetadata("US_AMT", new FixedMetadataValue(instance, newAmount)); + item.getItemStack().setAmount(32); + } else { + item.removeMetadata("US_AMT", instance); + item.getItemStack().setAmount(newAmount); + } + + if (instance.getItemFile().getConfig().getBoolean("Items." + material + ".Has Hologram")) { + item.setCustomName(name); + item.setCustomNameVisible(true); + } + } + + private int getActualAmount(Item item) { + if (item.hasMetadata("US_AMT")) { + return item.getMetadata("US_AMT").get(0).asInt(); + } else { + return item.getItemStack().getAmount(); + } + } +} diff --git a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java index d6eb14e..b61c645 100644 --- a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java +++ b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java @@ -23,35 +23,15 @@ public class StackingTask extends BukkitRunnable { private final UltimateStacker instance; - private Method methodGetItem, methodAsNMSCopy; - private Field fieldMaxStackSize; - public StackingTask(UltimateStacker instance) { this.instance = instance; - // Cache reflection. - try { - String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23); - Class clazzCraftItemStack = Class.forName("org.bukkit.craftbukkit." + ver + ".inventory.CraftItemStack"); - Class clazzItemStack = Class.forName("net.minecraft.server." + ver + ".ItemStack"); - Class clazzItem = Class.forName("net.minecraft.server." + ver + ".Item"); - - methodAsNMSCopy = clazzCraftItemStack.getMethod("asNMSCopy", ItemStack.class); - methodGetItem = clazzItemStack.getDeclaredMethod("getItem"); - - fieldMaxStackSize = clazzItem.getDeclaredField("maxStackSize"); - fieldMaxStackSize.setAccessible(true); - } catch (ReflectiveOperationException e) { - e.printStackTrace(); - } - // Start stacking task. runTaskTimer(instance, 0, Setting.STACK_SEARCH_TICK_SPEED.getInt()); } @Override public void run() { - int maxItemStackSize = Setting.MAX_STACK_ITEMS.getInt(); int maxEntityStackSizeGlobal = Setting.MAX_STACK_ENTITIES.getInt(); int minEntityStackAmount = Setting.MIN_STACK_ENTITIES.getInt(); @@ -68,38 +48,11 @@ public class StackingTask extends BukkitRunnable { nextEntity: for (Entity entityO : entities) { - if (entityO == null || entityO instanceof Player || !entityO.isValid()) continue; - - if (entityO instanceof Item && Setting.STACK_ITEMS.getBoolean()) { - ItemStack item = ((Item) entityO).getItemStack(); - - if (entityO.hasMetadata("grabbed") - || item == null - || entityO.isCustomNameVisible() && !entityO.getCustomName().contains(Methods.convertToInvisibleString("IS")) - || item.hasItemMeta() && item.getItemMeta().hasDisplayName()) - continue; - - int specific = instance.getItemFile().getConfig().getInt("Items." + item.getType().name() + ".Max Stack Size"); - int max = specific == -1 && new ItemStack(item.getType()).getMaxStackSize() != 1 ? maxItemStackSize : specific; - - if (max == -1) max = 1; - - if (item.getMaxStackSize() != max && item.getMaxStackSize() != 1 && (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName())) - setMax(item, max, false); - - int size = item.getAmount(); - - String name = Methods.convertToInvisibleString("IS") + Methods.compileItemName(item.getType(), size); - - if (instance.getItemFile().getConfig().getBoolean("Items." + item.getType().name() + ".Has Hologram")) { - entityO.setCustomName(name); - entityO.setCustomNameVisible(true); - } - - continue; - } - - if (!(entityO instanceof LivingEntity) || !Setting.STACK_ENTITIES.getBoolean()) + if (entityO == null + || entityO instanceof Player + || !entityO.isValid() + || !(entityO instanceof LivingEntity) + || !Setting.STACK_ENTITIES.getBoolean()) continue; LivingEntity initalEntity = (LivingEntity) entityO; @@ -168,14 +121,4 @@ public class StackingTask extends BukkitRunnable { removed.clear(); } } - - public ItemStack setMax(ItemStack item, int max, boolean reset) { - try { - Object objItemStack = methodGetItem.invoke(methodAsNMSCopy.invoke(null, item)); - fieldMaxStackSize.set(objItemStack, reset ? new ItemStack(item.getType()).getMaxStackSize() : max); - } catch (ReflectiveOperationException e) { - e.printStackTrace(); - } - return item; - } } diff --git a/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java b/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java index f68dd82..a164477 100644 --- a/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java +++ b/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java @@ -59,7 +59,7 @@ public enum Setting { SEARCH_RADIUS("Entity.Search Radius", 5, "The distance entities must be to each other in order to stack."), - MAX_STACK_ITEMS("Item.Max Stack Size", 120, + MAX_STACK_ITEMS("Item.Max Stack Size", 512, "The max stack size for items.", "Currently this can only be set to a max of 120."), diff --git a/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class b/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class index 888cc50..9755392 100644 Binary files a/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class and b/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class differ