geforkt von Mirrors/Paper
patches
Dieser Commit ist enthalten in:
Ursprung
a61429bdcf
Commit
7007f67ebb
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -1,99 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 29 May 2020 23:32:14 -0400
|
||||
Subject: [PATCH] Improve Chunk Status Transition Speed
|
||||
|
||||
When a chunk is loaded from disk that has already been generated,
|
||||
the server has to promote the chunk through the system to reach
|
||||
it's current desired status level.
|
||||
|
||||
This results in every single status transition going from the main thread
|
||||
to the world gen threads, only to discover it has no work it actually
|
||||
needs to do.... and then it returns back to main.
|
||||
|
||||
This back and forth costs a lot of time and can really delay chunk loads
|
||||
when the server is under high TPS due to their being a lot of time in
|
||||
between chunk load times, as well as hogs up the chunk threads from doing
|
||||
actual generation and light work.
|
||||
|
||||
Additionally, the whole task system uses a lot of CPU on the server threads anyways.
|
||||
|
||||
So by optimizing status transitions for status's that are already complete,
|
||||
we can run them to the desired level while on main thread (where it has
|
||||
to happen anyways) instead of ever jumping to world gen thread.
|
||||
|
||||
This will improve chunk loading effeciency to be reduced down to the following
|
||||
scenario / path:
|
||||
|
||||
1) MAIN: Chunk Requested, Load Request sent to ChunkTaskManager / IO Queue
|
||||
2) IO: Once position in queue comes, submit read IO data and schedule to chunk task thread
|
||||
3) CHUNK: Once IO is loaded and position in queue comes, deserialize the chunk data, process conversions, submit to main queue
|
||||
4) MAIN: next Chunk Task process (Mid Tick or End Of Tick), load chunk data into world (POI, main thread tasks)
|
||||
5) MAIN: process status transitions all the way to LIGHT, light schedules Threaded task
|
||||
6) SERVER: Light tasks register light enablement for chunk and any lighting needing to be done
|
||||
7) MAIN: Task returns to main, finish processing to FULL/TICKING status
|
||||
|
||||
Previously would have hopped to SERVER around 12+ times there extra.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkHolder {
|
||||
this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key);
|
||||
}
|
||||
// Paper end - optimise isOutsideOfRange
|
||||
+ // Paper start - optimize chunk status progression without jumping through thread pool
|
||||
+ public boolean canAdvanceStatus() {
|
||||
+ ChunkStatus status = getChunkHolderStatus();
|
||||
+ ChunkAccess chunk = getAvailableChunkNow();
|
||||
+ return chunk != null && (status == null || chunk.getStatus().isAtLeastStatus(getNextStatus(status)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// Paper start - no-tick view distance
|
||||
public final LevelChunk getSendingChunk() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return either.mapLeft((list) -> {
|
||||
return (LevelChunk) list.get(list.size() / 2);
|
||||
});
|
||||
- }, this.mainThreadExecutor);
|
||||
+ }, this.mainInvokingExecutor); // Paper
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
ChunkAccess ichunkaccess = (ChunkAccess) optional.get();
|
||||
|
||||
if (ichunkaccess.getStatus().isOrAfter(requiredStatus)) {
|
||||
- CompletableFuture completablefuture1;
|
||||
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture1; // Paper
|
||||
|
||||
if (requiredStatus == ChunkStatus.LIGHT) {
|
||||
completablefuture1 = this.scheduleChunkGeneration(holder, requiredStatus);
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return this.scheduleChunkGeneration(holder, requiredStatus);
|
||||
}
|
||||
}
|
||||
- }, this.mainThreadExecutor);
|
||||
+ }, this.mainInvokingExecutor).thenComposeAsync(CompletableFuture::completedFuture, this.mainInvokingExecutor); // Paper - optimize chunk status progression without jumping through thread pool - ensure main
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
|
||||
});
|
||||
}, (runnable) -> {
|
||||
+ // Paper start - optimize chunk status progression without jumping through thread pool
|
||||
+ if (holder.canAdvanceStatus()) {
|
||||
+ this.mainInvokingExecutor.execute(runnable);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.worldgenMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
|
||||
});
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 7 Jun 2020 19:25:13 -0400
|
||||
Subject: [PATCH] Use seed based lookup for Treasure Maps - Fixes lag from
|
||||
carto/sunken maps
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.worldDataServer.setThundering(thundering);
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public Biome getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) {
|
||||
+ public Biome getBiomeBySeed(int i, int j, int k) { return getUncachedNoiseBiome(i, j, k); } // Paper - OBFHELPER
|
||||
+ @Override public Biome getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) {
|
||||
return this.getChunkSource().getGenerator().getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/MapItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/MapItem.java
|
||||
@@ -0,0 +0,0 @@ public class MapItem extends ComplexItem {
|
||||
|
||||
for (l = 0; l < 128 * i; ++l) {
|
||||
for (i1 = 0; i1 < 128 * i; ++i1) {
|
||||
- abiomebase[l * 128 * i + i1] = worldserver.getBiome(new BlockPos((j / i - 64) * i + i1, 0, (k / i - 64) * i + l));
|
||||
+ abiomebase[l * 128 * i + i1] = worldserver.getBiomeBySeed((j / i - 64) * i + i1, 0, (k / i - 64) * i + l); // Paper
|
||||
}
|
||||
}
|
||||
|
@ -15,17 +15,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final BlockPos ZERO = new BlockPos(0, 0, 0);
|
||||
- private static final int PACKED_X_LENGTH = 1 + Mth.log2(Mth.smallestEncompassingPowerOfTwo(30000000));
|
||||
- private static final int PACKED_Z_LENGTH = BlockPos.PACKED_X_LENGTH;
|
||||
- private static final int PACKED_Y_LENGTH = 64 - BlockPos.PACKED_X_LENGTH - BlockPos.PACKED_Z_LENGTH;
|
||||
- private static final long PACKED_X_MASK = (1L << BlockPos.PACKED_X_LENGTH) - 1L;
|
||||
- private static final long PACKED_Y_MASK = (1L << BlockPos.PACKED_Y_LENGTH) - 1L;
|
||||
- private static final long PACKED_Z_MASK = (1L << BlockPos.PACKED_Z_LENGTH) - 1L;
|
||||
- private static final int Z_OFFSET = BlockPos.PACKED_Y_LENGTH;
|
||||
- private static final int X_OFFSET = BlockPos.PACKED_Y_LENGTH + BlockPos.PACKED_Z_LENGTH;
|
||||
- private static final int PACKED_Z_LENGTH = PACKED_X_LENGTH;
|
||||
- public static final int PACKED_Y_LENGTH = 64 - PACKED_X_LENGTH - PACKED_Z_LENGTH;
|
||||
- private static final long PACKED_X_MASK = (1L << PACKED_X_LENGTH) - 1L;
|
||||
- private static final long PACKED_Y_MASK = (1L << PACKED_Y_LENGTH) - 1L;
|
||||
- private static final long PACKED_Z_MASK = (1L << PACKED_Z_LENGTH) - 1L;
|
||||
- private static final int Y_OFFSET = 0;
|
||||
- private static final int Z_OFFSET = PACKED_Y_LENGTH;
|
||||
- private static final int X_OFFSET = PACKED_Y_LENGTH + PACKED_Z_LENGTH;
|
||||
+ // Paper start - static constants
|
||||
+ private static final int PACKED_X_LENGTH = 26;
|
||||
+ private static final int PACKED_Z_LENGTH = 26;
|
||||
+ private static final int PACKED_Y_LENGTH = 12;
|
||||
+ public static final int PACKED_Y_LENGTH = 12;
|
||||
+ private static final long PACKED_X_MASK = 67108863;
|
||||
+ private static final long PACKED_Y_MASK = 4095;
|
||||
+ private static final long PACKED_Z_MASK = 67108863;
|
||||
@ -50,17 +51,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
}
|
||||
|
||||
public static int getX(long packedPos) {
|
||||
- return (int) (packedPos << 64 - BlockPos.X_OFFSET - BlockPos.PACKED_X_LENGTH >> 64 - BlockPos.PACKED_X_LENGTH);
|
||||
- return (int)(packedPos << 64 - X_OFFSET - PACKED_X_LENGTH >> 64 - PACKED_X_LENGTH);
|
||||
+ return (int) (packedPos >> 38); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static int getY(long packedPos) {
|
||||
- return (int) (packedPos << 64 - BlockPos.PACKED_Y_LENGTH >> 64 - BlockPos.PACKED_Y_LENGTH);
|
||||
- return (int)(packedPos << 64 - PACKED_Y_LENGTH >> 64 - PACKED_Y_LENGTH);
|
||||
+ return (int) ((packedPos << 52) >> 52); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static int getZ(long packedPos) {
|
||||
- return (int) (packedPos << 64 - BlockPos.Z_OFFSET - BlockPos.PACKED_Z_LENGTH >> 64 - BlockPos.PACKED_Z_LENGTH);
|
||||
- return (int)(packedPos << 64 - Z_OFFSET - PACKED_Z_LENGTH >> 64 - PACKED_Z_LENGTH);
|
||||
+ return (int) ((packedPos << 26) >> 38); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
@ -71,15 +72,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
|
||||
public long asLong() {
|
||||
@@ -0,0 +0,0 @@ public class BlockPos extends Vec3i {
|
||||
}
|
||||
|
||||
public static long asLong(int x, int y, int z) { return asLong(x, y, z); } // Paper - OBFHELPER
|
||||
public static long asLong(int x, int y, int z) {
|
||||
- long l = 0L;
|
||||
-
|
||||
- l |= ((long) x & BlockPos.PACKED_X_MASK) << BlockPos.X_OFFSET;
|
||||
- l |= ((long) y & BlockPos.PACKED_Y_MASK) << 0;
|
||||
- l |= ((long) z & BlockPos.PACKED_Z_MASK) << BlockPos.Z_OFFSET;
|
||||
- return l;
|
||||
- l = l | ((long)x & PACKED_X_MASK) << X_OFFSET;
|
||||
- l = l | ((long)y & PACKED_Y_MASK) << 0;
|
||||
- return l | ((long)z & PACKED_Z_MASK) << Z_OFFSET;
|
||||
+ return (((long) x & (long) 67108863) << 38) | (((long) y & (long) 4095)) | (((long) z & (long) 67108863) << 12); // Paper - inline constants and simplify
|
||||
}
|
||||
|
||||
@ -105,7 +104,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ return new SectionPos((int) (packed >> 42), (int) (packed << 44 >> 44), (int) (packed << 22 >> 42)); // Paper
|
||||
}
|
||||
|
||||
public static long offset(long packed, Direction direction) {
|
||||
public static SectionPos bottomOf(ChunkAccess chunk) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPos extends Vec3i {
|
||||
return offset(packed, direction.getStepX(), direction.getStepY(), direction.getStepZ());
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ return (((long) ((int) (packed >> 42) + x) & 4194303L) << 42) | (((long) ((int) (packed << 44 >> 44) + y) & 1048575L)) | (((long) ((int) (packed << 22 >> 42) + z) & 4194303L) << 20); // Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public static int blockToSectionCoord(int coord) {
|
||||
public static int posToSectionCoord(double coord) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPos extends Vec3i {
|
||||
}
|
||||
|
||||
@ -130,8 +130,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- int i = sectionRelative(pos.getX());
|
||||
- int j = sectionRelative(pos.getY());
|
||||
- int k = sectionRelative(pos.getZ());
|
||||
-
|
||||
- return (short) (i << 8 | k << 4 | j << 0);
|
||||
- return (short)(i << 8 | k << 4 | j << 0);
|
||||
+ return (short) ((pos.getX() & 15) << 8 | (pos.getZ() & 15) << 4 | pos.getY() & 15); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
@ -141,29 +140,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
}
|
||||
|
||||
- public int minBlockX() {
|
||||
- return this.x() << 4;
|
||||
+ public final int minBlockX() { // Paper
|
||||
+ return this.getX() << 4; // Paper
|
||||
- return sectionToBlockCoord(this.x());
|
||||
+ public final int minBlockX() { // Paper - make final
|
||||
+ return this.getX() << 4; // Paper - inline
|
||||
}
|
||||
|
||||
- public int minBlockY() {
|
||||
- return this.y() << 4;
|
||||
+ public final int minBlockY() { // Paper
|
||||
+ return this.getY() << 4; // Paper
|
||||
- return sectionToBlockCoord(this.y());
|
||||
+ public final int minBlockY() { // Paper - make final
|
||||
+ return this.getY() << 4; // Paper - inline
|
||||
}
|
||||
|
||||
- public int minBlockZ() {
|
||||
- return this.z() << 4;
|
||||
+ public final int minBlockZ() { // Paper
|
||||
+ return this.getZ() << 4; // Paper
|
||||
- return sectionToBlockCoord(this.z());
|
||||
+ public int minBlockZ() { // Paper - make final
|
||||
+ return this.getZ() << 4; // Paper - inline
|
||||
}
|
||||
|
||||
public int maxBlockX() {
|
||||
@@ -0,0 +0,0 @@ public class SectionPos extends Vec3i {
|
||||
return (this.z() << 4) + 15;
|
||||
}
|
||||
|
||||
+ public static long blockToSection(long i) { return blockToSection(i); } // Paper - OBFHELPER
|
||||
public static long blockToSection(long blockPos) {
|
||||
- return asLong(blockToSectionCoord(BlockPos.getX(blockPos)), blockToSectionCoord(BlockPos.getY(blockPos)), blockToSectionCoord(BlockPos.getZ(blockPos)));
|
||||
+ // b(a(BlockPosition.b(i)), a(BlockPosition.c(i)), a(BlockPosition.d(i)));
|
||||
@ -172,7 +169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
|
||||
public static long getZeroNode(long pos) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPos extends Vec3i {
|
||||
return new ChunkPos(this.x(), this.z());
|
||||
return asLong(blockToSectionCoord(pos.getX()), blockToSectionCoord(pos.getY()), blockToSectionCoord(pos.getZ()));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
@ -180,14 +177,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ return (((long) (i >> 4) & 4194303L) << 42) | (((long) (j >> 4) & 1048575L)) | (((long) (k >> 4) & 4194303L) << 20);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ public static long asLong(int i, int j, int k) { return asLong(i, j, k); } // Paper - OBFHELPER
|
||||
+
|
||||
public static long asLong(int x, int y, int z) {
|
||||
- long l = 0L;
|
||||
-
|
||||
- l |= ((long) x & 4194303L) << 42;
|
||||
- l |= ((long) y & 1048575L) << 0;
|
||||
- l |= ((long) z & 4194303L) << 20;
|
||||
- return l;
|
||||
- l = l | ((long)x & 4194303L) << 42;
|
||||
- l = l | ((long)y & 1048575L) << 0;
|
||||
- return l | ((long)z & 4194303L) << 20;
|
||||
+ return (((long) x & 4194303L) << 42) | (((long) y & 1048575L)) | (((long) z & 4194303L) << 20); // Paper - Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
@ -196,25 +191,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ return (((long) getX() & 4194303L) << 42) | (((long) getY() & 1048575L)) | (((long) getZ() & 4194303L) << 20); // Paper - Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public Stream<BlockPos> blocksInside() {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class SectionPos extends Vec3i {
|
||||
}
|
||||
|
||||
public static Stream<SectionPos> cube(SectionPos center, int radius) {
|
||||
- int j = center.x();
|
||||
- int k = center.y();
|
||||
- int l = center.z();
|
||||
-
|
||||
- return betweenClosedStream(j - radius, k - radius, l - radius, j + radius, k + radius, l + radius);
|
||||
- int i = center.x();
|
||||
- int j = center.y();
|
||||
- int k = center.z();
|
||||
- return betweenClosedStream(i - radius, j - radius, k - radius, i + radius, j + radius, k + radius);
|
||||
+ return betweenClosedStream(center.getX() - radius, center.getY() - radius, center.getZ() - radius, center.getX() + radius, center.getY() + radius, center.getZ() + radius); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static Stream<SectionPos> aroundChunk(ChunkPos center, int radius) {
|
||||
- int j = center.x;
|
||||
- int k = center.z;
|
||||
-
|
||||
- return betweenClosedStream(j - radius, 0, k - radius, j + radius, 15, k + radius);
|
||||
public static Stream<SectionPos> aroundChunk(ChunkPos center, int radius, int minY, int maxY) {
|
||||
- int i = center.x;
|
||||
- int j = center.z;
|
||||
- return betweenClosedStream(i - radius, minY, j - radius, i + radius, maxY - 1, j + radius);
|
||||
+ return betweenClosedStream(center.x - radius, 0, center.z - radius, center.x + radius, 15, center.z + radius); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static Stream<SectionPos> betweenClosedStream(final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ) {
|
||||
public static Stream<SectionPos> betweenClosedStream(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ if (world == null) {
|
||||
+ world = server.getLevel(worldKey);
|
||||
+ }
|
||||
+ ChunkMap chunkMap = world != null ? world.getChunkSource().chunkMap : null;
|
||||
+ net.minecraft.server.level.ChunkMap chunkMap = world != null ? world.getChunkSource().chunkMap : null;
|
||||
+ Object[] backingSet;
|
||||
+ if (chunkMap == null) {
|
||||
+ // Really shouldn't happen...
|
@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 7 Jun 2020 19:25:13 -0400
|
||||
Subject: [PATCH] Use seed based lookup for Treasure Maps - Fixes lag from
|
||||
carto/sunken maps
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/MapItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/MapItem.java
|
||||
@@ -0,0 +0,0 @@ public class MapItem extends ComplexItem {
|
||||
|
||||
for (l = 0; l < 128 * i; ++l) {
|
||||
for (i1 = 0; i1 < 128 * i; ++i1) {
|
||||
- abiomebase[l * 128 * i + i1] = world.getBiome(new BlockPos((j / i - 64) * i + i1, 0, (k / i - 64) * i + l));
|
||||
+ abiomebase[l * 128 * i + i1] = world.getUncachedNoiseBiome((j / i - 64) * i + i1, 0, (k / i - 64) * i + l); // Paper
|
||||
}
|
||||
}
|
||||
|
@ -779,6 +779,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
|
||||
while (k < 3) {
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
// Paper start
|
||||
Boolean doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
|
||||
if (doSpawning == null) {
|
||||
- return;
|
||||
+ return j; // Paper
|
||||
}
|
||||
if (doSpawning && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
|
||||
// Paper end
|
||||
Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type);
|
||||
|
||||
if (entityinsentient == null) {
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren