use of dev.rosewood.rosestacker.event.EntityStackEvent in project RoseStacker by Rosewood-Development.
the class StackingThread method tryStackEntity.
/**
* Tries to stack a StackedEntity with all other StackedEntities
*
* @param stackedEntity the StackedEntity to try to stack
*/
private void tryStackEntity(StackedEntity stackedEntity) {
EntityStackSettings stackSettings = stackedEntity.getStackSettings();
if (stackSettings == null)
return;
if (stackedEntity.checkNPC()) {
this.removeEntityStack(stackedEntity);
return;
}
LivingEntity entity = stackedEntity.getEntity();
if (this.isRemoved(entity))
return;
if (!WorldGuardHook.testLocation(entity.getLocation()))
return;
Collection<Entity> nearbyEntities;
Predicate<Entity> predicate = x -> x.getType() == entity.getType();
if (!Setting.ENTITY_MERGE_ENTIRE_CHUNK.getBoolean()) {
nearbyEntities = this.entityCacheManager.getNearbyEntities(entity.getLocation(), stackSettings.getMergeRadius(), predicate);
} else {
nearbyEntities = this.entityCacheManager.getEntitiesInChunk(entity.getLocation(), predicate);
}
Set<StackedEntity> targetEntities = new HashSet<>();
targetEntities.add(stackedEntity);
for (Entity otherEntity : nearbyEntities) {
if (entity == otherEntity || this.isRemoved(otherEntity))
continue;
StackedEntity other = this.stackedEntities.get(otherEntity.getUniqueId());
if (other == null)
continue;
if (stackSettings.testCanStackWith(stackedEntity, other, false) && (!Setting.ENTITY_REQUIRE_LINE_OF_SIGHT.getBoolean() || EntityUtils.hasLineOfSight(entity, otherEntity, 0.75, false)) && WorldGuardHook.testLocation(otherEntity.getLocation()))
targetEntities.add(other);
}
StackedEntity increased;
int totalSize;
List<StackedEntity> removable = new ArrayList<>(targetEntities.size());
if (!Setting.ENTITY_MIN_STACK_COUNT_ONLY_INDIVIDUALS.getBoolean()) {
increased = targetEntities.stream().max(StackedEntity::compareTo).orElse(stackedEntity);
targetEntities.remove(increased);
totalSize = increased.getStackSize();
for (StackedEntity target : targetEntities) {
if (totalSize + target.getStackSize() <= stackSettings.getMaxStackSize()) {
totalSize += target.getStackSize();
removable.add(target);
}
}
} else {
increased = stackedEntity;
targetEntities.remove(increased);
totalSize = 1;
int totalStackSize = increased.getStackSize();
for (StackedEntity target : targetEntities) {
if (totalStackSize + target.getStackSize() <= stackSettings.getMaxStackSize()) {
totalSize++;
totalStackSize += target.getStackSize();
removable.add(target);
}
}
}
if (removable.isEmpty() || totalSize < stackSettings.getMinStackSize())
return;
EntityStackEvent entityStackEvent = new EntityStackEvent(removable, increased);
Bukkit.getPluginManager().callEvent(entityStackEvent);
if (entityStackEvent.isCancelled())
return;
for (StackedEntity toStack : removable) {
stackSettings.applyStackProperties(toStack.getEntity(), increased.getEntity());
increased.increaseStackSize(toStack.getEntity());
increased.increaseStackSize(toStack.getStackedEntityNBT());
this.removeEntityStack(toStack);
}
Runnable removeTask = () -> removable.stream().map(StackedEntity::getEntity).forEach(Entity::remove);
if (Bukkit.isPrimaryThread()) {
removeTask.run();
} else {
Bukkit.getScheduler().runTask(this.rosePlugin, removeTask);
}
}
Aggregations