9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-19 14:59:32 +00:00
Files
LeavesMC/patches/server/0084-Optimize-world-generation-chunk-and-block-access.patch
2023-09-28 18:12:42 +08:00

199 lines
8.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: violetc <58360096+s-yh-china@users.noreply.github.com>
Date: Tue, 18 Jul 2023 13:36:25 +0800
Subject: [PATCH] Optimize world generation chunk and block access
This patch is Powered by Gale(https://github.com/GaleMC/Gale)
diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
index 877498729c66de9aa6a27c9148f7494d7895615c..28386146cada17442d3b3f1517512b95ddcc6a9f 100644
--- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java
+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
@@ -83,6 +83,10 @@ public class WorldGenRegion implements WorldGenLevel {
private Supplier<String> currentlyGenerating;
private final AtomicLong subTickCount = new AtomicLong();
private static final ResourceLocation WORLDGEN_REGION_RANDOM = new ResourceLocation("worldgen_region_random");
+ // Leaves start - optimize world generation chunk and block access
+ private ChunkAccess[] chunksArr;
+ private int minChunkX, minChunkZ;
+ // Leaves end - optimize world generation chunk and block access
public WorldGenRegion(ServerLevel world, List<ChunkAccess> chunks, ChunkStatus status, int placementRadius) {
this.generatingStatus = status;
@@ -105,6 +109,11 @@ public class WorldGenRegion implements WorldGenLevel {
this.lastPos = ((ChunkAccess) chunks.get(chunks.size() - 1)).getPos();
this.structureManager = world.structureManager().forWorldGenRegion(this);
}
+ // Leaves start - optimize world generation chunk and block access
+ this.minChunkX = this.firstPos.x;
+ this.minChunkZ = this.firstPos.z;
+ this.chunksArr = chunks.toArray(new ChunkAccess[0]);
+ // Leaves end - optimize world generation chunk and block access
}
public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) {
@@ -122,8 +131,29 @@ public class WorldGenRegion implements WorldGenLevel {
@Override
public ChunkAccess getChunk(int chunkX, int chunkZ) {
- return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY);
+ // Leaves start - optimize world generation chunk and block access
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeWorldGenerationAccess) {
+ return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY);
+ } else {
+ int x = chunkX - this.minChunkX;
+ int z = chunkZ - this.minChunkZ;
+ int w = this.size;
+
+ if (x >= 0 && z >= 0 && x < w && z < w) {
+ return this.chunksArr[x + z * w];
+ } else {
+ throw new NullPointerException("No chunk exists at " + new ChunkPos(chunkX, chunkZ));
+ }
+ }
+ // Leaves end - optimize world generation chunk and block access
+ }
+
+ // Leaves start - optimize world generation chunk and block access
+ public ChunkAccess getChunk(BlockPos pos) {
+ // Skip checking chunk.getStatus().isAtLeast(ChunkStatus.EMPTY) here, because it is always true
+ return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()));
}
+ // Leaves end - optimize world generation chunk and block access
@Nullable
@Override
@@ -182,7 +212,21 @@ public class WorldGenRegion implements WorldGenLevel {
@Override
public BlockState getBlockState(BlockPos pos) {
- return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos);
+ // Leaves start - optimize world generation chunk and block access
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeWorldGenerationAccess) {
+ return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos);
+ } else {
+ int x = SectionPos.blockToSectionCoord(pos.getX()) - this.minChunkX;
+ int z = SectionPos.blockToSectionCoord(pos.getZ()) - this.minChunkZ;
+ int w = this.size;
+
+ if (x >= 0 && z >= 0 && x < w && z < w) {
+ return this.chunksArr[x + z * w].getBlockState(pos);
+ } else {
+ throw new NullPointerException("No chunk exists at " + new ChunkPos(pos));
+ }
+ }
+ // Leaves end - optimize world generation chunk and block access
}
@Override
diff --git a/src/main/java/top/leavesmc/leaves/lithium/common/util/Pos.java b/src/main/java/top/leavesmc/leaves/lithium/common/util/Pos.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1650846d080ab743aa324a3fe94447e2b3d7ece
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/lithium/common/util/Pos.java
@@ -0,0 +1,104 @@
+
+package top.leavesmc.leaves.lithium.common.util;
+
+import net.minecraft.core.SectionPos;
+import net.minecraft.world.level.LevelHeightAccessor;
+
+public class Pos {
+
+ public static class BlockCoord {
+ public static int getYSize(LevelHeightAccessor view) {
+ return view.getHeight();
+ }
+
+ public static int getMinY(LevelHeightAccessor view) {
+ return view.getMinBuildHeight();
+ }
+
+ public static int getMaxYInclusive(LevelHeightAccessor view) {
+ return view.getMaxBuildHeight() - 1;
+ }
+
+ public static int getMaxYExclusive(LevelHeightAccessor view) {
+ return view.getMaxBuildHeight();
+ }
+
+ public static int getMaxInSectionCoord(int sectionCoord) {
+ return 15 + getMinInSectionCoord(sectionCoord);
+ }
+
+ public static int getMaxYInSectionIndex(LevelHeightAccessor view, int sectionIndex) {
+ return getMaxInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex));
+ }
+
+ public static int getMinInSectionCoord(int sectionCoord) {
+ return SectionPos.sectionToBlockCoord(sectionCoord);
+ }
+
+ public static int getMinYInSectionIndex(LevelHeightAccessor view, int sectionIndex) {
+ return getMinInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex));
+ }
+ }
+
+ public static class ChunkCoord {
+ public static int fromBlockCoord(int blockCoord) {
+ return SectionPos.blockToSectionCoord(blockCoord);
+ }
+
+ public static int fromBlockSize(int i) {
+ return i >> 4; //same method as fromBlockCoord, just be clear about coord/size semantic difference
+ }
+ }
+
+ public static class SectionYCoord {
+ public static int getNumYSections(LevelHeightAccessor view) {
+ return view.getSectionsCount();
+ }
+
+ public static int getMinYSection(LevelHeightAccessor view) {
+ return view.getMinSection();
+ }
+
+ public static int getMaxYSectionInclusive(LevelHeightAccessor view) {
+ return view.getMaxSection() - 1;
+ }
+
+ public static int getMaxYSectionExclusive(LevelHeightAccessor view) {
+ return view.getMaxSection();
+ }
+
+ public static int fromSectionIndex(LevelHeightAccessor view, int sectionCoord) {
+ return sectionCoord + SectionYCoord.getMinYSection(view);
+ }
+
+ public static int fromBlockCoord(int blockCoord) {
+ return SectionPos.blockToSectionCoord(blockCoord);
+ }
+ }
+
+ public static class SectionYIndex {
+ public static int getNumYSections(LevelHeightAccessor view) {
+ return view.getSectionsCount();
+ }
+
+ public static int getMinYSectionIndex(LevelHeightAccessor view) {
+ return 0;
+ }
+
+ public static int getMaxYSectionIndexInclusive(LevelHeightAccessor view) {
+ return view.getSectionsCount() - 1;
+ }
+
+ public static int getMaxYSectionIndexExclusive(LevelHeightAccessor view) {
+ return view.getSectionsCount();
+ }
+
+ public static int fromSectionCoord(LevelHeightAccessor view, int sectionCoord) {
+ return sectionCoord - SectionYCoord.getMinYSection(view);
+ }
+
+ public static int fromBlockCoord(LevelHeightAccessor view, int blockCoord) {
+ return fromSectionCoord(view, SectionPos.blockToSectionCoord(blockCoord));
+ }
+ }
+}