papermc/Spigot-Server-Patches/0044-Force-load-chunks-for-specific-entities-that-fly-thr.patch

206 lines
9.9 KiB
Diff

From 068eb2ed78e703619a74bcd0005e5b1d82187def Mon Sep 17 00:00:00 2001
From: Byteflux <byte@byteflux.net>
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 ae0f276..0e6a37f 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -59,6 +59,17 @@ public class ChunkProviderServer implements IChunkProvider {
return;
}
// PaperSpigot end
+ // PaperSpigot start - Don't unload chunk if it contains an entity that loads chunks
+ if (chunk != null) {
+ for (List<Entity> 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 a3b4cdb..68126c4 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -116,6 +116,7 @@ public abstract class Entity implements ICommandListener {
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949
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
@@ -403,8 +404,21 @@ 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 aeade54..ba1cadb 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..3a7c4fa 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,15 @@ 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 +109,12 @@ 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 0de2af1..9cfa54c 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1179,8 +1179,14 @@ public abstract class World implements IBlockAccess {
{
if ( !this.isChunkLoaded( chunkx, chunkz, true ) )
{
- entity.inUnloadedChunk = true; // PaperSpigot - Remove entities in unloaded chunks
- continue;
+ // PaperSpigot start
+ if (entity.loadChunks) {
+ ((ChunkProviderServer) entity.world.chunkProvider).getChunkAt(chunkx, chunkz);
+ } else {
+ entity.inUnloadedChunk = true; // PaperSpigot - Remove entities in unloaded chunks
+ continue;
+ }
+ // PaperSpigot end
}
int cz = chunkz << 4;
Chunk chunk = this.getChunkAt( chunkx, chunkz );
@@ -1672,6 +1678,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 36e0948..a78d748 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..6f3734b 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 ) { // PaperSpigot
SpigotTimings.checkIfActiveTimer.stopTiming();
return true;
}
--
2.5.2