PaperMC/nms-patches/SpawnerCreature.patch

114 lines
6.5 KiB
Diff

--- a/net/minecraft/server/SpawnerCreature.java
+++ b/net/minecraft/server/SpawnerCreature.java
@@ -13,6 +13,10 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+// CraftBukkit start
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+// CraftBukkit end
+
public final class SpawnerCreature {
private static final Logger LOGGER = LogManager.getLogger();
@@ -34,7 +38,8 @@
if (entity instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) entity;
- if (entityinsentient.isPersistent() || entityinsentient.isSpecialPersistence()) {
+ // CraftBukkit - Split out persistent check, don't apply it to special persistent mobs
+ if (entityinsentient.isTypeNotPersistent(0) && entityinsentient.isPersistent()) {
continue;
}
}
@@ -70,10 +75,49 @@
EnumCreatureType[] aenumcreaturetype = SpawnerCreature.c;
int i = aenumcreaturetype.length;
+ // CraftBukkit start - Other mob type spawn tick rate
+ WorldData worlddata = worldserver.getWorldData();
+ boolean spawnAnimalThisTick = worldserver.ticksPerAnimalSpawns != 0L && worlddata.getTime() % worldserver.ticksPerAnimalSpawns == 0L;
+ boolean spawnMonsterThisTick = worldserver.ticksPerMonsterSpawns != 0L && worlddata.getTime() % worldserver.ticksPerMonsterSpawns == 0L;
+ boolean spawnWaterThisTick = worldserver.ticksPerWaterSpawns != 0L && worlddata.getTime() % worldserver.ticksPerWaterSpawns == 0L;
+ boolean spawnAmbientThisTick = worldserver.ticksPerAmbientSpawns != 0L && worlddata.getTime() % worldserver.ticksPerAmbientSpawns == 0L;
+ boolean spawnWaterAmbientThisTick = worldserver.ticksPerWaterAmbientSpawns != 0L && worlddata.getTime() % worldserver.ticksPerWaterAmbientSpawns == 0L;
+ // CraftBukkit end
+
for (int j = 0; j < i; ++j) {
EnumCreatureType enumcreaturetype = aenumcreaturetype[j];
+ // CraftBukkit start - Use per-world spawn limits
+ boolean spawnThisTick = true;
+ int limit = enumcreaturetype.c();
+ switch (enumcreaturetype) {
+ case MONSTER:
+ spawnThisTick = spawnMonsterThisTick;
+ limit = worldserver.getWorld().getMonsterSpawnLimit();
+ break;
+ case CREATURE:
+ spawnThisTick = spawnAnimalThisTick;
+ limit = worldserver.getWorld().getAnimalSpawnLimit();
+ break;
+ case WATER_CREATURE:
+ spawnThisTick = spawnWaterThisTick;
+ limit = worldserver.getWorld().getWaterAnimalSpawnLimit();
+ break;
+ case AMBIENT:
+ spawnThisTick = spawnAmbientThisTick;
+ limit = worldserver.getWorld().getAmbientSpawnLimit();
+ break;
+ case WATER_AMBIENT:
+ spawnThisTick = spawnWaterAmbientThisTick;
+ limit = worldserver.getWorld().getWaterAmbientSpawnLimit();
+ break;
+ }
- if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype)) {
+ if (!spawnThisTick || limit == 0) {
+ continue;
+ }
+
+ if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) {
+ // CraftBukkit end
a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
return spawnercreature_d.a(entitytypes, blockposition, ichunkaccess);
}, (entityinsentient, ichunkaccess) -> {
@@ -148,10 +192,13 @@
entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F);
if (a(worldserver, entityinsentient, d2)) {
groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
- ++j;
- ++k1;
- worldserver.addEntity(entityinsentient);
- spawnercreature_a.run(entityinsentient, ichunkaccess);
+ // CraftBukkit start
+ if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
+ ++j;
+ ++k1;
+ spawnercreature_a.run(entityinsentient, ichunkaccess);
+ }
+ // CraftBukkit end
if (j >= entityinsentient.getMaxSpawnGroup()) {
return;
}
@@ -333,7 +380,7 @@
if (entityinsentient.a(generatoraccess, EnumMobSpawn.CHUNK_GENERATION) && entityinsentient.a((IWorldReader) generatoraccess)) {
groupdataentity = entityinsentient.prepare(generatoraccess, generatoraccess.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.CHUNK_GENERATION, groupdataentity, (NBTTagCompound) null);
- generatoraccess.addEntity(entityinsentient);
+ generatoraccess.addEntity(entityinsentient, SpawnReason.CHUNK_GEN); // CraftBukkit
flag = true;
}
}
@@ -458,8 +505,10 @@
return this.d;
}
- private boolean a(EnumCreatureType enumcreaturetype) {
- int i = enumcreaturetype.c() * this.a / SpawnerCreature.b;
+ // CraftBukkit start
+ private boolean a(EnumCreatureType enumcreaturetype, int limit) {
+ int i = limit * this.a / SpawnerCreature.b;
+ // CraftBukkit end
return this.b.getInt(enumcreaturetype) < i;
}