Added per chunk per type stack limits.

This commit is contained in:
Brianna 2019-08-07 14:24:49 -04:00
parent 80d3c8f7b9
commit d63c29c7f3
3 changed files with 58 additions and 34 deletions

View File

@ -31,6 +31,8 @@ public class StackingTask extends BukkitRunnable {
private int maxEntityStackSize = Setting.MAX_STACK_ENTITIES.getInt(); private int maxEntityStackSize = Setting.MAX_STACK_ENTITIES.getInt();
private int minEntityStackSize = Setting.MIN_STACK_ENTITIES.getInt(); private int minEntityStackSize = Setting.MIN_STACK_ENTITIES.getInt();
private int minPerTypeStacksPerChunk = Setting.MIN_PER_TYPE_STACKS_PER_CHUNK.getInt();
public StackingTask(UltimateStacker plugin) { public StackingTask(UltimateStacker plugin) {
this.plugin = plugin; this.plugin = plugin;
this.stackManager = plugin.getEntityStackManager(); this.stackManager = plugin.getEntityStackManager();
@ -117,6 +119,15 @@ public class StackingTask extends BukkitRunnable {
// Is this entity stacked? // Is this entity stacked?
boolean isStack = stack != null; boolean isStack = stack != null;
if (isStack && minPerTypeStacksPerChunk != -1) {
if (plugin.getEntityUtils().getSimilarStacksInChunk(livingEntity) > minPerTypeStacksPerChunk) {
stack.setAmount(1);
livingEntity.remove();
this.processed.add(livingEntity.getUniqueId());
return;
}
}
// The amount that is stackable. // The amount that is stackable.
int amountToStack = isStack ? stack.getAmount() : 1; int amountToStack = isStack ? stack.getAmount() : 1;
@ -280,5 +291,4 @@ public class StackingTask extends BukkitRunnable {
maxEntityStackSize = configurationSection.getInt("Mobs." + initialEntity.getType().name() + ".Max Stack Size"); maxEntityStackSize = configurationSection.getInt("Mobs." + initialEntity.getType().name() + ".Max Stack Size");
return maxEntityStackSize; return maxEntityStackSize;
} }
} }

View File

@ -14,6 +14,8 @@ import java.util.stream.Collectors;
public class EntityUtils { public class EntityUtils {
UltimateStacker plugin = UltimateStacker.getInstance();
private List<String> checks = Setting.STACK_CHECKS.getStringList(); private List<String> checks = Setting.STACK_CHECKS.getStringList();
private boolean stackFlyingDown = Setting.ONLY_STACK_FLYING_DOWN.getBoolean(); private boolean stackFlyingDown = Setting.ONLY_STACK_FLYING_DOWN.getBoolean();
private boolean keepFire = Setting.KEEP_FIRE.getBoolean(); private boolean keepFire = Setting.KEEP_FIRE.getBoolean();
@ -28,7 +30,7 @@ public class EntityUtils {
} }
private Set<CachedChunk> getNearbyChunks(Location location, double radius) { private Set<CachedChunk> getNearbyChunks(Location location, double radius, boolean singleChunk) {
World world = location.getWorld(); World world = location.getWorld();
Set<CachedChunk> chunks = new HashSet<>(); Set<CachedChunk> chunks = new HashSet<>();
if (world == null) return chunks; if (world == null) return chunks;
@ -36,7 +38,7 @@ public class EntityUtils {
Chunk firstChunk = location.getChunk(); Chunk firstChunk = location.getChunk();
chunks.add(new CachedChunk(firstChunk)); chunks.add(new CachedChunk(firstChunk));
if (stackWholeChunk) return chunks; if (singleChunk) return chunks;
int minX = (int) Math.floor(((location.getX() - radius) - 2.0D) / 16.0D); int minX = (int) Math.floor(((location.getX() - radius) - 2.0D) / 16.0D);
int maxX = (int) Math.floor(((location.getX() + radius) + 2.0D) / 16.0D); int maxX = (int) Math.floor(((location.getX() + radius) + 2.0D) / 16.0D);
@ -52,9 +54,9 @@ public class EntityUtils {
return chunks; return chunks;
} }
private List<LivingEntity> getNearbyEntities(Location location, double radius) { private List<LivingEntity> getNearbyEntities(Location location, double radius, boolean singleChunk) {
List<LivingEntity> entities = new ArrayList<>(); List<LivingEntity> entities = new ArrayList<>();
for (CachedChunk chunk : getNearbyChunks(location, radius)) { for (CachedChunk chunk : getNearbyChunks(location, radius, singleChunk)) {
Entity[] entityArray; Entity[] entityArray;
if (cachedChunks.containsKey(chunk)) { if (cachedChunks.containsKey(chunk)) {
entityArray = cachedChunks.get(chunk); entityArray = cachedChunks.get(chunk);
@ -65,13 +67,22 @@ public class EntityUtils {
for (Entity e : entityArray) { for (Entity e : entityArray) {
if (e.getWorld() != location.getWorld() if (e.getWorld() != location.getWorld()
|| !(e instanceof LivingEntity) || !(e instanceof LivingEntity)
|| (!stackWholeChunk && location.distanceSquared(e.getLocation()) >= radius * radius)) continue; || (!singleChunk && location.distanceSquared(e.getLocation()) >= radius * radius)) continue;
entities.add((LivingEntity) e); entities.add((LivingEntity) e);
} }
} }
return entities; return entities;
} }
public int getSimilarStacksInChunk(LivingEntity entity) {
int count = 0;
for (LivingEntity e : getNearbyEntities(entity.getLocation(), -1, true)) {
if (plugin.getEntityStackManager().isStacked(e))
count++;
}
return count;
}
public LivingEntity newEntity(LivingEntity toClone) { public LivingEntity newEntity(LivingEntity toClone) {
LivingEntity newEntity = (LivingEntity) toClone.getWorld().spawnEntity(toClone.getLocation(), toClone.getType()); LivingEntity newEntity = (LivingEntity) toClone.getWorld().spawnEntity(toClone.getLocation(), toClone.getType());
newEntity.setVelocity(toClone.getVelocity()); newEntity.setVelocity(toClone.getVelocity());
@ -85,7 +96,7 @@ public class EntityUtils {
break; break;
} }
case NERFED: { case NERFED: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_9)) break; if (!plugin.isServerVersionAtLeast(ServerVersion.V1_9)) break;
if (!toClone.hasAI()) newEntity.setAI(false); if (!toClone.hasAI()) newEntity.setAI(false);
} }
case IS_TAMED: { case IS_TAMED: {
@ -98,7 +109,7 @@ public class EntityUtils {
} }
case SKELETON_TYPE: { case SKELETON_TYPE: {
if (!(toClone instanceof Skeleton) if (!(toClone instanceof Skeleton)
|| UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_12)) break; || plugin.isServerVersionAtLeast(ServerVersion.V1_12)) break;
((Skeleton) newEntity).setSkeletonType(((Skeleton) toClone).getSkeletonType()); ((Skeleton) newEntity).setSkeletonType(((Skeleton) toClone).getSkeletonType());
break; break;
} }
@ -113,13 +124,13 @@ public class EntityUtils {
break; break;
} }
case LLAMA_COLOR: { case LLAMA_COLOR: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(toClone instanceof Llama)) break; || !(toClone instanceof Llama)) break;
((Llama) newEntity).setColor(((Llama) toClone).getColor()); ((Llama) newEntity).setColor(((Llama) toClone).getColor());
break; break;
} }
case LLAMA_STRENGTH: { case LLAMA_STRENGTH: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(toClone instanceof Llama)) break; || !(toClone instanceof Llama)) break;
((Llama) newEntity).setStrength(((Llama) toClone).getStrength()); ((Llama) newEntity).setStrength(((Llama) toClone).getStrength());
break; break;
@ -135,7 +146,7 @@ public class EntityUtils {
break; break;
} }
case HORSE_JUMP: { case HORSE_JUMP: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(toClone instanceof AbstractHorse)) break; || !(toClone instanceof AbstractHorse)) break;
((AbstractHorse) newEntity).setJumpStrength(((AbstractHorse) toClone).getJumpStrength()); ((AbstractHorse) newEntity).setJumpStrength(((AbstractHorse) toClone).getJumpStrength());
break; break;
@ -162,11 +173,11 @@ public class EntityUtils {
} }
case OCELOT_TYPE: { case OCELOT_TYPE: {
if (!(toClone instanceof Ocelot) if (!(toClone instanceof Ocelot)
|| UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_14)) break; || plugin.isServerVersionAtLeast(ServerVersion.V1_14)) break;
((Ocelot) newEntity).setCatType(((Ocelot) toClone).getCatType()); ((Ocelot) newEntity).setCatType(((Ocelot) toClone).getCatType());
} }
case CAT_TYPE: { case CAT_TYPE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_14) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_14)
|| !(toClone instanceof Cat)) break; || !(toClone instanceof Cat)) break;
((Cat) newEntity).setCatType(((Cat) toClone).getCatType()); ((Cat) newEntity).setCatType(((Cat) toClone).getCatType());
break; break;
@ -177,37 +188,37 @@ public class EntityUtils {
break; break;
} }
case PARROT_TYPE: { case PARROT_TYPE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_12) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_12)
|| !(toClone instanceof Parrot)) break; || !(toClone instanceof Parrot)) break;
((Parrot) newEntity).setVariant(((Parrot) toClone).getVariant()); ((Parrot) newEntity).setVariant(((Parrot) toClone).getVariant());
break; break;
} }
case PUFFERFISH_STATE: { case PUFFERFISH_STATE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof PufferFish)) break; || !(toClone instanceof PufferFish)) break;
((PufferFish) newEntity).setPuffState(((PufferFish) toClone).getPuffState()); ((PufferFish) newEntity).setPuffState(((PufferFish) toClone).getPuffState());
break; break;
} }
case TROPICALFISH_PATTERN: { case TROPICALFISH_PATTERN: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof TropicalFish)) break; || !(toClone instanceof TropicalFish)) break;
((TropicalFish) newEntity).setPattern(((TropicalFish) toClone).getPattern()); ((TropicalFish) newEntity).setPattern(((TropicalFish) toClone).getPattern());
break; break;
} }
case TROPICALFISH_PATTERN_COLOR: { case TROPICALFISH_PATTERN_COLOR: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof TropicalFish)) break; || !(toClone instanceof TropicalFish)) break;
((TropicalFish) newEntity).setPatternColor(((TropicalFish) toClone).getPatternColor()); ((TropicalFish) newEntity).setPatternColor(((TropicalFish) toClone).getPatternColor());
break; break;
} }
case TROPICALFISH_BODY_COLOR: { case TROPICALFISH_BODY_COLOR: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof TropicalFish)) break; || !(toClone instanceof TropicalFish)) break;
((TropicalFish) newEntity).setBodyColor(((TropicalFish) toClone).getBodyColor()); ((TropicalFish) newEntity).setBodyColor(((TropicalFish) toClone).getBodyColor());
break; break;
} }
case PHANTOM_SIZE: { case PHANTOM_SIZE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(toClone instanceof Phantom)) break; || !(toClone instanceof Phantom)) break;
((Phantom) newEntity).setSize(((Phantom) toClone).getSize()); ((Phantom) newEntity).setSize(((Phantom) toClone).getSize());
break; break;
@ -225,7 +236,7 @@ public class EntityUtils {
public List<LivingEntity> getSimilarEntitiesAroundEntity(LivingEntity initalEntity, Location location) { public List<LivingEntity> getSimilarEntitiesAroundEntity(LivingEntity initalEntity, Location location) {
// Create a list of all entities around the initial entity of the same type. // Create a list of all entities around the initial entity of the same type.
List<LivingEntity> entityList = getNearbyEntities(location, searchRadius) List<LivingEntity> entityList = getNearbyEntities(location, searchRadius, stackWholeChunk)
.stream().filter(entity -> entity.getType() == initalEntity.getType() && entity != initalEntity) .stream().filter(entity -> entity.getType() == initalEntity.getType() && entity != initalEntity)
.collect(Collectors.toCollection(LinkedList::new)); .collect(Collectors.toCollection(LinkedList::new));
@ -250,7 +261,7 @@ public class EntityUtils {
break; break;
} }
case NERFED: { case NERFED: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_9)) break; if (!plugin.isServerVersionAtLeast(ServerVersion.V1_9)) break;
entityList.removeIf(entity -> entity.hasAI() != initalEntity.hasAI()); entityList.removeIf(entity -> entity.hasAI() != initalEntity.hasAI());
} }
case IS_TAMED: { case IS_TAMED: {
@ -294,14 +305,14 @@ public class EntityUtils {
break; break;
} }
case LLAMA_COLOR: { case LLAMA_COLOR: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(initalEntity instanceof Llama)) break; || !(initalEntity instanceof Llama)) break;
Llama llama = ((Llama) initalEntity); Llama llama = ((Llama) initalEntity);
entityList.removeIf(entity -> ((Llama) entity).getColor() != llama.getColor()); entityList.removeIf(entity -> ((Llama) entity).getColor() != llama.getColor());
break; break;
} }
case LLAMA_STRENGTH: { case LLAMA_STRENGTH: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_11)
|| !(initalEntity instanceof Llama)) break; || !(initalEntity instanceof Llama)) break;
Llama llama = ((Llama) initalEntity); Llama llama = ((Llama) initalEntity);
entityList.removeIf(entity -> ((Llama) entity).getStrength() != llama.getStrength()); entityList.removeIf(entity -> ((Llama) entity).getStrength() != llama.getStrength());
@ -320,7 +331,7 @@ public class EntityUtils {
break; break;
} }
case HORSE_CARRYING_CHEST: { case HORSE_CARRYING_CHEST: {
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11)) { if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (!(initalEntity instanceof ChestedHorse)) break; if (!(initalEntity instanceof ChestedHorse)) break;
entityList.removeIf(entity -> ((ChestedHorse) entity).isCarryingChest()); entityList.removeIf(entity -> ((ChestedHorse) entity).isCarryingChest());
} else { } else {
@ -335,7 +346,7 @@ public class EntityUtils {
break; break;
} }
case HORSE_HAS_SADDLE: { case HORSE_HAS_SADDLE: {
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (plugin.isServerVersionAtLeast(ServerVersion.V1_13)
&& initalEntity instanceof AbstractHorse) { && initalEntity instanceof AbstractHorse) {
entityList.removeIf(entity -> ((AbstractHorse) entity).getInventory().getSaddle() != null); entityList.removeIf(entity -> ((AbstractHorse) entity).getInventory().getSaddle() != null);
break; break;
@ -345,7 +356,7 @@ public class EntityUtils {
break; break;
} }
case HORSE_JUMP: { case HORSE_JUMP: {
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_11)) { if (plugin.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (!(initalEntity instanceof AbstractHorse)) break; if (!(initalEntity instanceof AbstractHorse)) break;
AbstractHorse horse = ((AbstractHorse) initalEntity); AbstractHorse horse = ((AbstractHorse) initalEntity);
entityList.removeIf(entity -> ((AbstractHorse) entity).getJumpStrength() != horse.getJumpStrength()); entityList.removeIf(entity -> ((AbstractHorse) entity).getJumpStrength() != horse.getJumpStrength());
@ -387,7 +398,7 @@ public class EntityUtils {
entityList.removeIf(entity -> ((Ocelot) entity).getCatType() != ocelot.getCatType()); entityList.removeIf(entity -> ((Ocelot) entity).getCatType() != ocelot.getCatType());
} }
case CAT_TYPE: { case CAT_TYPE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_14) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_14)
|| !(initalEntity instanceof Cat)) break; || !(initalEntity instanceof Cat)) break;
Cat cat = (Cat) initalEntity; Cat cat = (Cat) initalEntity;
entityList.removeIf(entity -> ((Cat) entity).getCatType() != cat.getCatType()); entityList.removeIf(entity -> ((Cat) entity).getCatType() != cat.getCatType());
@ -400,42 +411,42 @@ public class EntityUtils {
break; break;
} }
case PARROT_TYPE: { case PARROT_TYPE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_12) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_12)
|| !(initalEntity instanceof Parrot)) break; || !(initalEntity instanceof Parrot)) break;
Parrot parrot = (Parrot) initalEntity; Parrot parrot = (Parrot) initalEntity;
entityList.removeIf(entity -> ((Parrot) entity).getVariant() != parrot.getVariant()); entityList.removeIf(entity -> ((Parrot) entity).getVariant() != parrot.getVariant());
break; break;
} }
case PUFFERFISH_STATE: { case PUFFERFISH_STATE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof PufferFish)) break; || !(initalEntity instanceof PufferFish)) break;
PufferFish pufferFish = (PufferFish) initalEntity; PufferFish pufferFish = (PufferFish) initalEntity;
entityList.removeIf(entity -> ((PufferFish) entity).getPuffState() != pufferFish.getPuffState()); entityList.removeIf(entity -> ((PufferFish) entity).getPuffState() != pufferFish.getPuffState());
break; break;
} }
case TROPICALFISH_PATTERN: { case TROPICALFISH_PATTERN: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof TropicalFish)) break; || !(initalEntity instanceof TropicalFish)) break;
TropicalFish tropicalFish = (TropicalFish) initalEntity; TropicalFish tropicalFish = (TropicalFish) initalEntity;
entityList.removeIf(entity -> ((TropicalFish) entity).getPattern() != tropicalFish.getPattern()); entityList.removeIf(entity -> ((TropicalFish) entity).getPattern() != tropicalFish.getPattern());
break; break;
} }
case TROPICALFISH_PATTERN_COLOR: { case TROPICALFISH_PATTERN_COLOR: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof TropicalFish)) break; || !(initalEntity instanceof TropicalFish)) break;
TropicalFish tropicalFish = (TropicalFish) initalEntity; TropicalFish tropicalFish = (TropicalFish) initalEntity;
entityList.removeIf(entity -> ((TropicalFish) entity).getPatternColor() != tropicalFish.getPatternColor()); entityList.removeIf(entity -> ((TropicalFish) entity).getPatternColor() != tropicalFish.getPatternColor());
break; break;
} }
case TROPICALFISH_BODY_COLOR: { case TROPICALFISH_BODY_COLOR: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof TropicalFish)) break; || !(initalEntity instanceof TropicalFish)) break;
TropicalFish tropicalFish = (TropicalFish) initalEntity; TropicalFish tropicalFish = (TropicalFish) initalEntity;
entityList.removeIf(entity -> ((TropicalFish) entity).getBodyColor() != tropicalFish.getBodyColor()); entityList.removeIf(entity -> ((TropicalFish) entity).getBodyColor() != tropicalFish.getBodyColor());
break; break;
} }
case PHANTOM_SIZE: { case PHANTOM_SIZE: {
if (!UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)
|| !(initalEntity instanceof Phantom)) break; || !(initalEntity instanceof Phantom)) break;
Phantom phantom = (Phantom) initalEntity; Phantom phantom = (Phantom) initalEntity;
entityList.removeIf(entity -> ((Phantom) entity).getSize() != phantom.getSize()); entityList.removeIf(entity -> ((Phantom) entity).getSize() != phantom.getSize());
@ -452,7 +463,7 @@ public class EntityUtils {
} }
public void splitFromStack(LivingEntity entity) { public void splitFromStack(LivingEntity entity) {
UltimateStacker instance = UltimateStacker.getInstance(); UltimateStacker instance = plugin;
EntityStack stack = instance.getEntityStackManager().getStack(entity); EntityStack stack = instance.getEntityStackManager().getStack(entity);
if (stack.getAmount() <= 1) return; if (stack.getAmount() <= 1) return;

View File

@ -34,6 +34,9 @@ public enum Setting {
"The minimum amount required before a stack can be formed.", "The minimum amount required before a stack can be formed.",
"Do not set this to lower than 2."), "Do not set this to lower than 2."),
MIN_PER_TYPE_STACKS_PER_CHUNK("Entities.Min Per Type Stacks Per Chunk", -1,
"The minimum amount of each entity type stack allowed in a chunk."),
STACK_WHOLE_CHUNK("Entities.Stack Whole Chunk", false, STACK_WHOLE_CHUNK("Entities.Stack Whole Chunk", false,
"Should all qualifying entities in each chunk be stacked?", "Should all qualifying entities in each chunk be stacked?",
"This will override the stacking radius."), "This will override the stacking radius."),