mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-01 12:41:50 +01:00
Improve per player mob spawning (#3971)
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
parent
42433c2626
commit
55e2de5c6e
3 changed files with 25 additions and 20 deletions
|
@ -656,7 +656,7 @@ index cacf60563826da0219754a67500fdc239b13f0cd..f06c41d06f853b625dbd46822126810d
|
||||||
|
|
||||||
private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) {
|
private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) {
|
||||||
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||||
index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb9e8767cd 100644
|
index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..b255ccb4501d85f1507b105d2793c7fb6a919f62 100644
|
||||||
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||||
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||||
@@ -29,6 +29,11 @@ public final class SpawnerCreature {
|
@@ -29,6 +29,11 @@ public final class SpawnerCreature {
|
||||||
|
@ -683,10 +683,11 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,13 +135,33 @@ public final class SpawnerCreature {
|
@@ -125,13 +135,36 @@ public final class SpawnerCreature {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) {
|
||||||
+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards
|
+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards
|
||||||
+ int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype);
|
+ int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype);
|
||||||
+ int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b;
|
+ int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b;
|
||||||
|
@ -695,14 +696,17 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
+ if (worldserver.paperConfig.perPlayerMobSpawns) {
|
+ if (worldserver.paperConfig.perPlayerMobSpawns) {
|
||||||
+ int minDiff = Integer.MAX_VALUE;
|
+ int minDiff = Integer.MAX_VALUE;
|
||||||
+ for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
|
+ for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
|
||||||
+ minDiff = Math.min(limit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
|
+ int chunkRange = entityplayer.playerNaturallySpawnedEvent.getSpawnRadius();
|
||||||
|
+ double rangeScale = (double)((chunkRange * 2 + 1) * (chunkRange * 2 + 1)) / SpawnerCreature.b;
|
||||||
|
+ int scaledLimit = (int)Math.round(rangeScale * limit);
|
||||||
|
+ minDiff = Math.min(scaledLimit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
|
||||||
+ }
|
+ }
|
||||||
+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
|
+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
+
|
+
|
||||||
+ if (difference > 0) { // Paper
|
+ // Paper start - per player mob spawning
|
||||||
if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) {
|
+ if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && difference > 0) {
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
- a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
|
- a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
|
||||||
+ int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
|
+ int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
|
||||||
|
@ -710,15 +714,15 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
}, (entityinsentient, ichunkaccess) -> {
|
}, (entityinsentient, ichunkaccess) -> {
|
||||||
spawnercreature_d.a(entityinsentient, ichunkaccess);
|
spawnercreature_d.a(entityinsentient, ichunkaccess);
|
||||||
+ },
|
+ },
|
||||||
+ limit, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null);
|
+ difference, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null);
|
||||||
+ spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, 0, (keyInMap, valueInMap) -> {
|
+ spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, spawnCount, (keyInMap, valueInMap) -> {
|
||||||
+ return Integer.valueOf(spawnCount + valueInMap.intValue());
|
+ return Integer.valueOf(spawnCount + valueInMap.intValue());
|
||||||
});
|
});
|
||||||
+ } // Paper
|
+ // Paper end - per player mob spawning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,22 +170,34 @@ public final class SpawnerCreature {
|
@@ -140,22 +173,34 @@ public final class SpawnerCreature {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) {
|
public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) {
|
||||||
|
@ -755,7 +759,7 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
while (k < 3) {
|
while (k < 3) {
|
||||||
@@ -195,13 +237,13 @@ public final class SpawnerCreature {
|
@@ -195,13 +240,13 @@ public final class SpawnerCreature {
|
||||||
// Paper start
|
// Paper start
|
||||||
Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2);
|
Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2);
|
||||||
if (doSpawning == null) {
|
if (doSpawning == null) {
|
||||||
|
@ -771,7 +775,7 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
}
|
}
|
||||||
|
|
||||||
entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F);
|
entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F);
|
||||||
@@ -209,13 +251,18 @@ public final class SpawnerCreature {
|
@@ -209,13 +254,18 @@ public final class SpawnerCreature {
|
||||||
groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
|
groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
|
if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
|
||||||
|
@ -793,7 +797,7 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityinsentient.c(k1)) {
|
if (entityinsentient.c(k1)) {
|
||||||
@@ -237,6 +284,7 @@ public final class SpawnerCreature {
|
@@ -237,6 +287,7 @@ public final class SpawnerCreature {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -801,7 +805,7 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
|
private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
|
||||||
@@ -476,8 +524,8 @@ public final class SpawnerCreature {
|
@@ -476,8 +527,8 @@ public final class SpawnerCreature {
|
||||||
|
|
||||||
public static class d {
|
public static class d {
|
||||||
|
|
||||||
|
@ -812,7 +816,7 @@ index 8130e14b5d6c3e8b0a1234668d5c855e82f3a5dc..c5845013a79036704d084cfb903589cb
|
||||||
private final SpawnerCreatureProbabilities c;
|
private final SpawnerCreatureProbabilities c;
|
||||||
private final Object2IntMap<EnumCreatureType> d;
|
private final Object2IntMap<EnumCreatureType> d;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -540,7 +588,7 @@ public final class SpawnerCreature {
|
@@ -540,7 +591,7 @@ public final class SpawnerCreature {
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
private boolean a(EnumCreatureType enumcreaturetype, int limit) {
|
private boolean a(EnumCreatureType enumcreaturetype, int limit) {
|
||||||
|
|
|
@ -77,10 +77,10 @@ index 32d3887e2542c4ebba4a7498167fbe4b497a71ce..7e57a53ec614a2f7d2672edff9d7c0e0
|
||||||
|
|
||||||
public String c() {
|
public String c() {
|
||||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
index eebd4c50a7324250d3ebe7060739a71af4243f72..a6363b73522f9d27534b6e80f4b3789e84316c49 100644
|
index eebd4c50a7324250d3ebe7060739a71af4243f72..319059ba31f3614cc59cd4c4e4fa9242f6e4fe99 100644
|
||||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
@@ -728,6 +728,36 @@ public class ChunkProviderServer extends IChunkProvider {
|
@@ -728,6 +728,37 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||||
boolean flag1 = this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && !world.getPlayers().isEmpty(); // CraftBukkit
|
boolean flag1 = this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && !world.getPlayers().isEmpty(); // CraftBukkit
|
||||||
|
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
|
@ -112,12 +112,13 @@ index eebd4c50a7324250d3ebe7060739a71af4243f72..a6363b73522f9d27534b6e80f4b3789e
|
||||||
+
|
+
|
||||||
+ playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range);
|
+ playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range);
|
||||||
+ player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in isOutsideRange
|
+ player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in isOutsideRange
|
||||||
|
+ player.playerNaturallySpawnedEvent = event;
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end - optimize isOutisdeRange
|
+ // Paper end - optimize isOutisdeRange
|
||||||
this.world.getMethodProfiler().enter("pollingChunks");
|
this.world.getMethodProfiler().enter("pollingChunks");
|
||||||
int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED);
|
int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED);
|
||||||
boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit
|
boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit
|
||||||
@@ -757,15 +787,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
@@ -757,15 +788,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||||
this.world.getMethodProfiler().exit();
|
this.world.getMethodProfiler().exit();
|
||||||
//List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
|
//List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
|
||||||
//Collections.shuffle(list); // Paper
|
//Collections.shuffle(list); // Paper
|
||||||
|
@ -134,7 +135,7 @@ index eebd4c50a7324250d3ebe7060739a71af4243f72..a6363b73522f9d27534b6e80f4b3789e
|
||||||
final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
|
final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
|
||||||
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
||||||
|
|
||||||
@@ -781,9 +803,9 @@ public class ChunkProviderServer extends IChunkProvider {
|
@@ -781,9 +804,9 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||||
Chunk chunk = (Chunk) optional1.get();
|
Chunk chunk = (Chunk) optional1.get();
|
||||||
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
|
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@ Massive update to light to improve performance and chunk loading/generation.
|
||||||
8) Fix NPE risk that crashes server in getting nibble data
|
8) Fix NPE risk that crashes server in getting nibble data
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
index 604e7004b659daed2844ba1a76bf09288ec549e5..ef980f9859d1d7d0d5e13d0d70e998055f92135e 100644
|
index 7c87ef638d538093e944341525a1027be5d15a0e..3a5a9aba111fed8b68818b95332b723ee2bce2ac 100644
|
||||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
@@ -1044,7 +1044,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
@@ -1045,7 +1045,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||||
if (ChunkProviderServer.this.tickDistanceManager()) {
|
if (ChunkProviderServer.this.tickDistanceManager()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue