papermc/CraftBukkit-Patches/0016-Fix-Mob-Spawning-Relative-to-View-Distance.patch

156 lines
7.1 KiB
Diff
Raw Normal View History

From fa7ec75f87672542655a9d1a836d3090700ef8e1 Mon Sep 17 00:00:00 2001
2013-06-21 07:30:13 +00:00
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
2013-06-21 07:35:08 +00:00
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
2014-03-23 00:06:43 +00:00
index 771eab3..0110120 100644
2013-06-21 07:35:08 +00:00
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
2013-12-01 03:40:53 +00:00
@@ -40,6 +40,7 @@ public class Chunk {
public int r;
public long s;
private int x;
2013-06-21 07:35:08 +00:00
+ 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];
2014-01-15 09:28:26 +00:00
@@ -612,6 +613,22 @@ public class Chunk {
2014-03-23 00:06:43 +00:00
entity.ai = k;
entity.aj = this.locZ;
2013-06-21 07:35:08 +00:00
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;
+ }
+ }
2013-06-21 07:35:08 +00:00
+ 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) {
2014-01-15 09:28:26 +00:00
@@ -628,6 +645,22 @@ public class Chunk {
2013-06-21 07:35:08 +00:00
}
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;
+ }
+ }
2013-06-21 07:35:08 +00:00
+ 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
2014-03-23 00:06:43 +00:00
index 2ef15d2..23d6611 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
2013-07-02 03:03:56 +00:00
@@ -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
2013-07-02 03:24:59 +00:00
+ private int getEntityCount(WorldServer server, Class oClass)
2013-06-21 07:30:13 +00:00
+ {
+ int i = 0;
2013-07-02 03:24:59 +00:00
+ for ( Long coord : this.a.keySet() )
2013-06-21 07:30:13 +00:00
+ {
+ int x = LongHash.msw( coord );
+ int z = LongHash.lsw( coord );
2013-06-21 07:35:08 +00:00
+ if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z ) )
2013-06-21 07:30:13 +00:00
+ {
2013-06-21 07:35:08 +00:00
+ i += server.getChunkAt( x, z ).entityCount.get( oClass );
+ }
+ }
+ return i;
+ }
+ // Spigot end
+
2013-07-02 03:03:56 +00:00
public int spawnEntities(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
if (!flag && !flag1) {
return 0;
2013-07-02 03:03:56 +00:00
@@ -42,6 +59,11 @@ public final class SpawnerCreature {
j = MathHelper.floor(entityhuman.locZ / 16.0D);
2013-06-21 07:30:13 +00:00
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) {
2013-07-02 03:03:56 +00:00
@@ -89,13 +111,15 @@ public final class SpawnerCreature {
if (limit == 0) {
continue;
}
+ int mobcnt = 0;
// CraftBukkit end
2013-07-02 03:03:56 +00:00
- 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();
2013-07-02 03:24:59 +00:00
+ 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
2014-03-23 00:06:43 +00:00
// CraftBukkit start = use LongHash and LongObjectHashMap
long key = ((Long) iterator.next()).longValue();
2013-07-02 03:03:56 +00:00
@@ -160,6 +184,13 @@ public final class SpawnerCreature {
groupdataentity = entityinsentient.a(groupdataentity);
worldserver.addEntity(entityinsentient, SpawnReason.NATURAL);
// CraftBukkit end
+ // Spigot start
2013-06-21 07:30:13 +00:00
+ if ( --moblimit <= 0 )
+ {
+ // If we're past limit, stop spawn
+ continue label110;
+ }
+ // Spigot end
2014-03-23 00:06:43 +00:00
if (j2 >= entityinsentient.bB()) {
continue label110;
}
2013-06-21 07:30:13 +00:00
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
2014-03-09 22:14:45 +00:00
index 6cc3a91..46249d7 100644
2013-06-21 07:30:13 +00:00
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -131,4 +131,11 @@ public class SpigotWorldConfig
2013-12-13 00:10:33 +00:00
viewDistance = getInt( "view-distance", Bukkit.getViewDistance() );
log( "View Distance: " + viewDistance );
2013-06-21 07:30:13 +00:00
}
+
+ public byte mobSpawnRange;
+ private void mobSpawnRange()
+ {
2013-06-21 07:41:26 +00:00
+ mobSpawnRange = (byte) getInt( "mob-spawn-range", 4 );
2013-06-21 07:30:13 +00:00
+ log( "Mob Spawn Range: " + mobSpawnRange );
+ }
}
--
1.8.3.2
2013-08-03 22:51:09 +00:00