Performance improvements, fix for various breeding issues.

This commit is contained in:
Brianna O'Keefe 2024-03-12 14:25:22 -05:00
parent 19e0c36e1f
commit 5f556b1980
9 changed files with 150 additions and 205 deletions

View File

@ -118,6 +118,13 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.craftaro</groupId>
<artifactId>CraftaroCore</artifactId>

View File

@ -10,12 +10,10 @@ import com.craftaro.core.dependency.Dependency;
import com.craftaro.core.gui.GuiManager;
import com.craftaro.core.hooks.EntityStackerManager;
import com.craftaro.core.hooks.HologramManager;
import com.craftaro.core.hooks.HookManager;
import com.craftaro.core.hooks.ProtectionManager;
import com.craftaro.core.hooks.WorldGuardHook;
import com.craftaro.core.hooks.holograms.DecentHologramsHolograms;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.utils.TextUtils;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.ultimatestacker.api.UltimateStackerApi;
import com.craftaro.ultimatestacker.api.stack.block.BlockStack;
import com.craftaro.ultimatestacker.api.stack.block.BlockStackManager;
@ -25,13 +23,7 @@ import com.craftaro.ultimatestacker.api.stack.item.StackedItemManager;
import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStack;
import com.craftaro.ultimatestacker.api.stack.spawner.SpawnerStackManager;
import com.craftaro.ultimatestacker.api.utils.Hologramable;
import com.craftaro.ultimatestacker.commands.CommandConvert;
import com.craftaro.ultimatestacker.commands.CommandGiveSpawner;
import com.craftaro.ultimatestacker.commands.CommandLootables;
import com.craftaro.ultimatestacker.commands.CommandReload;
import com.craftaro.ultimatestacker.commands.CommandRemoveAll;
import com.craftaro.ultimatestacker.commands.CommandSettings;
import com.craftaro.ultimatestacker.commands.CommandSpawn;
import com.craftaro.ultimatestacker.commands.*;
import com.craftaro.ultimatestacker.database.migrations._1_InitialMigration;
import com.craftaro.ultimatestacker.database.migrations._2_EntityStacks;
import com.craftaro.ultimatestacker.database.migrations._3_BlockStacks;
@ -39,15 +31,7 @@ import com.craftaro.ultimatestacker.database.migrations._6_RemoveStackedEntityTa
import com.craftaro.ultimatestacker.hook.StackerHook;
import com.craftaro.ultimatestacker.hook.hooks.JobsHook;
import com.craftaro.ultimatestacker.hook.hooks.SuperiorSkyblock2Hook;
import com.craftaro.ultimatestacker.listeners.BlockListeners;
import com.craftaro.ultimatestacker.listeners.BreedListeners;
import com.craftaro.ultimatestacker.listeners.ClearLagListeners;
import com.craftaro.ultimatestacker.listeners.DeathListeners;
import com.craftaro.ultimatestacker.listeners.InteractListeners;
import com.craftaro.ultimatestacker.listeners.ShearListeners;
import com.craftaro.ultimatestacker.listeners.SheepDyeListeners;
import com.craftaro.ultimatestacker.listeners.SpawnerListeners;
import com.craftaro.ultimatestacker.listeners.TameListeners;
import com.craftaro.ultimatestacker.listeners.*;
import com.craftaro.ultimatestacker.listeners.entity.EntityCurrentListener;
import com.craftaro.ultimatestacker.listeners.entity.EntityListeners;
import com.craftaro.ultimatestacker.listeners.item.ItemCurrentListener;
@ -62,6 +46,7 @@ import com.craftaro.ultimatestacker.stackable.entity.custom.CustomEntityManager;
import com.craftaro.ultimatestacker.stackable.item.StackedItemManagerImpl;
import com.craftaro.ultimatestacker.stackable.spawner.SpawnerStackImpl;
import com.craftaro.ultimatestacker.stackable.spawner.SpawnerStackManagerImpl;
import com.craftaro.ultimatestacker.tasks.BreedingTask;
import com.craftaro.ultimatestacker.tasks.StackingTask;
import com.craftaro.ultimatestacker.utils.Async;
import org.apache.commons.lang.WordUtils;
@ -72,12 +57,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.*;
public class UltimateStacker extends SongodaPlugin {
@ -99,6 +79,7 @@ public class UltimateStacker extends SongodaPlugin {
private CommandManager commandManager;
private CustomEntityManager customEntityManager;
private StackingTask stackingTask;
private BreedingTask breedingTask;
private UltimateStackerApi API;
private SuperiorSkyblock2Hook superiorSkyblock2Hook;
private boolean instantStacking;
@ -122,9 +103,8 @@ public class UltimateStacker extends SongodaPlugin {
@Override
public void onPluginDisable() {
if (this.stackingTask != null) {
this.stackingTask.stop();
}
if (this.stackingTask != null)
this.stackingTask.cancel();
this.dataManager.saveBatchSync(this.spawnerStackManager.getStacksData());
this.dataManager.saveBatchSync(this.blockStackManager.getStacksData());
this.dataManager.shutdownNow();
@ -154,7 +134,7 @@ public class UltimateStacker extends SongodaPlugin {
new CommandGiveSpawner(this),
new CommandSpawn(this),
new CommandLootables(this),
new CommandConvert( guiManager)
new CommandConvert(guiManager)
);
PluginManager pluginManager = Bukkit.getPluginManager();
@ -248,7 +228,7 @@ public class UltimateStacker extends SongodaPlugin {
public void onDataLoad() {
if (HologramManager.isEnabled())
// Set the offset so that the holograms don't end up inside the blocks.
HologramManager.getHolograms().setPositionOffset(.5,.65,.5);
HologramManager.getHolograms().setPositionOffset(.5, .65, .5);
// Load current data.
final boolean useSpawnerHolo = Settings.SPAWNER_HOLOGRAMS.getBoolean();
@ -264,10 +244,12 @@ public class UltimateStacker extends SongodaPlugin {
}
});
//Start stacking task
if (Settings.STACK_ENTITIES.getBoolean()) {
//Start stacking task
this.breedingTask = new BreedingTask(this);
this.stackingTask = new StackingTask(this);
}
this.instantStacking = Settings.STACK_ENTITIES.getBoolean() && Settings.INSTANT_STACKING.getBoolean();
final boolean useBlockHolo = Settings.BLOCK_HOLOGRAMS.getBoolean();
this.dataManager.loadBatch(BlockStackImpl.class, "blocks").forEach((data) -> {
@ -275,9 +257,8 @@ public class UltimateStacker extends SongodaPlugin {
this.blockStackManager.addBlock(blockStack);
if (useBlockHolo) {
if (blockStack == null) return;
if (blockStack.getLocation().getWorld() != null) {
if (blockStack.getLocation().getWorld() != null)
updateHologram(blockStack);
}
}
});
}
@ -307,9 +288,9 @@ public class UltimateStacker extends SongodaPlugin {
this.setLocale(getConfig().getString("System.Language Mode"), true);
this.locale.reloadMessages();
if (stackingTask != null) {
this.stackingTask.stop();
}
if (stackingTask != null)
this.stackingTask.cancel();
if (Settings.STACK_ENTITIES.getBoolean()) {
this.stackingTask = new StackingTask(this);
}
@ -474,4 +455,8 @@ public class UltimateStacker extends SongodaPlugin {
return !whitelist.isEmpty() && !whitelist.contains(combined)
|| !blacklist.isEmpty() && blacklist.contains(combined);
}
public BreedingTask getBreedingTask() {
return breedingTask;
}
}

View File

@ -2,47 +2,38 @@ package com.craftaro.ultimatestacker.listeners;
import com.craftaro.ultimatestacker.UltimateStacker;
import com.craftaro.ultimatestacker.api.stack.entity.EntityStack;
import org.bukkit.Bukkit;
import com.craftaro.ultimatestacker.api.stack.entity.EntityStackManager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityBreedEvent;
import org.bukkit.metadata.FixedMetadataValue;
public class BreedListeners implements Listener {
private final UltimateStacker plugin;
private final EntityStackManager entityStackManager;
public BreedListeners(UltimateStacker plugin) {
this.plugin = plugin;
this.entityStackManager = plugin.getEntityStackManager();
}
@EventHandler
public void onBread(EntityBreedEvent event) {
//TODO: Fix breed. It removes a entity from the stack but not spawn a new one. (Splitting mechanic)
boolean isMotherStacked = plugin.getEntityStackManager().isStackedEntity(event.getMother());
boolean isFatherStacked = plugin.getEntityStackManager().isStackedEntity(event.getFather());
EntityStack stackedMother = entityStackManager.getStackedEntity(event.getMother());
EntityStack stackedFather = entityStackManager.getStackedEntity(event.getFather());
if (!isMotherStacked && !isFatherStacked) return;
plugin.getBreedingTask().addBreedingTicket(event.getMother(), event.getFather());
if (isMotherStacked) {
EntityStack stack = plugin.getEntityStackManager().getStackedEntity(event.getMother());
if (stackedMother != null) {
EntityStack stack = entityStackManager.getStackedEntity(event.getMother());
if (stack.getAmount() <= 1) return;
stack.releaseHost();
}
if (isFatherStacked) {
EntityStack stack = plugin.getEntityStackManager().getStackedEntity(event.getFather());
if (stackedFather != null) {
EntityStack stack = entityStackManager.getStackedEntity(event.getFather());
if (stack.getAmount() <= 1) return;
stack.releaseHost();
}
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> {
event.getFather().removeMetadata("breedCooldown", plugin);
event.getMother().removeMetadata("breedCooldown", plugin);
}, 5 * 20 * 60);
event.getFather().setMetadata("breedCooldown", new FixedMetadataValue(plugin, true));
event.getFather().removeMetadata("inLove", plugin);
event.getMother().setMetadata("breedCooldown", new FixedMetadataValue(plugin, true));
event.getMother().removeMetadata("inLove", plugin);
}
}

View File

@ -77,12 +77,10 @@ public class DeathListeners implements Listener {
List<Drop> drops = custom ? plugin.getLootablesManager().getDrops(event.getEntity())
: event.getDrops().stream().map(Drop::new).collect(Collectors.toList());
if (custom) {
for (ItemStack item : new ArrayList<>(event.getDrops())) {
if (custom)
for (ItemStack item : new ArrayList<>(event.getDrops()))
if (shouldDrop(event.getEntity(), item.getType()))
drops.add(new Drop(item));
}
}
if (plugin.getCustomEntityManager().getCustomEntity(entity) == null) {
//Run commands here, or it will be buggy

View File

@ -1,7 +1,5 @@
package com.craftaro.ultimatestacker.listeners;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.ultimatestacker.UltimateStacker;
import com.craftaro.ultimatestacker.api.stack.entity.EntityStack;
import com.craftaro.ultimatestacker.settings.Settings;
@ -58,12 +56,8 @@ public class InteractListeners implements Listener {
&& !((Ageable) entity).isAdult()) {
return;
}
entity.setMetadata("inLove", new FixedMetadataValue(plugin, true));
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
if (entity.isDead()) return;
entity.removeMetadata("inLove", plugin);
}, 20 * 20);
plugin.getBreedingTask().addInLoveTicket(entity);
}
}

View File

@ -1,12 +1,10 @@
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;
@ -14,7 +12,6 @@ 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.NamespacedKey;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
@ -27,8 +24,6 @@ import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
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;
@ -42,6 +37,7 @@ public class EntityStackImpl implements EntityStack {
/**
* Gets an existing stack from an entity or creates a new one if it doesn't exist.
*
* @param entity The entity to get the stack from.
*/
public EntityStackImpl(LivingEntity entity) {
@ -85,6 +81,7 @@ public class EntityStackImpl implements EntityStack {
/**
* Creates a new stack or overrides an existing stack.
*
* @param entity The entity to create the stack for.
* @param amount The amount of entities in the stack.
*/
@ -240,10 +237,10 @@ public class EntityStackImpl implements EntityStack {
@Override
public synchronized LivingEntity takeOneAndSpawnEntity(Location location) {
if (amount <= 0) return null;
LivingEntity entity = (LivingEntity) Objects.requireNonNull(location.getWorld()).spawnEntity(location, hostEntity.getType());
if (Settings.NO_AI.getBoolean()) {
if (Settings.NO_AI.getBoolean())
EntityUtils.setUnaware(entity);
}
this.hostEntity = entity;
setAmount(amount--);
updateNameTag();
@ -252,35 +249,28 @@ public class EntityStackImpl implements EntityStack {
@Override
public synchronized void releaseHost() {
//Remove the metadata from the entity if it's the last one
// if (getAmount() == 1) {
// if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) {
// PersistentDataContainer container = hostEntity.getPersistentDataContainer();
// container.remove(STACKED_ENTITY_KEY);
// } else {
// hostEntity.removeMetadata("US_AMOUNT", plugin);
// }
// hostEntity.setCustomName(null);
// hostEntity.setCustomNameVisible(false);
// return;
// }
wipeData();
LivingEntity oldHost = hostEntity;
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) {
PersistentDataContainer container = oldHost.getPersistentDataContainer();
container.remove(STACKED_ENTITY_KEY);
//Add new entry that the entity was split by player, not to stack it anymore
container.set(new NamespacedKey(plugin, "US_SPLIT_PLAYER"), PersistentDataType.BYTE, (byte) 1);
} else {
oldHost.removeMetadata("US_AMOUNT", plugin);
//Add new entry that the entity was split by player, not to stack it anymore
oldHost.setMetadata("US_SPLIT_PLAYER", new FixedMetadataValue(plugin, true));
}
//Summon a new entity and update the stack and remove the metadata from the old entity
//Summon a new entity, update the stack and remove the metadata from the old entity
this.hostEntity = takeOneAndSpawnEntity(hostEntity.getLocation());
setAmount(amount-1);
updateNameTag();
if (amount == 2) {
wipeData();
} else {
setAmount(amount - 1);
updateNameTag();
}
}
private synchronized void wipeData() {
hostEntity.setCustomName(null);
hostEntity.setCustomNameVisible(false);
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) {
PersistentDataContainer container = hostEntity.getPersistentDataContainer();
container.remove(STACKED_ENTITY_KEY);
} else {
hostEntity.removeMetadata("US_AMOUNT", plugin);
}
}
@Override
@ -291,9 +281,8 @@ public class EntityStackImpl implements EntityStack {
}
public void updateNameTag() {
if (hostEntity == null) {
if (hostEntity == null)
return;
}
hostEntity.setCustomNameVisible(!Settings.HOLOGRAMS_ON_LOOK_ENTITY.getBoolean());
hostEntity.setCustomName(Methods.compileEntityName(hostEntity, getAmount()));

View File

@ -0,0 +1,48 @@
package com.craftaro.ultimatestacker.tasks;
import com.craftaro.core.task.TaskScheduler;
import com.craftaro.ultimatestacker.UltimateStacker;
import org.bukkit.entity.LivingEntity;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class BreedingTask extends TaskScheduler {
private final UltimateStacker plugin;
private final Set<UUID> breedingEntities = new HashSet<>();
private final Set<UUID> inLoveEntities = new HashSet<>();
public BreedingTask(UltimateStacker plugin) {
super(plugin);
this.plugin = plugin;
}
public void addBreedingTicket(LivingEntity mother, LivingEntity father) {
UUID motherUUID = mother.getUniqueId();
UUID fatherUUID = father.getUniqueId();
addTask(() -> {
breedingEntities.remove(motherUUID);
breedingEntities.remove(fatherUUID);
}, 20L * 1000L);
breedingEntities.add(motherUUID);
inLoveEntities.remove(motherUUID);
breedingEntities.add(fatherUUID);
inLoveEntities.remove(fatherUUID);
}
public void addInLoveTicket(LivingEntity entity) {
UUID entityUUID = entity.getUniqueId();
addTask(() -> inLoveEntities.remove(entityUUID), 5L * 60L * 1000L);
inLoveEntities.add(entityUUID);
}
public boolean isInQueue(UUID uniqueId) {
return breedingEntities.contains(uniqueId) || inLoveEntities.contains(uniqueId);
}
}

View File

@ -2,8 +2,8 @@ package com.craftaro.ultimatestacker.tasks;
import com.craftaro.core.compatibility.ServerVersion;
import com.craftaro.core.hooks.WorldGuardHook;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.core.world.SWorld;
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
import com.craftaro.ultimatestacker.UltimateStacker;
import com.craftaro.ultimatestacker.api.stack.entity.EntityStack;
import com.craftaro.ultimatestacker.api.stack.entity.EntityStackManager;
@ -11,45 +11,24 @@ import com.craftaro.ultimatestacker.settings.Settings;
import com.craftaro.ultimatestacker.stackable.entity.Check;
import com.craftaro.ultimatestacker.stackable.entity.custom.CustomEntity;
import com.craftaro.ultimatestacker.utils.CachedChunk;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.*;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.*;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimerTask;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.*;
import java.util.stream.Collectors;
import static com.craftaro.ultimatestacker.stackable.entity.Check.getChecks;
public class StackingTask extends TimerTask {
public class StackingTask extends BukkitRunnable {
private final UltimateStacker plugin;
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "UltimateStacker-Stacking-Thread"));
private final EntityStackManager stackManager;
private final BreedingTask breedingTask;
private final ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile();
private final List<UUID> processed = new ArrayList<>();
@ -70,12 +49,12 @@ public class StackingTask extends TimerTask {
onlyStackOnSurface = Settings.ONLY_STACK_ON_SURFACE.getBoolean();
private final Set<SWorld> loadedWorlds;
private final NamespacedKey playerSplitKey;
public StackingTask(UltimateStacker plugin) {
this.plugin = plugin;
playerSplitKey = new NamespacedKey(plugin, "US_SPLIT_PLAYER");
this.stackManager = plugin.getEntityStackManager();
stackManager = plugin.getEntityStackManager();
breedingTask = plugin.getBreedingTask();
// Add loaded worlds.
loadedWorlds = new HashSet<>();
for (World world : Bukkit.getWorlds()) {
@ -83,12 +62,9 @@ public class StackingTask extends TimerTask {
if (isWorldDisabled(world)) continue;
loadedWorlds.add(new SWorld(world));
}
// Start the stacking task.
executorService.scheduleAtFixedRate(this, 0, (Settings.STACK_SEARCH_TICK_SPEED.getInt()*50L), TimeUnit.MILLISECONDS);
}
public void stop() {
executorService.shutdown();
int tickRate = Settings.STACK_SEARCH_TICK_SPEED.getInt();
runTaskTimer(plugin, tickRate, tickRate);
}
@Override
@ -99,42 +75,33 @@ public class StackingTask extends TimerTask {
for (SWorld sWorld : loadedWorlds) {
List<LivingEntity> entities;
// Get the loaded entities from the current world and reverse them.
try {
entities = getLivingEntitiesSync(sWorld).get();
} catch (ExecutionException | InterruptedException ex) {
ex.printStackTrace();
continue;
}
entities = sWorld.getLivingEntities();
//Filter non-stackable entities to improve performance on main thread
entities.removeIf(this::isEntityNotStackable);
for (LivingEntity entity : entities) {
// Check our WorldGuard flag.
Boolean flag = WorldGuardHook.isEnabled() ? WorldGuardHook.getBooleanFlag(entity.getLocation(), "mob-stacking") : null; //Does this work async?
if (flag != null && !flag) {
if (flag != null && !flag)
entities.removeIf(entity1 -> entity1.getUniqueId().equals(entity.getUniqueId()));
}
}
Bukkit.getScheduler().runTask(plugin, () -> {
// Loop through the entities.
for (LivingEntity entity : entities) {
// Make sure our entity has not already been processed.
// Skip it if it has been.
if (this.processed.contains(entity.getUniqueId())) continue;
// Loop through the entities.
for (LivingEntity entity : entities) {
// Make sure our entity has not already been processed.
// Skip it if it has been.
if (processed.contains(entity.getUniqueId())) continue;
// Get entity location to pass around as its faster this way.
Location location = entity.getLocation();
// Get entity location to pass around as its faster this way.
Location location = entity.getLocation();
// Process the entity.
this.processEntity(entity, location);
}
});
// Process the entity.
processEntity(entity, location, entities);
}
}
} catch (Exception ignored) {
} catch (Exception e) {
e.printStackTrace();
} finally {
// Make sure we clear the processed list.
this.processed.clear();
@ -142,18 +109,6 @@ public class StackingTask extends TimerTask {
}
}
private Future<List<LivingEntity>> getLivingEntitiesSync(SWorld sWorld) {
CompletableFuture<List<LivingEntity>> future = new CompletableFuture<>();
Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> future.complete(sWorld.getLivingEntities()));
return future;
}
private Future<Entity[]> getEntitiesInChunkSync(CachedChunk cachedChunk) {
CompletableFuture<Entity[]> future = new CompletableFuture<>();
Bukkit.getScheduler().runTask(this.plugin, () -> future.complete(cachedChunk.getEntities()));
return future;
}
public boolean isWorldDisabled(World world) {
return disabledWorlds.stream().anyMatch(worldStr -> world.getName().equalsIgnoreCase(worldStr));
}
@ -162,23 +117,17 @@ public class StackingTask extends TimerTask {
private boolean isEntityNotStackable(LivingEntity entity) {
if (isMaxStack(entity)) return true;
if (isPersistentSplit(entity)) return true;
// Make sure we have the correct entity type and that it is valid.
if (!entity.isValid()
|| entity instanceof HumanEntity
|| entity instanceof ArmorStand
// Make sure the entity is not in love.
|| entity.hasMetadata("inLove")
// Or in breeding cooldown.
|| entity.hasMetadata("breedCooldown")) {
// Make sure the entity is not in love or in the breeding queue.
|| breedingTask.isInQueue(entity.getUniqueId()))
return true;
}
if (!configurationSection.getBoolean("Mobs." + entity.getType().name() + ".Enabled")) {
if (!configurationSection.getBoolean("Mobs." + entity.getType().name() + ".Enabled"))
return true;
}
// Allow spawn if stack reasons are set and match, or if from a spawner
final String spawnReason = entity.hasMetadata("US_REASON") && !entity.getMetadata("US_REASON").isEmpty()
@ -186,9 +135,8 @@ public class StackingTask extends TimerTask {
List<String> stackReasons;
if (onlyStackFromSpawners) {
// If only stack from spawners is enabled, make sure the entity spawned from a spawner.
if (!"SPAWNER".equals(spawnReason)) {
if (!"SPAWNER".equals(spawnReason))
return true;
}
} else if (!(stackReasons = this.stackReasons).isEmpty() && !stackReasons.contains(spawnReason)) {
// Only stack if on the list of events to stack
return true;
@ -199,7 +147,7 @@ public class StackingTask extends TimerTask {
return onlyStackOnSurface && canFly(entity) && !entity.getType().name().equals("SHULKER") && !entity.isOnGround() && !(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) && (entity).isSwimming());
}
private void processEntity(LivingEntity baseEntity, Location location) {
private void processEntity(LivingEntity baseEntity, Location location, List<LivingEntity> entities) {
// Get the stack from the entity. It should be noted that this value will
// be null if our entity is not a stack.
EntityStack baseStack = plugin.getEntityStackManager().getStackedEntity(baseEntity);
@ -236,9 +184,8 @@ public class StackingTask extends TimerTask {
// Loop through our similar stackable entities.
for (LivingEntity friendlyEntity : stackableFriends) {
if (isPersistentSplit(friendlyEntity)) {
if (!entities.contains(friendlyEntity))
continue;
}
// Process similar entities.
EntityStack friendStack = stackManager.getStackedEntity(friendlyEntity);
@ -271,7 +218,8 @@ public class StackingTask extends TimerTask {
/**
* This method splitting overstacked entities into new stacks.
* Must be called synchronously.
* @param baseStack The base stack to check for splitting.
*
* @param baseStack The base stack to check for splitting.
* @param maxEntityStackSize The maximum stack size for the entity. -1 if we need to calculate it.
* @return True if the split was successful, false otherwise.
*/
@ -336,12 +284,13 @@ public class StackingTask extends TimerTask {
/**
* Get all entities around an entity within a radius which are similar to the entity.
*
* @param entity The entity to get similar entities around.
* @return A list of similar entities around the entity.
*/
public List<LivingEntity> getFriendlyStacksNearby(LivingEntity entity) {
if (!stackWholeChunk) {
return entity.getNearbyEntities(searchRadius/2.0, searchRadius/2.0, searchRadius/2.0)
return entity.getNearbyEntities(searchRadius / 2.0, searchRadius / 2.0, searchRadius / 2.0)
.stream().filter(e -> e.getType() == entity.getType() && !isMaxStack((LivingEntity) e))
.map(e -> (LivingEntity) e).collect(Collectors.toList());
}
@ -708,22 +657,6 @@ public class StackingTask extends TimerTask {
return stack.getAmount() >= getEntityMaxStackSize(livingEntity);
}
private boolean isPersistentSplit(LivingEntity entity) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) {
PersistentDataContainer container = entity.getPersistentDataContainer();
if (container.has(playerSplitKey, PersistentDataType.BYTE)) {
processed.add(entity.getUniqueId());
return true;
}
} else {
if (entity.hasMetadata("US_SPLIT_PLAYER")) {
processed.add(entity.getUniqueId());
return true;
}
}
return false;
}
public boolean canFly(LivingEntity entity) {
switch (entity.getType()) {
case GHAST:

View File

@ -19,7 +19,7 @@
<url>https://craftaro.com/marketplace/product/16</url>
<properties>
<craftaro.coreVersion>3.0.0-SNAPSHOT</craftaro.coreVersion>
<craftaro.coreVersion>3.0.1-SNAPSHOT</craftaro.coreVersion>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.target>1.8</maven.compiler.target>