Added the optional ability to stack entity health. Perfect for grinders.

This commit is contained in:
Brianna 2019-06-29 19:32:16 -04:00
parent c2d5a0082e
commit 43eba6e59d
6 changed files with 73 additions and 16 deletions

View File

@ -15,6 +15,8 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
import java.util.UUID;
@ -23,8 +25,11 @@ public class EntityStack {
private UUID entity;
private int amount;
public EntityStack(Entity entity, int amount) {
private Deque<Double> health = new ArrayDeque<>();
public EntityStack(LivingEntity entity, int amount) {
this(entity.getUniqueId(), amount);
health.add(entity.getHealth());
}
public EntityStack(UUID uuid, int amount) {
@ -46,8 +51,8 @@ public class EntityStack {
}
public Entity getEntity() {
Entity entity = getEntityByUniqueId(this.entity);
public LivingEntity getEntity() {
LivingEntity entity = getEntityByUniqueId(this.entity);
if (entity == null) {
UltimateStacker.getInstance().getEntityStackManager().removeStack(this.entity);
return null;
@ -87,14 +92,14 @@ public class EntityStack {
updateStack();
}
public Entity getEntityByUniqueId(UUID uniqueId) {
private LivingEntity getEntityByUniqueId(UUID uniqueId) {
if (UltimateStacker.getInstance().isServerVersionAtLeast(ServerVersion.V1_12))
return Bukkit.getEntity(uniqueId);
return (LivingEntity) Bukkit.getEntity(uniqueId);
for (World world : Bukkit.getWorlds()) {
for (Entity entity : world.getEntities()) {
if (entity.getUniqueId().equals(uniqueId))
return entity;
return (LivingEntity) entity;
}
}
@ -126,6 +131,8 @@ public class EntityStack {
EntityStackManager stackManager = instance.getEntityStackManager();
LivingEntity newEntity = Methods.newEntity(killed);
updateHealth(newEntity);
newEntity.getEquipment().clear();
if (killed.getType() == EntityType.PIG_ZOMBIE)
@ -169,6 +176,27 @@ public class EntityStack {
}
}
public void updateHealth(LivingEntity entity) {
entity.setHealth(Setting.STACK_ENTITY_HEALTH.getBoolean()
&& !this.health.isEmpty() ? this.health.removeFirst() : entity.getMaxHealth());
}
public void addHealth(double health) {
this.health.addLast(health);
}
public void mergeHealth(EntityStack stack) {
this.health.addAll(stack.getHealthDeque());
}
public Deque<Double> getHealthDeque() {
return new ArrayDeque<>(health);
}
public void setHealthDeque(Deque<Double> health) {
this.health = health;
}
@Override
public String toString() {
return "EntityStack:{"

View File

@ -24,7 +24,9 @@ public class EntityStackManager {
}
public EntityStack addStack(UUID uuid, int amount) {
return stacks.put(uuid, new EntityStack(uuid, amount));
EntityStack stack = new EntityStack(uuid, amount);
stacks.put(uuid, new EntityStack(uuid, amount));
return stack;
}
public EntityStack addSerializedStack(Entity entity, String customName) {

View File

@ -36,7 +36,7 @@ public class TameListeners implements Listener {
if (stack.getAmount() <= 1) return;
Entity newEntity = Methods.newEntity((LivingEntity) tameable);
LivingEntity newEntity = Methods.newEntity((LivingEntity) tameable);
instance.getEntityStackManager().addStack(new EntityStack(newEntity, stack.getAmount() - 1));
stack.setAmount(1);

View File

@ -48,8 +48,7 @@ public class StackingTask extends BukkitRunnable {
Collections.reverse(entities);
for (Entity entityO : entities) {
if (entityO == null
|| !(entityO instanceof LivingEntity)
if (!(entityO instanceof LivingEntity)
|| entityO instanceof Player
|| !entityO.isValid()
|| !Setting.STACK_ENTITIES.getBoolean())
@ -116,9 +115,16 @@ public class StackingTask extends BukkitRunnable {
if (stack != null && (stack.getAmount() + amtToStack) <= maxEntityStackSize) {
stack.addAmount(amtToStack);
stack.updateStack();
if (initialStack == null)
stack.addHealth(initialEntity.getHealth());
else
stack.mergeHealth(initialStack);
removed.add(initialEntity.getUniqueId());
fixHealth(entity, initialEntity);
updateHealth(stack);
initialEntity.remove();
@ -129,11 +135,16 @@ public class StackingTask extends BukkitRunnable {
&& Methods.canFly(entity)
&& Setting.ONLY_STACK_FLYING_DOWN.getBoolean()
&& initialEntity.getLocation().getY() > entity.getLocation().getY()) {
stackManager.addStack(entity, initialStack.getAmount() + 1);
EntityStack newStack = stackManager.addStack(entity, initialStack.getAmount() + 1);
newStack.setHealthDeque(initialStack.getHealthDeque());
newStack.addHealth(entity.getHealth());
removed.add(initialEntity.getUniqueId());
fixHealth(initialEntity, entity);
updateHealth(newStack);
stackManager.removeStack(initialEntity);
initialEntity.remove();
return true;
@ -156,18 +167,25 @@ public class StackingTask extends BukkitRunnable {
&& !removed.contains(entity.getUniqueId())).limit(maxEntityStackSize).forEach(entity -> {
fixHealth(initialEntity, entity);
stack.addHealth(entity.getHealth());
removed.add(entity.getUniqueId());
entity.remove();
});
updateHealth(stack);
stack.updateStack();
return false;
}
private void fixHealth(LivingEntity entity, LivingEntity initialEntity) {
if (Setting.CARRY_OVER_LOWEST_HEALTH.getBoolean() && initialEntity.getHealth() < entity.getHealth())
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());
}
}

View File

@ -27,6 +27,7 @@ public class Methods {
case GHAST:
case BLAZE:
case PHANTOM:
case BAT:
return true;
default:
return false;
@ -424,7 +425,7 @@ public class Methods {
if (stack.getAmount() <= 1) return;
Entity newEntity = Methods.newEntity(entity);
LivingEntity newEntity = Methods.newEntity(entity);
int newAmount = stack.getAmount() - 1;
if (newAmount != 1)

View File

@ -85,8 +85,10 @@ public enum Setting {
KEEP_POTION("Entities.Keep Potion Effects", true,
"Should potion effects persist to the next entity when an entity dies?"),
CARRY_OVER_LOWEST_HEALTH("Entities.Carry Over Lowest Health", true,
"Should the lowest health be carried over when stacked?"),
CARRY_OVER_LOWEST_HEALTH("Entities.Carry Over Lowest Health", false,
"Should the lowest health be carried over when stacked?",
"This should not be used in collaboration with 'Stack Entity Health'.",
"If it is used this setting will be overrode."),
ONLY_STACK_FROM_SPAWNERS("Entities.Only Stack From Spawners", false,
"Should entities only be stacked if they originate from a spawner?",
@ -94,10 +96,16 @@ public enum Setting {
"if the entity originated from a spawner or not is wiped on",
"server restart."),
ONLY_STACK_ON_SURFACE("Entities.Only Stack On Surface", false,
ONLY_STACK_ON_SURFACE("Entities.Only Stack On Surface", true,
"Should entities only be stacked if they are touching the ground",
"or swimming? This does not effect flying entities."),
STACK_ENTITY_HEALTH("Main.Stack Entity Health", true,
"Should entity health be stacked? When enabled Entity stacks will",
"remember the health of all entities inside of the stack. This",
"works the best with 'Only Stack On Surface enabled' as entities",
"falling out of grinders may stack before hitting the ground."),
ONLY_STACK_FLYING_DOWN("Entities.Only Stack Flying Down", true,
"Should entities that fly only stack with entities that are lower on the",
"Y axis. This is important for grinders so that flying entities don't continuously",