Fix item stacking issues, add annotations

This commit is contained in:
ceze88 2023-07-08 11:23:20 +02:00
parent b9b76b8d28
commit 86a19a520b
8 changed files with 108 additions and 61 deletions

View File

@ -14,21 +14,22 @@ public interface StackedItemManager {
/** /**
* Get the StackedItem for the given Item * Get the StackedItem for the given Item
* Creates a new StackedItem if it does not exist
* @param item The Item to get the stack for * @param item The Item to get the stack for
* @return The StackedItem for the given Item or null if not stacked * @return The StackedItem for the given Item
*/ */
@Nullable StackedItem getStackedItem(Item item); @NotNull 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 * 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
*/
@NotNull StackedItem createStack(Item item, int amount);
/**
* Create a new StackedItem for the given ItemStack
* @param item The ItemStack to create the stack for * @param item The ItemStack to create the stack for
* @param amount The amount of items in the stack * @param amount The amount of items in the stack
* @param location The location to spawn the stack * @param location The location to spawn the stack
@ -37,12 +38,12 @@ public interface StackedItemManager {
@Nullable StackedItem createStack(ItemStack item, Location location, int amount); @Nullable StackedItem createStack(ItemStack item, Location location, int amount);
/** /**
* Create a new StackedItem for the given item * Update the stack for the given item
* @param item The item to create the stack for * @param item The Item to update
* @param amount The amount of items in the stack * @param newAmount The new amount of the stack
* @return The StackedItem for the given Item or null if it could not be created * @return The StackedItem for the given Item
*/ */
@Nullable StackedItem createStack(Item item, int amount); @NotNull StackedItem updateStack(Item item, int newAmount);
/** /**
* Create a new StackedItem for the given item in the main thread * Create a new StackedItem for the given item in the main thread
@ -57,9 +58,17 @@ public interface StackedItemManager {
* Create a new StackedItem for the given item in the main thread * Create a new StackedItem for the given item in the main thread
* @param item The item to create the stack for * @param item The item to create the stack for
* @param amount The amount of items in the stack * @param amount The amount of items in the stack
* @return The StackedItem for the given Item or null if it could not be created * @return The StackedItem for the given Item
*/ */
@Nullable Future<StackedItem> createStackSync(Item item, int amount); @NotNull Future<StackedItem> createStackSync(Item item, int amount);
/**
* Update the stack for the given item in the main thread
* @param item The Item to update
* @param newAmount The new amount of the stack
* @return The StackedItem for the given Item
*/
@NotNull Future<StackedItem> updateStackSync(Item item, int newAmount);
/** /**
* Get the actual amount of the given item * Get the actual amount of the given item
@ -83,7 +92,7 @@ public interface StackedItemManager {
* @param ignoreRestrictions ignore ignoreRestrictions such as max stack size, or blacklist * @param ignoreRestrictions ignore ignoreRestrictions such as max stack size, or blacklist
* @return The merged item or null if they merge was unsuccessful * @return The merged item or null if they merge was unsuccessful
*/ */
StackedItem merge(Item from, Item to, boolean ignoreRestrictions); @Nullable StackedItem merge(Item from, Item to, boolean ignoreRestrictions);
/** /**
* Merge two items together if they are the same type * Merge two items together if they are the same type
@ -93,7 +102,7 @@ public interface StackedItemManager {
* @param callback callback to be called when the merge is successful see {@link ItemMergeCallback#accept(Item, Item, StackedItem)} * @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 * @return The merged item or null if they merge was unsuccessful
*/ */
StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback<Item, Item, StackedItem> callback); @Nullable StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback<Item, Item, StackedItem> callback);
/** /**
* Check to see if this material is not permitted to stack * Check to see if this material is not permitted to stack

View File

@ -65,7 +65,7 @@ public class SpawnerListeners implements Listener {
SpawnerStack spawnerStack = spawnerStackManager.getSpawner(location); SpawnerStack spawnerStack = spawnerStackManager.getSpawner(location);
int amountToSpawn = Settings.STACK_ENTITIES.getBoolean() ? spawnerStack.calculateSpawnCount(entity.getType()) : 1; int amountToSpawn = Settings.STACK_ENTITIES.getBoolean() ? spawnerStack.calculateSpawnCount(entity.getType(), false) : 1;
if (amountToSpawn <= 0) return; if (amountToSpawn <= 0) return;
entity.remove(); entity.remove();

View File

@ -8,20 +8,20 @@ import com.craftaro.ultimatestacker.utils.Methods;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class ItemCurrentListener implements Listener { public class ItemCurrentListener implements Listener {
@EventHandler @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPickup(EntityPickupItemEvent event) { public void onPickup(EntityPickupItemEvent event) {
if (!Settings.STACK_ITEMS.getBoolean() || event.getItem() instanceof Arrow) return; if (!Settings.STACK_ITEMS.getBoolean() || event.getItem() instanceof Arrow) return;
// Amount here is not the total amount of item (32 if more than 32) but the amount of item the player can retrieve // 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 // ie there is x64 diamonds blocks (so 32), the player pick 8 items so the amount is 8 and not 32
StackedItem stackedItem = UltimateStackerApi.getStackedItemManager().getStackedItem(event.getItem()); StackedItem stackedItem = UltimateStackerApi.getStackedItemManager().getStackedItem(event.getItem());
if (stackedItem == null) return;
ItemStack stack = stackedItem.getItem().getItemStack(); ItemStack stack = stackedItem.getItem().getItemStack();
int amount = stackedItem.getAmount(); int amount = stackedItem.getAmount();

View File

@ -7,15 +7,14 @@ import com.craftaro.ultimatestacker.utils.Methods;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class ItemLegacyListener implements Listener { public class ItemLegacyListener implements Listener {
//TODO Do we need this? @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@EventHandler
public void onPickup(PlayerPickupItemEvent event) { public void onPickup(PlayerPickupItemEvent event) {
if (!Settings.STACK_ITEMS.getBoolean() || event.getItem() instanceof Arrow) return; if (!Settings.STACK_ITEMS.getBoolean() || event.getItem() instanceof Arrow) return;
// Amount here is not the total amount of item (32 if more than 32) but the amount of item the player can retrieve // Amount here is not the total amount of item (32 if more than 32) but the amount of item the player can retrieve

View File

@ -88,6 +88,16 @@ public class EntityStackImpl implements EntityStack {
this.amount -= amount; this.amount -= amount;
} }
@Override
public Location getLocation() {
return hostEntity.getLocation();
}
@Override
public boolean isValid() {
return hostEntity.isValid();
}
@Override @Override
public UUID getUuid() { public UUID getUuid() {
return hostEntity.getUniqueId(); return hostEntity.getUniqueId();

View File

@ -5,6 +5,7 @@ import com.craftaro.ultimatestacker.UltimateStacker;
import com.craftaro.ultimatestacker.api.stack.item.StackedItem; import com.craftaro.ultimatestacker.api.stack.item.StackedItem;
import com.craftaro.ultimatestacker.settings.Settings; import com.craftaro.ultimatestacker.settings.Settings;
import com.craftaro.ultimatestacker.utils.Methods; import com.craftaro.ultimatestacker.utils.Methods;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -16,6 +17,9 @@ public class StackedItemImpl implements StackedItem {
public StackedItemImpl(Item item) { public StackedItemImpl(Item item) {
this.item = item; this.item = item;
if (!item.hasMetadata("US_AMT")) {
item.setMetadata("US_AMT", new FixedMetadataValue(UltimateStacker.getInstance(), item.getItemStack().getAmount()));
}
} }
public StackedItemImpl(Item item, int amount) { public StackedItemImpl(Item item, int amount) {
@ -25,12 +29,10 @@ public class StackedItemImpl implements StackedItem {
@Override @Override
public int getAmount() { public int getAmount() {
ItemStack itemStack = item.getItemStack();
int amount = itemStack.getAmount();
if (item.hasMetadata("US_AMT")) { if (item.hasMetadata("US_AMT")) {
return item.getMetadata("US_AMT").get(0).asInt(); return item.getMetadata("US_AMT").get(0).asInt();
} else { } else {
return amount; return item.getItemStack().getAmount();
} }
} }
@ -54,6 +56,16 @@ public class StackedItemImpl implements StackedItem {
updateItemAmount(item, getAmount() - amount); updateItemAmount(item, getAmount() - amount);
} }
@Override
public Location getLocation() {
return item.getLocation();
}
@Override
public boolean isValid() {
return item.isValid();
}
private void updateItemAmount(Item item, int newAmount) { private void updateItemAmount(Item item, int newAmount) {
updateItemAmount(item, item.getItemStack(), newAmount); updateItemAmount(item, item.getItemStack(), newAmount);
} }
@ -84,8 +96,7 @@ public class StackedItemImpl implements StackedItem {
private void updateItemMeta(Item item, ItemStack itemStack, int newAmount) { private void updateItemMeta(Item item, ItemStack itemStack, int newAmount) {
Material material = itemStack.getType(); Material material = itemStack.getType();
if (material == Material.AIR) if (material == Material.AIR) return;
return;
String name = TextUtils.convertToInvisibleString("IS") + Methods.compileItemName(itemStack, newAmount); String name = TextUtils.convertToInvisibleString("IS") + Methods.compileItemName(itemStack, newAmount);
@ -101,8 +112,9 @@ public class StackedItemImpl implements StackedItem {
if ((blacklisted && !Settings.ITEM_HOLOGRAM_BLACKLIST.getBoolean()) if ((blacklisted && !Settings.ITEM_HOLOGRAM_BLACKLIST.getBoolean())
|| !UltimateStacker.getInstance().getItemFile().getBoolean("Items." + material + ".Has Hologram") || !UltimateStacker.getInstance().getItemFile().getBoolean("Items." + material + ".Has Hologram")
|| !Settings.ITEM_HOLOGRAMS.getBoolean() || !Settings.ITEM_HOLOGRAMS.getBoolean()
|| newAmount < Settings.ITEM_MIN_HOLOGRAM_SIZE.getInt()) || newAmount < Settings.ITEM_MIN_HOLOGRAM_SIZE.getInt()) {
return; return;
}
item.setCustomName(name); item.setCustomName(name);
item.setCustomNameVisible(true); item.setCustomNameVisible(true);
@ -120,4 +132,12 @@ public class StackedItemImpl implements StackedItem {
item.setCustomNameVisible(true); item.setCustomNameVisible(true);
return item; return item;
} }
@Override
public String toString() {
return "StackedItemImpl{" +
"ItemStack=" + item.getItemStack() +
", us_amount=" + getAmount() +
'}';
}
} }

View File

@ -22,16 +22,8 @@ import java.util.concurrent.atomic.AtomicReference;
public class StackedItemManagerImpl implements StackedItemManager { public class StackedItemManagerImpl implements StackedItemManager {
@Override @Override
public @Nullable StackedItem getStackedItem(Item item) { public @NotNull StackedItem getStackedItem(Item item) {
if (item.hasMetadata("US_AMT")) { return new StackedItemImpl(item);
return new StackedItemImpl(item);
}
return null;
}
@Override
public @NotNull StackedItem getStackedItem(Item item, boolean create) {
return null;
} }
@Override @Override
@ -39,23 +31,21 @@ public class StackedItemManagerImpl implements StackedItemManager {
if (item.getType() == Material.AIR) return null; if (item.getType() == Material.AIR) return null;
World world = location.getWorld(); World world = location.getWorld();
if (world == null) return null; if (world == null) return null;
AtomicReference<StackedItem> stack = new AtomicReference<>(null); Item dropped = world.dropItem(location, item);
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17)) { if (dropped.getItemStack().getType() == Material.AIR) return null;
world.dropItem(location, item, dropped -> { return new StackedItemImpl(dropped, amount);
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 @Override
public @Nullable StackedItem createStack(Item item, int amount) { public @NotNull StackedItem createStack(Item item, int amount) {
return null; return new StackedItemImpl(item, amount);
}
@Override
public @NotNull StackedItem updateStack(Item item, int newAmount) {
StackedItem stackedItem = getStackedItem(item);
stackedItem.setAmount(newAmount);
return stackedItem;
} }
@Override @Override
@ -64,10 +54,15 @@ public class StackedItemManagerImpl implements StackedItemManager {
} }
@Override @Override
public @Nullable Future<StackedItem> createStackSync(Item item, int amount) { public @NotNull Future<StackedItem> createStackSync(Item item, int amount) {
return Bukkit.getScheduler().callSyncMethod(UltimateStacker.getInstance(), () -> createStack(item, amount)); return Bukkit.getScheduler().callSyncMethod(UltimateStacker.getInstance(), () -> createStack(item, amount));
} }
@Override
public @NotNull Future<StackedItem> updateStackSync(Item item, int newAmount) {
return Bukkit.getScheduler().callSyncMethod(UltimateStacker.getInstance(), () -> updateStack(item, newAmount));
}
@Override @Override
public int getActualItemAmount(Item item) { public int getActualItemAmount(Item item) {
if (isStackedItem(item)) { if (isStackedItem(item)) {
@ -86,12 +81,12 @@ public class StackedItemManagerImpl implements StackedItemManager {
} }
@Override @Override
public StackedItem merge(Item from, Item to, boolean ignoreRestrictions) { public @Nullable StackedItem merge(Item from, Item to, boolean ignoreRestrictions) {
return merge(from, to, ignoreRestrictions, null); return merge(from, to, ignoreRestrictions, null);
} }
@Override @Override
public StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback<Item, Item, StackedItem> callback) { public @Nullable StackedItem merge(Item from, Item to, boolean ignoreRestrictions, ItemMergeCallback<Item, Item, StackedItem> callback) {
if (!ignoreRestrictions) { if (!ignoreRestrictions) {
if (!Settings.STACK_ITEMS.getBoolean()) return null; if (!Settings.STACK_ITEMS.getBoolean()) return null;
@ -111,11 +106,18 @@ public class StackedItemManagerImpl implements StackedItemManager {
int maxSize = UltimateStacker.getInstance().getItemFile().getInt("Items." + fromItemStack.getType().name() + ".Max Stack Size"); int maxSize = UltimateStacker.getInstance().getItemFile().getInt("Items." + fromItemStack.getType().name() + ".Max Stack Size");
if (maxSize <= 0) {
maxSize = maxItemStackSize;
} else {
maxSize = Math.min(maxSize, maxItemStackSize);
}
int fromAmount = getActualItemAmount(from); int fromAmount = getActualItemAmount(from);
int toAmount = getActualItemAmount(to); int toAmount = getActualItemAmount(to);
if (fromAmount + toAmount > maxSize) { if (fromAmount + toAmount > maxSize) {
if (callback != null) callback.accept(from, to, null); if (callback != null) callback.accept(from, to, null);
//merge was unsuccessful //merge was unsuccessful
return null; return null;
} else { } else {

View File

@ -6,6 +6,8 @@ import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStack;
import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStackManager; import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStackManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -31,7 +33,7 @@ public class SpawnerStackManagerImpl implements SpawnerStackManager {
} }
@Override @Override
public SpawnerStack removeSpawner(Location location) { public @Nullable SpawnerStack removeSpawner(Location location) {
return registeredSpawners.remove(roundLocation(location)); return registeredSpawners.remove(roundLocation(location));
} }
@ -45,6 +47,11 @@ public class SpawnerStackManagerImpl implements SpawnerStackManager {
return this.registeredSpawners.get(location); return this.registeredSpawners.get(location);
} }
@Override
public boolean isSpawner(Block block) {
return isSpawner(block.getLocation());
}
@Override @Override
public SpawnerStack getSpawner(Block block) { public SpawnerStack getSpawner(Block block) {
return this.getSpawner(block.getLocation()); return this.getSpawner(block.getLocation());
@ -56,12 +63,12 @@ public class SpawnerStackManagerImpl implements SpawnerStackManager {
} }
@Override @Override
public Collection<SpawnerStack> getStacks() { public @NotNull Collection<SpawnerStack> getStacks() {
return Collections.unmodifiableCollection(this.registeredSpawners.values()); return Collections.unmodifiableCollection(this.registeredSpawners.values());
} }
@Override @Override
public Collection<Data> getStacksData() { public @NotNull Collection<Data> getStacksData() {
return Collections.unmodifiableCollection(this.registeredSpawners.values()); return Collections.unmodifiableCollection(this.registeredSpawners.values());
} }