af480b8b95
Whilst the new behaviour was technically correct as it prevented the possibility of the chunk tick list actually increasing over time, it introduced a few issues, namely the fact that it slowed growth to unreasonable levels, and interfered with the values which server admins have finally tuned, and come to enjoy over the last few years. If it is absolutely essential that growth be halted and ticking reduced as much as possible, the config option is there for power users. If we wish to 'fix' this by default in the future, a new chunk ticking algorithm, which actually has meaningful config options should be designed.
155 lines
7.1 KiB
Diff
155 lines
7.1 KiB
Diff
From d9860352fadbcf7ba9dc05acdfa6f57bbb3fe2e7 Mon Sep 17 00:00:00 2001
|
|
From: md_5 <md_5@live.com.au>
|
|
Date: Fri, 21 Jun 2013 17:29:54 +1000
|
|
Subject: [PATCH] Fix Mob Spawning Relative to View Distance
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index 95b4704..3bcca91 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -40,6 +40,7 @@ public class Chunk {
|
|
public int r;
|
|
public long s;
|
|
private int x;
|
|
+ protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
|
|
|
|
public Chunk(World world, int i, int j) {
|
|
this.sections = new ChunkSection[16];
|
|
@@ -601,6 +602,22 @@ public class Chunk {
|
|
entity.aj = k;
|
|
entity.ak = this.locZ;
|
|
this.entitySlices[k].add(entity);
|
|
+ // Spigot start - increment creature type count
|
|
+ // Keep this synced up with World.a(Class)
|
|
+ if (entity instanceof EntityInsentient) {
|
|
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
|
|
+ if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ for ( EnumCreatureType creatureType : EnumCreatureType.values() )
|
|
+ {
|
|
+ if ( creatureType.a().isAssignableFrom( entity.getClass() ) )
|
|
+ {
|
|
+ this.entityCount.adjustOrPutValue( creatureType.a(), 1, 1 );
|
|
+ }
|
|
+ }
|
|
+ // Spigot end
|
|
}
|
|
|
|
public void b(Entity entity) {
|
|
@@ -617,6 +634,22 @@ public class Chunk {
|
|
}
|
|
|
|
this.entitySlices[i].remove(entity);
|
|
+ // Spigot start - decrement creature type count
|
|
+ // Keep this synced up with World.a(Class)
|
|
+ if (entity instanceof EntityInsentient) {
|
|
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
|
|
+ if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ for ( EnumCreatureType creatureType : EnumCreatureType.values() )
|
|
+ {
|
|
+ if ( creatureType.a().isAssignableFrom( entity.getClass() ) )
|
|
+ {
|
|
+ this.entityCount.adjustValue( creatureType.a(), -1 );
|
|
+ }
|
|
+ }
|
|
+ // Spigot end
|
|
}
|
|
|
|
public boolean d(int i, int j, int k) {
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index f514b78..3f0dd70 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -27,6 +27,23 @@ public final class SpawnerCreature {
|
|
return new ChunkPosition(k, i1, l);
|
|
}
|
|
|
|
+ // Spigot start - get entity count only from chunks being processed in b
|
|
+ private int getEntityCount(WorldServer server, Class oClass)
|
|
+ {
|
|
+ int i = 0;
|
|
+ for ( Long coord : this.a.keySet() )
|
|
+ {
|
|
+ int x = LongHash.msw( coord );
|
|
+ int z = LongHash.lsw( coord );
|
|
+ if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z ) )
|
|
+ {
|
|
+ i += server.getChunkAt( x, z ).entityCount.get( oClass );
|
|
+ }
|
|
+ }
|
|
+ return i;
|
|
+ }
|
|
+ // Spigot end
|
|
+
|
|
public int spawnEntities(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
|
|
if (!flag && !flag1) {
|
|
return 0;
|
|
@@ -42,6 +59,11 @@ public final class SpawnerCreature {
|
|
|
|
j = MathHelper.floor(entityhuman.locZ / 16.0D);
|
|
byte b0 = 8;
|
|
+ // Spigot Start
|
|
+ b0 = worldserver.spigotConfig.mobSpawnRange;
|
|
+ b0 = ( b0 > worldserver.spigotConfig.viewDistance ) ? (byte) worldserver.spigotConfig.viewDistance : b0;
|
|
+ b0 = ( b0 > 8 ) ? 8 : b0;
|
|
+ // Spigot End
|
|
|
|
for (int l = -b0; l <= b0; ++l) {
|
|
for (int i1 = -b0; i1 <= b0; ++i1) {
|
|
@@ -89,13 +111,15 @@ public final class SpawnerCreature {
|
|
if (limit == 0) {
|
|
continue;
|
|
}
|
|
+ int mobcnt = 0;
|
|
// CraftBukkit end
|
|
|
|
- if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && worldserver.a(enumcreaturetype.a()) <= limit * this.a.size() / 256) { // CraftBukkit - use per-world limits
|
|
+ if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && (mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * this.a.size() / 256) { // Spigot - use per-world limits and use all loaded chunks
|
|
Iterator iterator = this.a.keySet().iterator();
|
|
|
|
+ int moblimit = (limit * this.a.size() / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
|
|
label110:
|
|
- while (iterator.hasNext()) {
|
|
+ while (iterator.hasNext() && (moblimit > 0)) { // Spigot - while more allowed
|
|
// CraftBukkit start
|
|
long key = ((Long) iterator.next()).longValue();
|
|
|
|
@@ -160,6 +184,13 @@ public final class SpawnerCreature {
|
|
groupdataentity = entityinsentient.a(groupdataentity);
|
|
worldserver.addEntity(entityinsentient, SpawnReason.NATURAL);
|
|
// CraftBukkit end
|
|
+ // Spigot start
|
|
+ if ( --moblimit <= 0 )
|
|
+ {
|
|
+ // If we're past limit, stop spawn
|
|
+ continue label110;
|
|
+ }
|
|
+ // Spigot end
|
|
if (j2 >= entityinsentient.bz()) {
|
|
continue label110;
|
|
}
|
|
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
index 15b2ac8..49a5b7a 100644
|
|
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
@@ -131,4 +131,11 @@ public class SpigotWorldConfig
|
|
viewDistance = getInt( "view-distance", Bukkit.getViewDistance() );
|
|
log( "View Distance: " + viewDistance );
|
|
}
|
|
+
|
|
+ public byte mobSpawnRange;
|
|
+ private void mobSpawnRange()
|
|
+ {
|
|
+ mobSpawnRange = (byte) getInt( "mob-spawn-range", 4 );
|
|
+ log( "Mob Spawn Range: " + mobSpawnRange );
|
|
+ }
|
|
}
|
|
--
|
|
1.8.3.2
|
|
|