Paper/Spigot-Server-Patches/0393-Actually-Limit-Natural-Spawns-To-Limit.patch
Spottedleaf fe7ef7b5d6 Do not schedule to main for getChunkImmediately type calls (#2362)
They are MT-Safe already. These changes reduce deadlock chances
given these calls are used in Entity#isValid(), and plugins
check this in packet handling...
2019-07-26 02:36:26 +01:00

98 lines
6.1 KiB
Diff

From 8dccf6997c9352637853343a52abcdd7a96950e5 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 a58cfc14bb..26216fe72c 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -444,8 +444,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 c6ea37ffbd..5e6559df0b 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
@@ -88,7 +95,7 @@ public final class SpawnerCreature {
);
if (!event.callEvent()) {
if (event.shouldAbortSpawn()) {
- return;
+ return amountSpawned; // Paper
}
++i2;
continue;
@@ -107,7 +114,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);
@@ -117,10 +124,16 @@ 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 end
// CraftBukkit end
if (i >= entityinsentient.dC()) {
- return;
+ return amountSpawned; // Paper
}
if (entityinsentient.c(i2)) {
@@ -146,6 +159,7 @@ public final class SpawnerCreature {
}
}
+ return amountSpawned; // Paper
}
@Nullable
--
2.22.0