mirror of
https://github.com/songoda/UltimateStacker.git
synced 2024-11-27 12:35:17 +01:00
1.17 Support.
This commit is contained in:
parent
c9ee85c85a
commit
8638d1a127
@ -3,6 +3,7 @@ package com.songoda.ultimatestacker.tasks;
|
|||||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||||
import com.songoda.core.compatibility.ServerVersion;
|
import com.songoda.core.compatibility.ServerVersion;
|
||||||
import com.songoda.core.hooks.WorldGuardHook;
|
import com.songoda.core.hooks.WorldGuardHook;
|
||||||
|
import com.songoda.core.world.SWorld;
|
||||||
import com.songoda.ultimatestacker.UltimateStacker;
|
import com.songoda.ultimatestacker.UltimateStacker;
|
||||||
import com.songoda.ultimatestacker.settings.Settings;
|
import com.songoda.ultimatestacker.settings.Settings;
|
||||||
import com.songoda.ultimatestacker.stackable.entity.Check;
|
import com.songoda.ultimatestacker.stackable.entity.Check;
|
||||||
@ -55,10 +56,16 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
onlyStackFromSpawners = Settings.ONLY_STACK_FROM_SPAWNERS.getBoolean(),
|
onlyStackFromSpawners = Settings.ONLY_STACK_FROM_SPAWNERS.getBoolean(),
|
||||||
onlyStackOnSurface = Settings.ONLY_STACK_ON_SURFACE.getBoolean();
|
onlyStackOnSurface = Settings.ONLY_STACK_ON_SURFACE.getBoolean();
|
||||||
|
|
||||||
|
Set<SWorld> loadedWorlds = new HashSet<>();
|
||||||
|
|
||||||
public StackingTask(UltimateStacker plugin) {
|
public StackingTask(UltimateStacker plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.stackManager = plugin.getEntityStackManager();
|
this.stackManager = plugin.getEntityStackManager();
|
||||||
|
|
||||||
|
// Add loaded worlds.
|
||||||
|
for (World world : Bukkit.getWorlds())
|
||||||
|
loadedWorlds.add(new SWorld(world));
|
||||||
|
|
||||||
// Start the stacking task.
|
// Start the stacking task.
|
||||||
runTaskTimerAsynchronously(plugin, 0, Settings.STACK_SEARCH_TICK_SPEED.getInt());
|
runTaskTimerAsynchronously(plugin, 0, Settings.STACK_SEARCH_TICK_SPEED.getInt());
|
||||||
}
|
}
|
||||||
@ -69,15 +76,14 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
if (!Settings.STACK_ENTITIES.getBoolean()) return;
|
if (!Settings.STACK_ENTITIES.getBoolean()) return;
|
||||||
|
|
||||||
// Loop through each world.
|
// Loop through each world.
|
||||||
for (World world : Bukkit.getWorlds()) {
|
for (SWorld sWorld : loadedWorlds) {
|
||||||
// If world is disabled then continue to the next world.
|
// If world is disabled then continue to the next world.
|
||||||
|
if (isWorldDisabled(sWorld.getWorld())) continue;
|
||||||
if (isWorldDisabled(world)) continue;
|
|
||||||
|
|
||||||
// Get the loaded entities from the current world and reverse them.
|
// Get the loaded entities from the current world and reverse them.
|
||||||
List<Entity> entities;
|
List<LivingEntity> entities;
|
||||||
try {
|
try {
|
||||||
entities = new ArrayList<>(world.getEntities());
|
entities = sWorld.getLivingEntities();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
continue;
|
continue;
|
||||||
// Sometimes accessing this method asynchronously throws an error. This is super rare and
|
// Sometimes accessing this method asynchronously throws an error. This is super rare and
|
||||||
@ -86,7 +92,7 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
Collections.reverse(entities);
|
Collections.reverse(entities);
|
||||||
|
|
||||||
// Loop through the entities.
|
// Loop through the entities.
|
||||||
for (Entity entity : entities) {
|
for (LivingEntity entity : entities) {
|
||||||
// Get entity location to pass around as its faster this way.
|
// Get entity location to pass around as its faster this way.
|
||||||
Location location = entity.getLocation();
|
Location location = entity.getLocation();
|
||||||
|
|
||||||
@ -98,12 +104,8 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
// Skip it if it has been.
|
// Skip it if it has been.
|
||||||
if (this.processed.contains(entity.getUniqueId())) continue;
|
if (this.processed.contains(entity.getUniqueId())) continue;
|
||||||
|
|
||||||
// Cast our entity to living entity.
|
|
||||||
LivingEntity livingEntity = (LivingEntity) entity;
|
|
||||||
|
|
||||||
// Process the entity.
|
// Process the entity.
|
||||||
this.processEntity(livingEntity, location);
|
this.processEntity(entity, sWorld, location);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear caches in preparation for the next run.
|
// Clear caches in preparation for the next run.
|
||||||
@ -118,7 +120,6 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
private boolean isEntityStackable(Entity entity) {
|
private boolean isEntityStackable(Entity entity) {
|
||||||
// Make sure we have the correct entity type and that it is valid.
|
// Make sure we have the correct entity type and that it is valid.
|
||||||
if (!entity.isValid()
|
if (!entity.isValid()
|
||||||
|| !(entity instanceof LivingEntity)
|
|
||||||
|| entity instanceof HumanEntity
|
|| entity instanceof HumanEntity
|
||||||
|| entity instanceof ArmorStand
|
|| entity instanceof ArmorStand
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processEntity(LivingEntity livingEntity, Location location) {
|
private void processEntity(LivingEntity livingEntity, SWorld sWorld, Location location) {
|
||||||
// Get the stack from the entity. It should be noted that this value will
|
// Get the stack from the entity. It should be noted that this value will
|
||||||
// be null if our entity is not a stack.
|
// be null if our entity is not a stack.
|
||||||
EntityStack stack = plugin.getEntityStackManager().getStack(livingEntity);
|
EntityStack stack = plugin.getEntityStackManager().getStack(livingEntity);
|
||||||
@ -179,7 +180,7 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
|
|
||||||
// Get similar entities around our entity and make sure those entities are both compatible and stackable.
|
// Get similar entities around our entity and make sure those entities are both compatible and stackable.
|
||||||
List<LivingEntity> stackableFriends = new LinkedList<>();
|
List<LivingEntity> stackableFriends = new LinkedList<>();
|
||||||
for (LivingEntity entity : getSimilarEntitiesAroundEntity(livingEntity, location)) {
|
for (LivingEntity entity : getSimilarEntitiesAroundEntity(livingEntity, sWorld, location)) {
|
||||||
// Check to see if entity is not stackable.
|
// Check to see if entity is not stackable.
|
||||||
if (!isEntityStackable(entity))
|
if (!isEntityStackable(entity))
|
||||||
continue;
|
continue;
|
||||||
@ -228,7 +229,7 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
if (livingEntity.isLeashed())
|
if (livingEntity.isLeashed())
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> livingEntity.getWorld()
|
Bukkit.getScheduler().runTask(plugin, () -> livingEntity.getWorld()
|
||||||
.dropItemNaturally(livingEntity.getLocation(), CompatibleMaterial.LEAD.getItem()));
|
.dropItemNaturally(livingEntity.getLocation(), CompatibleMaterial.LEAD.getItem()));
|
||||||
livingEntity.remove();
|
Bukkit.getScheduler().runTask(plugin, livingEntity::remove);
|
||||||
processed.add(livingEntity.getUniqueId());
|
processed.add(livingEntity.getUniqueId());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -246,7 +247,7 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
plugin.getDataManager().createStackedEntity(newStack, newStack.addEntityToStack(livingEntity));
|
plugin.getDataManager().createStackedEntity(newStack, newStack.addEntityToStack(livingEntity));
|
||||||
|
|
||||||
// Remove our entity and mark it as processed.
|
// Remove our entity and mark it as processed.
|
||||||
livingEntity.remove();
|
Bukkit.getScheduler().runTask(plugin, livingEntity::remove);
|
||||||
processed.add(livingEntity.getUniqueId());
|
processed.add(livingEntity.getUniqueId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -265,8 +266,8 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
|
|
||||||
// If the stack cap is met then delete this entity.
|
// If the stack cap is met then delete this entity.
|
||||||
if (maxPerTypeStacksPerChunk != -1
|
if (maxPerTypeStacksPerChunk != -1
|
||||||
&& (getSimilarStacksInChunk(livingEntity) + 1) > maxPerTypeStacksPerChunk) {
|
&& (getSimilarStacksInChunk(sWorld, livingEntity) + 1) > maxPerTypeStacksPerChunk) {
|
||||||
livingEntity.remove();
|
Bukkit.getScheduler().runTask(plugin, livingEntity::remove);
|
||||||
this.processed.add(livingEntity.getUniqueId());
|
this.processed.add(livingEntity.getUniqueId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -299,7 +300,7 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
if (entity.isLeashed())
|
if (entity.isLeashed())
|
||||||
entity.getWorld().dropItemNaturally(entity.getLocation(), CompatibleMaterial.LEAD.getItem());
|
entity.getWorld().dropItemNaturally(entity.getLocation(), CompatibleMaterial.LEAD.getItem());
|
||||||
livingEntities.add(entity);
|
livingEntities.add(entity);
|
||||||
entity.remove();
|
Bukkit.getScheduler().runTask(plugin, entity::remove);
|
||||||
processed.add(entity.getUniqueId());
|
processed.add(entity.getUniqueId());
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -332,17 +333,17 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Remove our entity and mark it as processed.
|
// Remove our entity and mark it as processed.
|
||||||
livingEntity.remove();
|
Bukkit.getScheduler().runTask(plugin, livingEntity::remove);
|
||||||
processed.add(livingEntity.getUniqueId());
|
processed.add(livingEntity.getUniqueId());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<CachedChunk> getNearbyChunks(Location location, double radius, boolean singleChunk) {
|
private Set<CachedChunk> getNearbyChunks(SWorld sWorld, Location location, double radius, boolean singleChunk) {
|
||||||
World world = location.getWorld();
|
World world = location.getWorld();
|
||||||
Set<CachedChunk> chunks = new HashSet<>();
|
Set<CachedChunk> chunks = new HashSet<>();
|
||||||
if (world == null) return chunks;
|
if (world == null) return chunks;
|
||||||
|
|
||||||
CachedChunk firstChunk = new CachedChunk(location);
|
CachedChunk firstChunk = new CachedChunk(sWorld, location);
|
||||||
chunks.add(firstChunk);
|
chunks.add(firstChunk);
|
||||||
|
|
||||||
if (singleChunk) return chunks;
|
if (singleChunk) return chunks;
|
||||||
@ -355,15 +356,15 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
for (int x = minX; x <= maxX; ++x) {
|
for (int x = minX; x <= maxX; ++x) {
|
||||||
for (int z = minZ; z <= maxZ; ++z) {
|
for (int z = minZ; z <= maxZ; ++z) {
|
||||||
if (firstChunk.getX() == x && firstChunk.getZ() == z) continue;
|
if (firstChunk.getX() == x && firstChunk.getZ() == z) continue;
|
||||||
chunks.add(new CachedChunk(world.getName(), x, z));
|
chunks.add(new CachedChunk(sWorld, x, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LivingEntity> getNearbyEntities(Location location, double radius, boolean singleChunk) {
|
private List<LivingEntity> getNearbyEntities(SWorld sWorld, Location location, double radius, boolean singleChunk) {
|
||||||
List<LivingEntity> entities = new ArrayList<>();
|
List<LivingEntity> entities = new ArrayList<>();
|
||||||
for (CachedChunk chunk : getNearbyChunks(location, radius, singleChunk)) {
|
for (CachedChunk chunk : getNearbyChunks(sWorld, location, radius, singleChunk)) {
|
||||||
if (chunk == null) continue;
|
if (chunk == null) continue;
|
||||||
Entity[] entityArray = new Entity[0];
|
Entity[] entityArray = new Entity[0];
|
||||||
if (cachedChunks.containsKey(chunk)) {
|
if (cachedChunks.containsKey(chunk)) {
|
||||||
@ -389,20 +390,20 @@ public class StackingTask extends BukkitRunnable {
|
|||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSimilarStacksInChunk(LivingEntity entity) {
|
public int getSimilarStacksInChunk(SWorld sWorld, LivingEntity entity) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (LivingEntity e : getNearbyEntities(entity.getLocation(), -1, true)) {
|
for (LivingEntity e : getNearbyEntities(sWorld, entity.getLocation(), -1, true)) {
|
||||||
if (entity.getType() == e.getType() && plugin.getEntityStackManager().isStackedAndLoaded(e))
|
if (entity.getType() == e.getType() && plugin.getEntityStackManager().isStackedAndLoaded(e))
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LivingEntity> getSimilarEntitiesAroundEntity(LivingEntity initialEntity, Location location) {
|
public List<LivingEntity> getSimilarEntitiesAroundEntity(LivingEntity initialEntity, SWorld sWorld, Location location) {
|
||||||
// Create a list of all entities around the initial entity of the same type.
|
// Create a list of all entities around the initial entity of the same type.
|
||||||
List<LivingEntity> entityList = new LinkedList<>();
|
List<LivingEntity> entityList = new LinkedList<>();
|
||||||
|
|
||||||
for (LivingEntity entity : getNearbyEntities(location, searchRadius, stackWholeChunk)) {
|
for (LivingEntity entity : getNearbyEntities(sWorld, location, searchRadius, stackWholeChunk)) {
|
||||||
if (entity.getType() != initialEntity.getType() || entity == initialEntity)
|
if (entity.getType() != initialEntity.getType() || entity == initialEntity)
|
||||||
continue;
|
continue;
|
||||||
entityList.add(entity);
|
entityList.add(entity);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.songoda.ultimatestacker.utils;
|
package com.songoda.ultimatestacker.utils;
|
||||||
|
|
||||||
|
import com.songoda.core.world.SWorld;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -10,65 +11,61 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class CachedChunk {
|
public class CachedChunk {
|
||||||
|
|
||||||
private final String world;
|
private final SWorld sWorld;
|
||||||
private final int x;
|
private final int x;
|
||||||
private final int z;
|
private final int z;
|
||||||
|
|
||||||
public CachedChunk(Chunk chunk) {
|
public CachedChunk(SWorld sWorld, Location location) {
|
||||||
this(chunk.getWorld().getName(), chunk.getX(), chunk.getZ());
|
this(sWorld, (int)location.getX() >> 4, (int)location.getZ() >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachedChunk(Location location) {
|
public CachedChunk(SWorld sWorld, int x, int z) {
|
||||||
this(location.getWorld().getName(), (int)location.getX() >> 4, (int)location.getZ() >> 4);
|
this.sWorld = sWorld;
|
||||||
}
|
|
||||||
|
|
||||||
public CachedChunk(String world, int x, int z) {
|
|
||||||
this.world = world;
|
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWorld() {
|
public String getWorld() {
|
||||||
return this.world;
|
return sWorld.getWorld().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return this.x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getZ() {
|
public int getZ() {
|
||||||
return this.z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk getChunk() {
|
public Chunk getChunk() {
|
||||||
World world = Bukkit.getWorld(this.world);
|
World world = sWorld.getWorld();
|
||||||
if (world == null)
|
if (world == null)
|
||||||
return null;
|
return null;
|
||||||
return world.getChunkAt(this.x, this.z);
|
return world.getChunkAt(this.x, this.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity[] getEntities() {
|
public Entity[] getEntities() {
|
||||||
if (!Bukkit.getWorld(world).isChunkLoaded(x, z)) {
|
if (!sWorld.getWorld().isChunkLoaded(x, z)) {
|
||||||
return new Entity[0];
|
return new Entity[0];
|
||||||
}
|
}
|
||||||
Chunk chunk = getChunk();
|
Chunk chunk = getChunk();
|
||||||
return chunk == null ? new Entity[0] : getChunk().getEntities();
|
return chunk == null ? new Entity[0] : sWorld.getEntitiesFromChunk(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o instanceof Chunk) {
|
if (o instanceof Chunk) {
|
||||||
Chunk other = (Chunk) o;
|
Chunk other = (Chunk) o;
|
||||||
return this.world.equals(other.getWorld().getName()) && this.x == other.getX() && this.z == other.getZ();
|
return getWorld().equals(other.getWorld().getName()) && this.x == other.getX() && this.z == other.getZ();
|
||||||
} else if (o instanceof CachedChunk) {
|
} else if (o instanceof CachedChunk) {
|
||||||
CachedChunk other = (CachedChunk) o;
|
CachedChunk other = (CachedChunk) o;
|
||||||
return this.world.equals(other.getWorld()) && this.x == other.getX() && this.z == other.getZ();
|
return getWorld().equals(other.getWorld()) && this.x == other.getX() && this.z == other.getZ();
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(this.world, this.x, this.z);
|
return Objects.hash(getWorld(), this.x, this.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user