From effe9ef51b8e5e41276686710dac36c6b35f1c55 Mon Sep 17 00:00:00 2001
From: kickash32 <kickash32@gmail.com>
Date: Sun, 2 Jun 2019 01:22:02 -0400
Subject: [PATCH] Actually-Limit-Natural-Spawns-To-Limit


diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index cdc35b912f..10604cf24d 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -412,8 +412,12 @@ public class ChunkProviderServer extends IChunkProvider {
                                 if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) {
                                     int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits
 
-                                    if (object2intmap.getInt(enumcreaturetype) <= k1) {
-                                        SpawnerCreature.a(enumcreaturetype, (World) this.world, chunk, blockposition);
+                                    // Paper start - only allow spawns upto the limit per chunk and update count afterwards
+                                    int currEntityCount = object2intmap.getInt(enumcreaturetype);
+                                    int difference = k1 - currEntityCount;
+                                    if (difference > 0) {
+                                        object2intmap.put(enumcreaturetype, currEntityCount + SpawnerCreature.spawnMobs(enumcreaturetype, world, chunk, blockposition, difference));
+                                    // Paper end
                                     }
                                 }
                             }
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index 94d7bca09d..93fec1685b 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -16,13 +16,20 @@ public final class SpawnerCreature {
 
     private static final Logger LOGGER = LogManager.getLogger();
 
+    // Paper start - add maxSpawns parameter and update counts
     public static void a(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition) {
+        spawnMobs(enumcreaturetype, world, chunk, blockposition, Integer.MAX_VALUE);
+    }
+
+    public static int spawnMobs(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition, int maxSpawns) {
+    // Paper end
         ChunkGenerator<?> chunkgenerator = world.getChunkProvider().getChunkGenerator();
         int i = 0;
         BlockPosition blockposition1 = getRandomPosition(world, chunk);
         int j = blockposition1.getX();
         int k = blockposition1.getY();
         int l = blockposition1.getZ();
+        int amountSpawned = 0; // Paper - keep track of mobs spawned
 
         if (k >= 1) {
             IBlockData iblockdata = world.getTypeIfLoadedAndInBounds(blockposition1);  // Paper - don't load chunks for mob spawn
@@ -85,7 +92,7 @@ public final class SpawnerCreature {
                                                         );
                                                         if (!event.callEvent()) {
                                                             if (event.shouldAbortSpawn()) {
-                                                                return;
+                                                                return amountSpawned; // Paper
                                                             }
                                                             ++i2;
                                                             continue;
@@ -104,7 +111,7 @@ public final class SpawnerCreature {
                                                     } catch (Exception exception) {
                                                         SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
                                                         ServerInternalException.reportInternalException(exception); // Paper
-                                                        return;
+                                                        return amountSpawned; // Paper
                                                     }
 
                                                     entityinsentient.setPositionRotation((double) f, (double) k, (double) f1, world.random.nextFloat() * 360.0F, 0.0F);
@@ -114,10 +121,17 @@ public final class SpawnerCreature {
                                                         if (world.addEntity(entityinsentient, SpawnReason.NATURAL)) {
                                                             ++i;
                                                             ++i2;
+                                                            // Paper start - stop when limit is reached
+                                                            amountSpawned++;
+                                                        }
+
+                                                        if (amountSpawned >= maxSpawns){
+                                                            return amountSpawned; // Paper
                                                         }
+                                                        // Paper end
                                                         // CraftBukkit end
                                                         if (i >= entityinsentient.dC()) {
-                                                            return;
+                                                            return amountSpawned; // Paper
                                                         }
 
                                                         if (entityinsentient.c(i2)) {
@@ -142,6 +156,7 @@ public final class SpawnerCreature {
 
             }
         }
+        return amountSpawned; // Paper
     }
 
     @Nullable
-- 
2.21.0

