Redid Item stacking completely.

This commit is contained in:
Brianna 2019-06-04 03:17:25 -04:00
parent f02076933c
commit 50a6d5c04d
7 changed files with 141 additions and 139 deletions

View File

@ -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")) {

View File

@ -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); */
}
}

View File

@ -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);
}
}

View File

@ -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<Integer, ItemStack> 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();
}
}
}

View File

@ -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;
}
}

View File

@ -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."),