From 5044c22415ac2f084b90a5c0e5cdad1ffa7cec63 Mon Sep 17 00:00:00 2001 From: Byteflux Date: Tue, 30 Jun 2015 20:45:24 -0700 Subject: [PATCH] Force load chunks for specific entities that fly through diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index 975d666..f2e13ad 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -53,6 +53,18 @@ public class ChunkProviderServer implements IChunkProvider { } public void queueUnload(int i, int j) { + // PaperSpigot start - Don't unload chunk if it contains an entity that loads chunks + Chunk chunk = chunks.get(LongHash.toLong(i, j)); + if (chunk != null) { + for (List entities : chunk.entitySlices) { + for (Entity entity : entities) { + if (entity.loadChunks) { + return; + } + } + } + } + // PaperSpigot end if (this.world.worldProvider.e()) { if (!this.world.c(i, j)) { // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 2611007..f76c67d 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -115,6 +115,7 @@ public abstract class Entity implements ICommandListener { public boolean valid; // CraftBukkit public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only public boolean inUnloadedChunk = false; // PaperSpigot - Remove entities in unloaded chunks + public boolean loadChunks = false; // PaperSpigot - Entities can load chunks they move through and keep them loaded // Spigot start public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot @@ -402,8 +403,20 @@ public abstract class Entity implements ICommandListener { return this.world.getCubes(this, axisalignedbb).isEmpty() && !this.world.containsLiquid(axisalignedbb); } + /** + * PaperSpigot - Load surrounding chunks the entity is moving through + */ + public void loadChunks() { + for (int cx = (int) locX >> 4; cx <= (int) (locX + motX) >> 4; ++cx) { + for (int cz = (int) locZ >> 4; cz <= (int) (locZ + motZ) >> 4; ++cz) { + ((ChunkProviderServer) world.chunkProvider).getChunkAt(cx, cz); + } + } + } + public void move(double d0, double d1, double d2) { org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot + if (this.loadChunks) loadChunks(); // PaperSpigot - Load chunks if (this.noclip) { this.a(this.getBoundingBox().c(d0, d1, d2)); this.recalcPosition(); diff --git a/src/main/java/net/minecraft/server/EntityEnderPearl.java b/src/main/java/net/minecraft/server/EntityEnderPearl.java index f4b5032..319c0bc 100644 --- a/src/main/java/net/minecraft/server/EntityEnderPearl.java +++ b/src/main/java/net/minecraft/server/EntityEnderPearl.java @@ -12,11 +12,13 @@ public class EntityEnderPearl extends EntityProjectile { public EntityEnderPearl(World world) { super(world); + this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot } public EntityEnderPearl(World world, EntityLiving entityliving) { super(world, entityliving); this.c = entityliving; + this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot } protected void a(MovingObjectPosition movingobjectposition) { diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java index 44219cd..34627c6 100644 --- a/src/main/java/net/minecraft/server/EntityFallingBlock.java +++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -26,6 +26,7 @@ public class EntityFallingBlock extends Entity { public EntityFallingBlock(org.bukkit.Location loc, World world) { super(world); sourceLoc = loc; + this.loadChunks = world.paperSpigotConfig.loadUnloadedFallingBlocks; // PaperSpigot } public EntityFallingBlock(org.bukkit.Location loc, World world, double d0, double d1, double d2, IBlockData iblockdata) { @@ -42,6 +43,7 @@ public class EntityFallingBlock extends Entity { this.lastX = d0; this.lastY = d1; this.lastZ = d2; + this.loadChunks = world.paperSpigotConfig.loadUnloadedFallingBlocks; // PaperSpigot } protected boolean s_() { diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java index 1daba4e..3e16472 100644 --- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java +++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java @@ -21,6 +21,7 @@ public class EntityTNTPrimed extends Entity { // PaperSpigot end this.k = true; this.setSize(0.98F, 0.98F); + this.loadChunks = world.paperSpigotConfig.loadUnloadedTNTEntities; // PaperSpigot } public EntityTNTPrimed(org.bukkit.Location loc, World world, double d0, double d1, double d2, EntityLiving entityliving) { @@ -90,7 +91,13 @@ public class EntityTNTPrimed extends Entity { private void explode() { // CraftBukkit start // float f = 4.0F; - + // PaperSpigot start - Force load chunks during TNT explosions + ChunkProviderServer chunkProviderServer = ((ChunkProviderServer) world.chunkProvider); + boolean forceChunkLoad = chunkProviderServer.forceChunkLoad; + if (world.paperSpigotConfig.loadUnloadedTNTEntities) { + chunkProviderServer.forceChunkLoad = true; + } + // PaperSpigot end org.bukkit.craftbukkit.CraftServer server = this.world.getServer(); ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(server, this)); @@ -100,6 +107,11 @@ public class EntityTNTPrimed extends Entity { this.world.createExplosion(this, this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, event.getRadius(), event.getFire(), true); } // CraftBukkit end + // PaperSpigot start - Force load chunks during TNT explosions + if (world.paperSpigotConfig.loadUnloadedTNTEntities) { + chunkProviderServer.forceChunkLoad = forceChunkLoad; + } + // PaperSpigot end } protected void b(NBTTagCompound nbttagcompound) { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index f507134..a7b5062 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -1634,6 +1634,7 @@ public abstract class World implements IBlockAccess { int i1 = MathHelper.floor(entity.locZ / 16.0D); if (!entity.ad || entity.ae != k || entity.af != l || entity.ag != i1) { + if (entity.loadChunks) entity.loadChunks(); // PaperSpigot - Force load chunks if (entity.ad && this.isChunkLoaded(entity.ae, entity.ag, true)) { this.getChunkAt(entity.ae, entity.ag).a(entity, entity.af); } diff --git a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java index 6de509c..e6ecaff 100644 --- a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java +++ b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java @@ -259,4 +259,14 @@ public class PaperSpigotWorldConfig { disableEndCredits = getBoolean( "game-mechanics.disable-end-credits", false ); } + + public boolean loadUnloadedEnderPearls; + public boolean loadUnloadedTNTEntities; + public boolean loadUnloadedFallingBlocks; + private void loadUnloaded() + { + loadUnloadedEnderPearls = getBoolean( "load-chunks.enderpearls", false ); + loadUnloadedTNTEntities = getBoolean( "load-chunks.tnt-entities", false ); + loadUnloadedFallingBlocks = getBoolean( "load-chunks.falling-blocks", false ); + } } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 7ca1b24..6cf26ff 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -247,7 +247,7 @@ public class ActivationRange { SpigotTimings.checkIfActiveTimer.startTiming(); // Never safe to skip fireworks or entities not yet added to chunk - if ( !entity.isAddedToChunk() || entity instanceof EntityFireworks ) { + if ( !entity.isAddedToChunk() || entity instanceof EntityFireworks || entity.loadChunks ) { SpigotTimings.checkIfActiveTimer.stopTiming(); return true; } -- 1.9.5.msysgit.1