Fix item stacking when using large numbers

This commit is contained in:
ceze88 2023-07-17 12:20:37 +02:00
parent 86a19a520b
commit 6f77c43d97
5 changed files with 53 additions and 37 deletions

View File

@ -56,8 +56,6 @@ public class ItemListeners implements Listener {
}
}
//Do we need this?
@EventHandler
public void onExist(ItemSpawnEvent event) {
if (!Settings.STACK_ITEMS.getBoolean()) return;
@ -72,16 +70,7 @@ public class ItemListeners implements Listener {
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());
UltimateStackerApi.getStackedItemManager().createStack(event.getEntity(), UltimateStackerApi.getStackedItemManager().getActualItemAmount(event.getEntity()) + itemStack.getAmount());
} else {
UltimateStackerApi.getStackedItemManager().createStack(event.getEntity(), itemStack.getAmount());
}
UltimateStackerApi.getStackedItemManager().createStack(event.getEntity(), itemStack.getAmount());
}
}

View File

@ -27,6 +27,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
public class LootablesManager {
@ -36,6 +37,7 @@ public class LootablesManager {
private final LootManager lootManager;
private final String lootablesDir = UltimateStacker.getInstance().getDataFolder() + File.separator + "lootables";
private final static int MAX_INT = Integer.MAX_VALUE/2;
public LootablesManager() {
this.lootables = new Lootables(lootablesDir);
@ -121,7 +123,6 @@ public class LootablesManager {
double extraChance = looting / (looting + 1.0);
Random random = new Random();
boolean isCharged = entity instanceof Creeper && ((Creeper) entity).isPowered();
//Run main loot
@ -130,38 +131,56 @@ public class LootablesManager {
if (loot.getOnlyDropFor().size() != 0 && loot.getOnlyDropFor().stream().noneMatch(type -> entity.getKiller() != null && type == entity.getKiller().getType())) continue;
int finalLooting = loot.isAllowLootingEnchant() ? looting : 0;
int max = (int) (((loot.getMax() + finalLooting) * times) * (loot.getChance()/100));
int min = (int) ((loot.getMin()) * times * (loot.getChance()/100));
long max = (long) (((long) (loot.getMax() + finalLooting) * times) * (loot.getChance()/100 + (loot.isAllowLootingEnchant() ? extraChance : 0)));
long min = (long) ((loot.getMin()) * times * (loot.getChance()/100));
int amount = random.nextInt((max - min) + 1) + min;
long amount = ThreadLocalRandom.current().nextLong((max - min) + 1) + min;
if (amount > 0) {
ItemStack item = entity.getFireTicks() > 0
? loot.getBurnedMaterial() != null ? loot.getBurnedMaterial().parseItem() : loot.getMaterial().parseItem()
: loot.getMaterial().parseItem().clone();
item.setAmount(amount);
: loot.getMaterial().parseItem();
if (amount > MAX_INT) {
while (amount > MAX_INT) {
ItemStack loop = item.clone();
loop.setAmount(MAX_INT);
amount -= MAX_INT;
toDrop.add(new Drop(loop));
}
}
//Leftover
item.setAmount((int) amount);
toDrop.add(new Drop(item));
}
}
//Run child loot
for (Loot loot : lootable.getRegisteredLoot().stream().filter(loot -> loot.getMaterial() == null).collect(Collectors.toList())) {
//Run child loot //TODO: remove duplicated code
for (Loot child : loot.getChildLoot()) {
if (child.isRequireCharged() && !isCharged) continue;
if (loot.getOnlyDropFor().size() != 0 && loot.getOnlyDropFor().stream().noneMatch(type -> entity.getKiller() != null && type == entity.getKiller().getType())) continue;
if (child.getOnlyDropFor().size() != 0 && child.getOnlyDropFor().stream().noneMatch(type -> entity.getKiller() != null && type == entity.getKiller().getType())) continue;
int finalLooting = child.isAllowLootingEnchant() ? looting : 0;
int choildFinalLooting = child.isAllowLootingEnchant() ? looting : 0;
int max = (int) (((loot.getMax() + finalLooting) * times * (loot.getChance()/100)));
int min = (int) ((loot.getMin()) * times * (loot.getChance()/100));
min = (int) (min - min*0.90);
long childMax = (long) (((long) (child.getMax() + finalLooting) * times) * (child.getChance()/100 + (child.isAllowLootingEnchant() ? extraChance : 0)));
long childmin = (long) ((child.getMin()) * times * (child.getChance()/100));
childmin = (long) (childmin - childmin*0.90);
int amount = random.nextInt((max - min) + 1) + min;
if (amount > 0) {
long childamount = ThreadLocalRandom.current().nextLong((childMax - childmin) + 1) + childmin;
if (childamount > 0) {
ItemStack item = entity.getFireTicks() > 0
? child.getBurnedMaterial() != null ? child.getBurnedMaterial().parseItem() : child.getMaterial().parseItem()
: child.getMaterial().parseItem().clone();
item.setAmount(amount);
: child.getMaterial().parseItem();
if (childamount > MAX_INT) {
while (childamount > MAX_INT) {
ItemStack loop = item.clone();
loop.setAmount(MAX_INT);
childamount -= MAX_INT;
toDrop.add(new Drop(loop));
}
}
//Leftover
item.setAmount((int) childamount);
toDrop.add(new Drop(item));
}
}

View File

@ -34,7 +34,7 @@ public class Settings implements com.craftaro.ultimatestacker.api.Settings {
"The distance entities must be to each other in order to stack.");
public static final ConfigSetting MAX_STACK_ENTITIES = new ConfigSetting(config, "Entities.Max Stack Size", 15,
"The max amount of entities in a single stack.");
"The max amount of entities in a single stack. Max value is 2000000000");
// Note: this setting is also referenced in EpicSpawners
public static final ConfigSetting MIN_STACK_ENTITIES = new ConfigSetting(config, "Entities.Min Stack Amount", 5,
@ -183,7 +183,7 @@ public class Settings implements com.craftaro.ultimatestacker.api.Settings {
"Should items that are blacklisted display holograms?");
public static final ConfigSetting MAX_STACK_ITEMS = new ConfigSetting(config, "Items.Max Stack Size", 512,
"The max stack size for items.");
"The max stack size for items. Max value is 1500000000");
public static final ConfigSetting NAME_FORMAT_ITEM = new ConfigSetting(config, "Items.Name Format", "&f{TYPE} &r[&6{AMT}x]",
"The text displayed above a dropped item.");

View File

@ -1,10 +1,12 @@
package com.craftaro.ultimatestacker.stackable.entity;
import com.craftaro.core.SongodaCore;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.lootables.loot.Drop;
import com.craftaro.core.lootables.loot.DropUtils;
import com.craftaro.core.utils.EntityUtils;
import com.craftaro.ultimatestacker.UltimateStacker;
import com.craftaro.ultimatestacker.api.UltimateStackerApi;
import com.craftaro.ultimatestacker.api.events.entity.EntityStackKillEvent;
import com.craftaro.ultimatestacker.api.stack.entity.EntityStack;
import com.craftaro.ultimatestacker.settings.Settings;
@ -12,6 +14,7 @@ import com.craftaro.ultimatestacker.utils.Async;
import com.craftaro.ultimatestacker.utils.Methods;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.LivingEntity;
@ -21,6 +24,8 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

View File

@ -21,6 +21,8 @@ import java.util.concurrent.atomic.AtomicReference;
public class StackedItemManagerImpl implements StackedItemManager {
private final static int MAX_INT = 1500000000;
@Override
public @NotNull StackedItem getStackedItem(Item item) {
return new StackedItemImpl(item);
@ -97,6 +99,7 @@ public class StackedItemManagerImpl implements StackedItemManager {
}
int maxItemStackSize = Settings.MAX_STACK_ITEMS.getInt();
if (maxItemStackSize > MAX_INT) maxItemStackSize = MAX_INT;
ItemStack fromItemStack = from.getItemStack();
ItemStack toItemStack = to.getItemStack();
@ -104,7 +107,7 @@ public class StackedItemManagerImpl implements StackedItemManager {
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");
long maxSize = UltimateStacker.getInstance().getItemFile().getInt("Items." + fromItemStack.getType().name() + ".Max Stack Size");
if (maxSize <= 0) {
maxSize = maxItemStackSize;
@ -112,8 +115,8 @@ public class StackedItemManagerImpl implements StackedItemManager {
maxSize = Math.min(maxSize, maxItemStackSize);
}
int fromAmount = getActualItemAmount(from);
int toAmount = getActualItemAmount(to);
long fromAmount = getActualItemAmount(from);
long toAmount = getActualItemAmount(to);
if (fromAmount + toAmount > maxSize) {
if (callback != null) callback.accept(from, to, null);
@ -121,7 +124,7 @@ public class StackedItemManagerImpl implements StackedItemManager {
//merge was unsuccessful
return null;
} else {
StackedItem merged = new StackedItemImpl(to, fromAmount + toAmount);
StackedItem merged = new StackedItemImpl(to, (int) (fromAmount + toAmount));
if (callback != null) callback.accept(null, to, merged);
return merged;
}