diff --git a/paper-server/nms-patches/net/minecraft/world/level/SpawnerCreature.patch b/paper-server/nms-patches/net/minecraft/world/level/SpawnerCreature.patch index b7525f994f..c73d364c27 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/SpawnerCreature.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/SpawnerCreature.patch @@ -22,7 +22,7 @@ continue; } } -@@ -108,10 +114,49 @@ +@@ -108,10 +114,54 @@ EnumCreatureType[] aenumcreaturetype = SpawnerCreature.SPAWNING_CATEGORIES; int i = aenumcreaturetype.length; @@ -33,6 +33,7 @@ + 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; ++ boolean spawnWaterUndergroundCreatureThisTick = worldserver.ticksPerWaterUndergroundCreatureSpawns != 0L && worlddata.getTime() % worldserver.ticksPerWaterUndergroundCreatureSpawns == 0L; + // CraftBukkit end + for (int j = 0; j < i; ++j) { @@ -53,6 +54,10 @@ + spawnThisTick = spawnWaterThisTick; + limit = worldserver.getWorld().getWaterAnimalSpawnLimit(); + break; ++ case UNDERGROUND_WATER_CREATURE: ++ spawnThisTick = spawnWaterUndergroundCreatureThisTick; ++ limit = worldserver.getWorld().getWaterUndergroundCreatureSpawnLimit(); ++ break; + case AMBIENT: + spawnThisTick = spawnAmbientThisTick; + limit = worldserver.getWorld().getAmbientSpawnLimit(); @@ -73,7 +78,7 @@ Objects.requireNonNull(spawnercreature_d); SpawnerCreature.c spawnercreature_c = spawnercreature_d::a; -@@ -196,10 +241,14 @@ +@@ -196,10 +246,14 @@ 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); @@ -92,7 +97,7 @@ if (j >= entityinsentient.getMaxSpawnGroup()) { return; } -@@ -370,7 +419,7 @@ +@@ -370,7 +424,7 @@ if (entityinsentient.a((GeneratorAccess) worldaccess, EnumMobSpawn.CHUNK_GENERATION) && entityinsentient.a((IWorldReader) worldaccess)) { groupdataentity = entityinsentient.prepare(worldaccess, worldaccess.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.CHUNK_GENERATION, groupdataentity, (NBTTagCompound) null); @@ -101,7 +106,7 @@ flag = true; } } -@@ -486,8 +535,10 @@ +@@ -486,8 +540,10 @@ return this.unmodifiableMobCategoryCounts; } diff --git a/paper-server/nms-patches/net/minecraft/world/level/World.patch b/paper-server/nms-patches/net/minecraft/world/level/World.patch index edabea4865..da7951823c 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/World.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/World.patch @@ -29,7 +29,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { protected static final Logger LOGGER = LogManager.getLogger(); -@@ -103,7 +125,50 @@ +@@ -103,7 +125,52 @@ private final BiomeManager biomeManager; private final ResourceKey dimension; @@ -51,6 +51,7 @@ + public long ticksPerMonsterSpawns; + public long ticksPerWaterSpawns; + public long ticksPerWaterAmbientSpawns; ++ public long ticksPerWaterUndergroundCreatureSpawns; + public long ticksPerAmbientSpawns; + public boolean populating; + @@ -73,6 +74,7 @@ + this.ticksPerMonsterSpawns = this.getCraftServer().getTicksPerMonsterSpawns(); // CraftBukkit + this.ticksPerWaterSpawns = this.getCraftServer().getTicksPerWaterSpawns(); // CraftBukkit + this.ticksPerWaterAmbientSpawns = this.getCraftServer().getTicksPerWaterAmbientSpawns(); // CraftBukkit ++ this.ticksPerWaterUndergroundCreatureSpawns = this.getCraftServer().getTicksPerWaterUndergroundCreatureSpawns(); // CraftBukkit + this.ticksPerAmbientSpawns = this.getCraftServer().getTicksPerAmbientSpawns(); // CraftBukkit + this.typeKey = (ResourceKey) this.getCraftServer().getHandle().getServer().registryHolder.d(IRegistry.DIMENSION_TYPE_REGISTRY).c(dimensionmanager).orElseThrow(() -> { + return new IllegalStateException("Unregistered dimension type: " + dimensionmanager); @@ -81,7 +83,7 @@ this.profiler = supplier; this.levelData = worlddatamutable; this.dimensionType = dimensionmanager; -@@ -113,12 +178,12 @@ +@@ -113,12 +180,12 @@ this.worldBorder = new WorldBorder() { @Override public double getCenterX() { @@ -96,7 +98,7 @@ } }; } else { -@@ -128,6 +193,35 @@ +@@ -128,6 +195,35 @@ this.thread = Thread.currentThread(); this.biomeManager = new BiomeManager(this, i, dimensionmanager.getGenLayerZoomer()); this.isDebug = flag1; @@ -132,7 +134,7 @@ } @Override -@@ -185,6 +279,17 @@ +@@ -185,6 +281,17 @@ @Override public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) { @@ -150,7 +152,7 @@ if (this.isOutsideWorld(blockposition)) { return false; } else if (!this.isClientSide && this.isDebugWorld()) { -@@ -192,9 +297,24 @@ +@@ -192,9 +299,24 @@ } else { Chunk chunk = this.getChunkAtWorldCoords(blockposition); Block block = iblockdata.getBlock(); @@ -176,7 +178,7 @@ return false; } else { IBlockData iblockdata2 = this.getType(blockposition); -@@ -205,6 +325,7 @@ +@@ -205,6 +327,7 @@ this.getMethodProfiler().exit(); } @@ -184,7 +186,7 @@ if (iblockdata2 == iblockdata) { if (iblockdata1 != iblockdata2) { this.b(blockposition, iblockdata1, iblockdata2); -@@ -231,12 +352,69 @@ +@@ -231,12 +354,69 @@ this.a(blockposition, iblockdata1, iblockdata2); } @@ -254,7 +256,7 @@ public void a(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} @Override -@@ -326,6 +504,17 @@ +@@ -326,6 +506,17 @@ IBlockData iblockdata = this.getType(blockposition); try { @@ -272,7 +274,7 @@ iblockdata.doPhysics(this, blockposition, block, blockposition1, false); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours"); -@@ -368,6 +557,14 @@ +@@ -368,6 +559,14 @@ @Override public IBlockData getType(BlockPosition blockposition) { @@ -287,7 +289,7 @@ if (this.isOutsideWorld(blockposition)) { return Blocks.VOID_AIR.getBlockData(); } else { -@@ -484,7 +681,17 @@ +@@ -484,7 +683,17 @@ @Nullable @Override @@ -305,7 +307,7 @@ return this.isOutsideWorld(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAtWorldCoords(blockposition).a(blockposition, Chunk.EnumTileEntityState.IMMEDIATE)); } -@@ -492,6 +699,12 @@ +@@ -492,6 +701,12 @@ BlockPosition blockposition = tileentity.getPosition(); if (!this.isOutsideWorld(blockposition)) { @@ -318,7 +320,7 @@ this.getChunkAtWorldCoords(blockposition).b(tileentity); } } -@@ -595,7 +808,7 @@ +@@ -595,7 +810,7 @@ for (int j = 0; j < i; ++j) { EntityComplexPart entitycomplexpart = aentitycomplexpart[j]; @@ -327,7 +329,7 @@ if (t0 != null && predicate.test(t0)) { list.add(t0); -@@ -921,6 +1134,14 @@ +@@ -921,6 +1136,14 @@ public abstract LevelEntityGetter getEntities(); protected void a(@Nullable Entity entity, GameEvent gameevent, BlockPosition blockposition, int i) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 32d60c2fbc..a483c1c053 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -269,6 +269,7 @@ public final class CraftServer implements Server { private int animalSpawn = -1; private int waterAnimalSpawn = -1; private int waterAmbientSpawn = -1; + private int waterUndergroundCreatureSpawn = -1; private int ambientSpawn = -1; private File container; private WarningState warningState = WarningState.DEFAULT; @@ -356,6 +357,7 @@ public final class CraftServer implements Server { animalSpawn = configuration.getInt("spawn-limits.animals"); waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals"); waterAmbientSpawn = configuration.getInt("spawn-limits.water-ambient"); + waterUndergroundCreatureSpawn = configuration.getInt("spawn-limits.water-underground-creature"); ambientSpawn = configuration.getInt("spawn-limits.ambient"); console.autosavePeriod = configuration.getInt("ticks-per.autosave"); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); @@ -700,6 +702,11 @@ public final class CraftServer implements Server { return this.configuration.getInt("ticks-per.water-ambient-spawns"); } + @Override + public int getTicksPerWaterUndergroundCreatureSpawns() { + return this.configuration.getInt("ticks-per.water-underground-creature-spawns"); + } + @Override public int getTicksPerAmbientSpawns() { return this.configuration.getInt("ticks-per.ambient-spawns"); @@ -784,6 +791,7 @@ public final class CraftServer implements Server { animalSpawn = configuration.getInt("spawn-limits.animals"); waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals"); waterAmbientSpawn = configuration.getInt("spawn-limits.water-ambient"); + waterUndergroundCreatureSpawn = configuration.getInt("spawn-limits.water-underground-creature"); ambientSpawn = configuration.getInt("spawn-limits.ambient"); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks"); @@ -830,6 +838,12 @@ public final class CraftServer implements Server { world.ticksPerWaterAmbientSpawns = this.getTicksPerWaterAmbientSpawns(); } + if (this.getTicksPerWaterUndergroundCreatureSpawns() < 0) { + world.ticksPerWaterUndergroundCreatureSpawns = 1; + } else { + world.ticksPerWaterUndergroundCreatureSpawns = this.getTicksPerWaterUndergroundCreatureSpawns(); + } + if (this.getTicksPerAmbientSpawns() < 0) { world.ticksPerAmbientSpawns = 1; } else { @@ -1830,6 +1844,11 @@ public final class CraftServer implements Server { return waterAmbientSpawn; } + @Override + public int getWaterUndergroundCreatureSpawnLimit() { + return waterUndergroundCreatureSpawn; + } + @Override public int getAmbientSpawnLimit() { return ambientSpawn; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 6bcc47e831..80b4c02e04 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -134,6 +134,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { private int animalSpawn = -1; private int waterAnimalSpawn = -1; private int waterAmbientSpawn = -1; + private int waterUndergroundCreatureSpawn = -1; private int ambientSpawn = -1; private static final Random rand = new Random(); @@ -1353,6 +1354,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { world.ticksPerWaterAmbientSpawns = ticksPerWaterAmbientSpawns; } + @Override + public long getTicksPerWaterUndergroundCreatureSpawns() { + return world.ticksPerWaterUndergroundCreatureSpawns; + } + + @Override + public void setTicksPerWaterUndergroundCreatureSpawns(int ticksPerWaterUndergroundCreatureSpawns) { + world.ticksPerWaterUndergroundCreatureSpawns = ticksPerWaterUndergroundCreatureSpawns; + } + @Override public long getTicksPerAmbientSpawns() { return world.ticksPerAmbientSpawns; @@ -1439,6 +1450,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { waterAmbientSpawn = limit; } + @Override + public int getWaterUndergroundCreatureSpawnLimit() { + if (waterUndergroundCreatureSpawn < 0) { + return server.getWaterUndergroundCreatureSpawnLimit(); + } + + return waterUndergroundCreatureSpawn; + } + + @Override + public void setWaterUndergroundCreatureSpawnLimit(int limit) { + waterUndergroundCreatureSpawn = limit; + } + @Override public int getAmbientSpawnLimit() { if (ambientSpawn < 0) { diff --git a/paper-server/src/main/resources/configurations/bukkit.yml b/paper-server/src/main/resources/configurations/bukkit.yml index 6474a7fb73..236ffc5a5a 100644 --- a/paper-server/src/main/resources/configurations/bukkit.yml +++ b/paper-server/src/main/resources/configurations/bukkit.yml @@ -26,8 +26,9 @@ settings: spawn-limits: monsters: 70 animals: 10 - water-animals: 15 + water-animals: 5 water-ambient: 20 + water-underground-creature: 5 ambient: 15 chunk-gc: period-in-ticks: 600 @@ -36,6 +37,7 @@ ticks-per: monster-spawns: 1 water-spawns: 1 water-ambient-spawns: 1 + water-underground-creature-spawns: 1 ambient-spawns: 1 autosave: 6000 aliases: now-in-commands.yml