mirror of
https://github.com/songoda/UltimateStacker.git
synced 2024-11-08 03:21:32 +01:00
Redid the entire stacking task.
This commit is contained in:
parent
109898d6fc
commit
8873c601f0
@ -10,14 +10,15 @@ import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StackingTask extends BukkitRunnable {
|
||||
|
||||
@ -25,8 +26,10 @@ public class StackingTask extends BukkitRunnable {
|
||||
|
||||
private EntityStackManager stackManager;
|
||||
|
||||
ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile().getConfig();
|
||||
|
||||
private List<UUID> processed = new ArrayList<>();
|
||||
|
||||
private List<UUID> removed = new ArrayList<>();
|
||||
|
||||
public StackingTask(UltimateStacker instance) {
|
||||
this.instance = instance;
|
||||
@ -38,148 +41,203 @@ public class StackingTask extends BukkitRunnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Gather disabled worlds.
|
||||
List<String> disabledWorlds = Setting.DISABLED_WORLDS.getStringList();
|
||||
|
||||
nextEntity:
|
||||
// Should entities be stacked?
|
||||
if (!Setting.STACK_ENTITIES.getBoolean()) return;
|
||||
|
||||
// Loop through each world.
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
// If world is disabled then continue to the next world.
|
||||
if (disabledWorlds.stream().anyMatch(worldStr -> world.getName().equalsIgnoreCase(worldStr))) continue;
|
||||
|
||||
List<Entity> entities = world.getEntities();
|
||||
// Get the loaded entities from the current world, reverse them and make sure they are stackable.
|
||||
List<Entity> entities = new ArrayList<>(world.getEntities()).stream()
|
||||
.filter(this::isEntityStackable).collect(Collectors.toList());
|
||||
Collections.reverse(entities);
|
||||
|
||||
for (Entity entityO : entities) {
|
||||
if (!(entityO instanceof LivingEntity)
|
||||
|| entityO instanceof Player
|
||||
|| !entityO.isValid()
|
||||
|| !Setting.STACK_ENTITIES.getBoolean())
|
||||
continue nextEntity;
|
||||
// Loop through the entities.
|
||||
for (Entity entity : entities) {
|
||||
// Make sure our entity has not already been processed.
|
||||
// Skip it if it has been.
|
||||
if (this.processed.contains(entity.getUniqueId())) continue;
|
||||
|
||||
LivingEntity initialEntity = (LivingEntity) entityO;
|
||||
// Cast our entity to living entity.
|
||||
LivingEntity livingEntity = (LivingEntity) entity;
|
||||
|
||||
if (initialEntity.isDead()
|
||||
|| !initialEntity.isValid()
|
||||
|| initialEntity instanceof ArmorStand
|
||||
|| initialEntity.hasMetadata("inLove")
|
||||
// Process the entity.
|
||||
this.processEntity(livingEntity);
|
||||
|
||||
|| Setting.ONLY_STACK_FROM_SPAWNERS.getBoolean()
|
||||
&& !(initialEntity.hasMetadata("US_REASON")
|
||||
&& initialEntity.getMetadata("US_REASON").get(0).asString().equals("SPAWNER"))
|
||||
|
||||
|| Setting.ONLY_STACK_ON_SURFACE.getBoolean()
|
||||
&& !Methods.canFly(initialEntity)
|
||||
&& (!initialEntity.isOnGround() && !initialEntity.getLocation().getBlock().isLiquid()))
|
||||
continue nextEntity;
|
||||
|
||||
EntityStack initialStack = stackManager.getStack(initialEntity);
|
||||
if (initialStack == null && initialEntity.getCustomName() != null) continue nextEntity;
|
||||
|
||||
attemptAddToStack(initialEntity, initialStack);
|
||||
}
|
||||
entities.clear();
|
||||
removed.clear();
|
||||
}
|
||||
processed.clear();
|
||||
}
|
||||
|
||||
public boolean attemptAddToStack(LivingEntity initialEntity, EntityStack initialStack) {
|
||||
ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile().getConfig();
|
||||
private boolean isEntityStackable(Entity entity) {
|
||||
// Make sure we have the correct entity type and that it is valid.
|
||||
if (!entity.isValid()
|
||||
|| !(entity instanceof LivingEntity)
|
||||
|| entity instanceof HumanEntity
|
||||
|| entity instanceof ArmorStand
|
||||
|
||||
if (!configurationSection.getBoolean("Mobs." + initialEntity.getType().name() + ".Enabled"))
|
||||
return false;
|
||||
|
||||
int minEntityStackAmount = Setting.MIN_STACK_ENTITIES.getInt();
|
||||
int amtToStack = initialStack != null ? initialStack.getAmount() : 1;
|
||||
|
||||
List<LivingEntity> entityList = Methods.getSimilarEntitiesAroundEntity(initialEntity);
|
||||
entityList.removeIf(entity -> entity.hasMetadata("inLove")
|
||||
// Make sure the entity is not in love.
|
||||
|| entity.hasMetadata("inLove")
|
||||
// Or in breeding cooldown.
|
||||
|| entity.hasMetadata("breedCooldown")
|
||||
|
||||
// If only stack from spawners is enabled make sure the entity spawned from a spawner.
|
||||
|| Setting.ONLY_STACK_FROM_SPAWNERS.getBoolean()
|
||||
&& !(initialEntity.hasMetadata("US_REASON")
|
||||
&& initialEntity.getMetadata("US_REASON").get(0).asString().equals("SPAWNER")));
|
||||
&& !(entity.hasMetadata("US_REASON")
|
||||
&& entity.getMetadata("US_REASON").get(0).asString().equals("SPAWNER")))
|
||||
return false;
|
||||
|
||||
// Cast our entity to living entity.
|
||||
LivingEntity livingEntity = (LivingEntity) entity;
|
||||
|
||||
int maxEntityStackSize = Setting.MAX_STACK_ENTITIES.getInt();
|
||||
if (configurationSection.getInt("Mobs." + initialEntity.getType().name() + ".Max Stack Size") != -1)
|
||||
maxEntityStackSize = configurationSection.getInt("Mobs." + initialEntity.getType().name() + ".Max Stack Size");
|
||||
// If only stack on surface is enabled make sure the entity is on a surface then entity is stackable.
|
||||
return !Setting.ONLY_STACK_ON_SURFACE.getBoolean()
|
||||
|| Methods.canFly(livingEntity)
|
||||
|| (livingEntity.isOnGround() || livingEntity.getLocation().getBlock().isLiquid());
|
||||
|
||||
}
|
||||
|
||||
for (LivingEntity entity : new ArrayList<>(entityList)) {
|
||||
if (removed.contains(entity.getUniqueId())) continue;
|
||||
EntityStack stack = stackManager.getStack(entity);
|
||||
if (stack == null && entity.getCustomName() != null) {
|
||||
entityList.remove(entity);
|
||||
continue;
|
||||
}
|
||||
private void processEntity(LivingEntity livingEntity) {
|
||||
// Get the stack from the entity. It should be noted that this value will
|
||||
// be null if our entity is not a stack.
|
||||
EntityStack stack = instance.getEntityStackManager().getStack(livingEntity);
|
||||
|
||||
//If a stack was found add 1 to this stack.
|
||||
if (stack != null && (stack.getAmount() + amtToStack) <= maxEntityStackSize) {
|
||||
stack.addAmount(amtToStack);
|
||||
stack.updateStack();
|
||||
// Is this entity stacked?
|
||||
boolean isStack = stack != null;
|
||||
|
||||
if (initialStack == null)
|
||||
stack.addHealth(entity.getHealth());
|
||||
// The amount that is stackable.
|
||||
int amountToStack = isStack ? stack.getAmount() : 1;
|
||||
|
||||
// Attempt to split our stack. If the split is successful then skip this entity.
|
||||
if (isStack && attemptSplit(stack, livingEntity)) return;
|
||||
|
||||
// If this entity is named or disabled then skip it.
|
||||
if (!isStack && livingEntity.getCustomName() != null
|
||||
|| !configurationSection.getBoolean("Mobs." + livingEntity.getType().name() + ".Enabled"))
|
||||
return;
|
||||
|
||||
// Get the minimum stack size.
|
||||
int minEntityStackSize = Setting.MIN_STACK_ENTITIES.getInt();
|
||||
// Get the maximum stack size for this entity.
|
||||
int maxEntityStackSize = getEntityStackSize(livingEntity);
|
||||
|
||||
// Get similar entities around our entity and make sure those entities are both compatible and stackable.
|
||||
List<LivingEntity> stackableFriends = Methods.getSimilarEntitiesAroundEntity(livingEntity)
|
||||
.stream().filter(this::isEntityStackable).collect(Collectors.toList());
|
||||
|
||||
// Loop through our similar stackable entities.
|
||||
for (LivingEntity entity : stackableFriends) {
|
||||
// Make sure the entity has not already been processed.
|
||||
if (this.processed.contains(entity.getUniqueId())) continue;
|
||||
|
||||
// Get this entities friendStack.
|
||||
EntityStack friendStack = stackManager.getStack(entity);
|
||||
|
||||
// Check to see if this entity is stacked and friendStack plus
|
||||
// our amount to stack is not above our max friendStack size
|
||||
// for this entity.
|
||||
if (friendStack != null && (friendStack.getAmount() + amountToStack) <= maxEntityStackSize) {
|
||||
|
||||
// Add one to the found friendStack.
|
||||
friendStack.addAmount(amountToStack);
|
||||
|
||||
// Add our entities health to the friendStacks health.
|
||||
friendStack.addHealth(entity.getHealth());
|
||||
|
||||
// Fix the friendStacks health.
|
||||
if (!isStack)
|
||||
friendStack.addHealth(entity.getHealth());
|
||||
else
|
||||
stack.mergeHealth(initialStack);
|
||||
friendStack.mergeHealth(stack);
|
||||
|
||||
removed.add(initialEntity.getUniqueId());
|
||||
|
||||
fixHealth(entity, initialEntity);
|
||||
fixHealth(entity, livingEntity);
|
||||
if (Setting.STACK_ENTITY_HEALTH.getBoolean())
|
||||
entity.setHealth(entity.getMaxHealth() < initialEntity.getHealth()
|
||||
? entity.getMaxHealth() : initialEntity.getHealth());
|
||||
entity.setHealth(entity.getMaxHealth() < livingEntity.getHealth()
|
||||
? entity.getMaxHealth() : livingEntity.getHealth());
|
||||
|
||||
initialEntity.remove();
|
||||
|
||||
return true;
|
||||
} else if (stack == null
|
||||
&& initialStack != null
|
||||
&& (initialStack.getAmount() + 1) <= maxEntityStackSize
|
||||
// Remove our entity and mark it as processed.
|
||||
livingEntity.remove();
|
||||
processed.add(livingEntity.getUniqueId());
|
||||
|
||||
return;
|
||||
} else if (friendStack == null
|
||||
&& isStack
|
||||
&& (stack.getAmount() + 1) <= maxEntityStackSize
|
||||
&& Methods.canFly(entity)
|
||||
&& Setting.ONLY_STACK_FLYING_DOWN.getBoolean()
|
||||
&& initialEntity.getLocation().getY() > entity.getLocation().getY()) {
|
||||
EntityStack newStack = stackManager.addStack(entity, initialStack.getAmount() + 1);
|
||||
&& livingEntity.getLocation().getY() > entity.getLocation().getY()) {
|
||||
|
||||
newStack.mergeHealth(initialStack);
|
||||
// If entity has a custom name skip it.
|
||||
if (entity.getCustomName() != null) continue;
|
||||
|
||||
newStack.addHealth(initialEntity.getHealth());
|
||||
removed.add(initialEntity.getUniqueId());
|
||||
// Create a new stack with the current stacks amount and add one to it.
|
||||
EntityStack newStack = stackManager.addStack(entity, stack.getAmount() + 1);
|
||||
|
||||
fixHealth(initialEntity, entity);
|
||||
// Fix the entities health.
|
||||
newStack.mergeHealth(stack);
|
||||
newStack.addHealth(livingEntity.getHealth());
|
||||
fixHealth(livingEntity, entity);
|
||||
if (Setting.STACK_ENTITY_HEALTH.getBoolean())
|
||||
entity.setHealth(entity.getHealth());
|
||||
|
||||
stackManager.removeStack(initialEntity);
|
||||
initialEntity.remove();
|
||||
// Remove our entities stack from the stack manager.
|
||||
stackManager.removeStack(livingEntity);
|
||||
|
||||
return true;
|
||||
// Remove our entity and mark it as processed.
|
||||
livingEntity.remove();
|
||||
processed.add(livingEntity.getUniqueId());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (initialStack != null) return false;
|
||||
// If our entity is stacked then skip this entity.
|
||||
if (isStack) return;
|
||||
|
||||
entityList.removeIf(stackManager::isStacked);
|
||||
// Remove all stacked entities from our stackable friends.
|
||||
stackableFriends.removeIf(stackManager::isStacked);
|
||||
|
||||
if (entityList.size() < minEntityStackAmount - 1
|
||||
|| minEntityStackAmount > maxEntityStackSize
|
||||
|| minEntityStackAmount == 1 && entityList.size() == 0) return false;
|
||||
// If there are none or not enough stackable friends left to create a new entity,
|
||||
// the stack sizes overlap then skip this entity.
|
||||
if (stackableFriends.isEmpty()
|
||||
|| stackableFriends.size() < minEntityStackSize - 1
|
||||
|| minEntityStackSize > maxEntityStackSize) return;
|
||||
|
||||
//If stack was never found make a new one.
|
||||
EntityStack stack = stackManager.addStack(new EntityStack(initialEntity, (entityList.size() + 1) >
|
||||
maxEntityStackSize ? maxEntityStackSize : entityList.size() + 1));
|
||||
// If a stack was never found create a new one.
|
||||
EntityStack newStack = stackManager.addStack(new EntityStack(livingEntity, (stackableFriends.size() + 1) >
|
||||
maxEntityStackSize ? maxEntityStackSize : stackableFriends.size() + 1));
|
||||
|
||||
entityList.stream().filter(entity -> !stackManager.isStacked(entity)
|
||||
&& !removed.contains(entity.getUniqueId())).limit(maxEntityStackSize).forEach(entity -> {
|
||||
// Loop through the unstacked and unprocessed stackable friends while not creating
|
||||
// a stack larger than the maximum.
|
||||
stackableFriends.stream().filter(entity -> !stackManager.isStacked(entity)
|
||||
&& !this.processed.contains(entity.getUniqueId())).limit(maxEntityStackSize).forEach(entity -> {
|
||||
|
||||
fixHealth(initialEntity, entity);
|
||||
stack.addHealth(entity.getHealth());
|
||||
// Fix the entities health.
|
||||
fixHealth(livingEntity, entity);
|
||||
newStack.addHealth(entity.getHealth());
|
||||
|
||||
removed.add(entity.getUniqueId());
|
||||
// Remove our entity and mark it as processed.
|
||||
entity.remove();
|
||||
processed.add(entity.getUniqueId());
|
||||
});
|
||||
updateHealth(stack);
|
||||
|
||||
stack.updateStack();
|
||||
return false;
|
||||
// Update our stacks health.
|
||||
updateHealth(newStack);
|
||||
|
||||
// Update our stack.
|
||||
newStack.updateStack();
|
||||
}
|
||||
|
||||
private void updateHealth(EntityStack stack) {
|
||||
if (Setting.STACK_ENTITY_HEALTH.getBoolean())
|
||||
stack.updateHealth(stack.getEntity());
|
||||
}
|
||||
|
||||
public void attemptSplit(EntityStack stack, LivingEntity entity) {
|
||||
@ -194,13 +252,18 @@ public class StackingTask extends BukkitRunnable {
|
||||
entity.remove();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void fixHealth(LivingEntity entity, LivingEntity initialEntity) {
|
||||
if (!Setting.STACK_ENTITY_HEALTH.getBoolean() && Setting.CARRY_OVER_LOWEST_HEALTH.getBoolean() && initialEntity.getHealth() < entity.getHealth())
|
||||
entity.setHealth(initialEntity.getHealth());
|
||||
}
|
||||
|
||||
private void updateHealth(EntityStack stack) {
|
||||
if (Setting.STACK_ENTITY_HEALTH.getBoolean())
|
||||
stack.updateHealth(stack.getEntity());
|
||||
private int getEntityStackSize(LivingEntity initialEntity) {
|
||||
int maxEntityStackSize = Setting.MAX_STACK_ENTITIES.getInt();
|
||||
if (configurationSection.getInt("Mobs." + initialEntity.getType().name() + ".Max Stack Size") != -1)
|
||||
maxEntityStackSize = configurationSection.getInt("Mobs." + initialEntity.getType().name() + ".Max Stack Size");
|
||||
return maxEntityStackSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user