Performance improvements, fix for various breeding issues.
This commit is contained in:
parent
19e0c36e1f
commit
5f556b1980
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue