Paper/CraftBukkit-Patches/0011-Fix-Mob-Spawning-Relative-to-View-Distance.patch

164 lines
7.2 KiB
Diff
Raw Normal View History

2016-02-29 22:33:06 +01:00
From df5eaaafd25ed43b37cbc8073538fa9a362616e6 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
Changes the mob spawning algorithm to properly account for view distance and the range around players.
Needs better documentation.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
2016-02-29 22:33:06 +01:00
index 8345e87..e4725b0 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
2016-02-29 22:33:06 +01:00
@@ -43,6 +43,7 @@ public class Chunk {
private long v;
private int w;
private ConcurrentLinkedQueue<BlockPosition> x;
2014-11-28 02:17:45 +01:00
+ protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
// CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
private int neighbors = 0x1 << 12;
2016-02-29 22:33:06 +01:00
@@ -606,6 +607,22 @@ public class Chunk {
entity.ac = k;
entity.ad = 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) {
2016-02-29 22:33:06 +01:00
@@ -622,6 +639,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
}
2016-02-29 22:33:06 +01:00
public boolean c(BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
2016-02-29 22:33:06 +01:00
index b3cb8bb..9e19dfd 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
2016-02-29 22:33:06 +01:00
@@ -17,6 +17,25 @@ public final class SpawnerCreature {
2014-11-28 02:17:45 +01:00
public SpawnerCreature() {}
+ // Spigot start - get entity count only from chunks being processed in b
+ private int getEntityCount(WorldServer server, Class oClass)
+ {
+ int i = 0;
2014-11-28 02:17:45 +01:00
+ Iterator<Long> it = this.b.iterator();
+ while ( it.hasNext() )
+ {
2014-11-28 02:17:45 +01:00
+ Long coord = it.next();
+ int x = LongHash.msw( coord );
+ int z = LongHash.lsw( coord );
2016-02-29 22:33:06 +01:00
+ if ( !((ChunkProviderServer)server.chunkProvider).unloadQueue.contains( coord ) && server.isChunkLoaded( x, z, true ) )
+ {
+ i += server.getChunkAt( x, z ).entityCount.get( oClass );
+ }
+ }
+ return i;
+ }
+ // Spigot end
+
2014-11-28 02:17:45 +01:00
public int a(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
if (!flag && !flag1) {
return 0;
2016-02-29 22:33:06 +01:00
@@ -36,6 +55,11 @@ public final class SpawnerCreature {
2014-11-28 02:17:45 +01:00
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 i1 = -b0; i1 <= b0; ++i1) {
2014-11-28 02:17:45 +01:00
for (k = -b0; k <= b0; ++k) {
2016-02-29 22:33:06 +01:00
@@ -89,18 +113,20 @@ public final class SpawnerCreature {
if (limit == 0) {
continue;
}
2014-11-28 02:17:45 +01:00
+ int mobcnt = 0; // Spigot
// CraftBukkit end
2014-11-28 02:17:45 +01:00
if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2)) {
k = worldserver.a(enumcreaturetype.a());
int l1 = limit * i / a; // CraftBukkit - use per-world limits
- if (k <= l1) {
+ if ((mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * i / 256) {
2016-02-29 22:33:06 +01:00
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
2014-11-28 02:17:45 +01:00
Iterator iterator1 = this.b.iterator();
2014-11-28 02:17:45 +01:00
+ int moblimit = (limit * i / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
2016-02-29 22:33:06 +01:00
label120:
2014-11-28 02:17:45 +01:00
- while (iterator1.hasNext()) {
+ while (iterator1.hasNext() && (moblimit > 0)) { // Spigot - while more allowed
// CraftBukkit start = use LongHash and LongObjectHashMap
long key = ((Long) iterator1.next()).longValue();
BlockPosition blockposition1 = getRandomPosition(worldserver, LongHash.msw(key), LongHash.lsw(key));
2016-02-29 22:33:06 +01:00
@@ -162,7 +188,10 @@ public final class SpawnerCreature {
entityinsentient.die();
2014-11-28 02:17:45 +01:00
}
2016-02-29 22:33:06 +01:00
- if (l2 >= entityinsentient.cJ()) {
2014-11-28 02:17:45 +01:00
+ // Spigot start
2016-02-29 22:33:06 +01:00
+ if ( --moblimit <= 0 ) {
2014-11-28 02:17:45 +01:00
+ // If we're past limit, stop spawn
2016-02-29 22:33:06 +01:00
+ // Spigot end
continue label120;
2014-11-28 02:17:45 +01:00
}
2016-02-29 22:33:06 +01:00
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
2016-02-29 22:33:06 +01:00
index 86300d6..cacb8fc 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
2016-02-29 22:33:06 +01:00
@@ -122,4 +122,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 );
+ }
}
--
2016-02-29 22:33:06 +01:00
2.5.0