9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-23 00:39:16 +00:00
Files
DivineMC/divinemc-server/minecraft-patches/features/0011-World-and-Noise-gen-optimizations.patch
2025-02-22 15:13:16 +03:00

919 lines
46 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 1 Feb 2025 00:09:39 +0300
Subject: [PATCH] World and Noise gen optimizations
diff --git a/net/minecraft/world/level/ChunkPos.java b/net/minecraft/world/level/ChunkPos.java
index 55ce935a2fab7e32904d9ff599867269035d703f..4fa84743ba7f570f11a4979b7e5381478c844aef 100644
--- a/net/minecraft/world/level/ChunkPos.java
+++ b/net/minecraft/world/level/ChunkPos.java
@@ -110,7 +110,12 @@ public class ChunkPos {
@Override
public boolean equals(Object other) {
- return this == other || other instanceof ChunkPos chunkPos && this.x == chunkPos.x && this.z == chunkPos.z;
+ // DivineMC start - Use standard equals
+ if (other == this) return true;
+ if (other == null || other.getClass() != this.getClass()) return false;
+ ChunkPos thatPos = (ChunkPos) other;
+ return this.x == thatPos.x && this.z == thatPos.z;
+ // DivineMC end - Use standard equals
}
public int getMiddleBlockX() {
diff --git a/net/minecraft/world/level/biome/TheEndBiomeSource.java b/net/minecraft/world/level/biome/TheEndBiomeSource.java
index cf3172be76fa4c7987ed569138439ff42f92fa7f..bfc65a4d8d1e64f42ff13508020e5e0260e83b98 100644
--- a/net/minecraft/world/level/biome/TheEndBiomeSource.java
+++ b/net/minecraft/world/level/biome/TheEndBiomeSource.java
@@ -27,6 +27,33 @@ public class TheEndBiomeSource extends BiomeSource {
private final Holder<Biome> islands;
private final Holder<Biome> barrens;
+ // DivineMC start - World gen optimizations
+ private Holder<Biome> getBiomeForNoiseGenVanilla(int x, int y, int z, Climate.Sampler noise) {
+ int i = QuartPos.toBlock(x);
+ int j = QuartPos.toBlock(y);
+ int k = QuartPos.toBlock(z);
+ int l = SectionPos.blockToSectionCoord(i);
+ int m = SectionPos.blockToSectionCoord(k);
+ if ((long)l * (long)l + (long)m * (long)m <= 4096L) {
+ return this.end;
+ } else {
+ int n = (SectionPos.blockToSectionCoord(i) * 2 + 1) * 8;
+ int o = (SectionPos.blockToSectionCoord(k) * 2 + 1) * 8;
+ double d = noise.erosion().compute(new DensityFunction.SinglePointContext(n, j, o));
+ if (d > 0.25D) {
+ return this.highlands;
+ } else if (d >= -0.0625D) {
+ return this.midlands;
+ } else {
+ return d < -0.21875D ? this.islands : this.barrens;
+ }
+ }
+ }
+
+ private final ThreadLocal<it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<Holder<Biome>>> cache = ThreadLocal.withInitial(it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap::new);
+ private final int cacheCapacity = 1024;
+ // DivineMC end - World gen optimizations
+
public static TheEndBiomeSource create(HolderGetter<Biome> biomeGetter) {
return new TheEndBiomeSource(
biomeGetter.getOrThrow(Biomes.THE_END),
@@ -55,26 +82,24 @@ public class TheEndBiomeSource extends BiomeSource {
return CODEC;
}
+ // DivineMC start - World gen optimizations
@Override
- public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
- int blockPosX = QuartPos.toBlock(x);
- int blockPosY = QuartPos.toBlock(y);
- int blockPosZ = QuartPos.toBlock(z);
- int sectionPosX = SectionPos.blockToSectionCoord(blockPosX);
- int sectionPosZ = SectionPos.blockToSectionCoord(blockPosZ);
- if ((long)sectionPosX * sectionPosX + (long)sectionPosZ * sectionPosZ <= 4096L) {
- return this.end;
+ public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler multiNoiseSampler) {
+ final long key = net.minecraft.world.level.ChunkPos.asLong(biomeX, biomeZ);
+ final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<Holder<Biome>> cacheThreadLocal = cache.get();
+ final Holder<Biome> biome = cacheThreadLocal.get(key);
+ if (biome != null) {
+ return biome;
} else {
- int i = (SectionPos.blockToSectionCoord(blockPosX) * 2 + 1) * 8;
- int i1 = (SectionPos.blockToSectionCoord(blockPosZ) * 2 + 1) * 8;
- double d = sampler.erosion().compute(new DensityFunction.SinglePointContext(i, blockPosY, i1));
- if (d > 0.25) {
- return this.highlands;
- } else if (d >= -0.0625) {
- return this.midlands;
- } else {
- return d < -0.21875 ? this.islands : this.barrens;
+ final Holder<Biome> gennedBiome = getBiomeForNoiseGenVanilla(biomeX, biomeY, biomeZ, multiNoiseSampler);
+ cacheThreadLocal.put(key, gennedBiome);
+ if (cacheThreadLocal.size() > cacheCapacity) {
+ for (int i = 0; i < cacheCapacity / 16; i ++) {
+ cacheThreadLocal.removeFirst();
+ }
}
+ return gennedBiome;
}
}
+ // DivineMC end - World gen optimizations
}
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
index c83d0667b19830304f22319a46a23422a8766790..5bc74d860923d6485593cacb67d4c18e20db2634 100644
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -23,6 +23,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
public short tickingFluidCount;
public final PalettedContainer<BlockState> states;
private PalettedContainer<Holder<Biome>> biomes; // CraftBukkit - read/write
+ private static final int sliceSize = 4; // DivineMC - World and Noise gen optimizations
// Paper start - block counting
private static final it.unimi.dsi.fastutil.shorts.ShortArrayList FULL_LIST = new it.unimi.dsi.fastutil.shorts.ShortArrayList(16*16*16);
@@ -312,13 +313,15 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
PalettedContainer<Holder<Biome>> palettedContainer = this.biomes.recreate();
int i = 4;
- for (int i1 = 0; i1 < 4; i1++) {
- for (int i2 = 0; i2 < 4; i2++) {
- for (int i3 = 0; i3 < 4; i3++) {
- palettedContainer.getAndSetUnchecked(i1, i2, i3, biomeResolver.getNoiseBiome(x + i1, y + i2, z + i3, climateSampler));
+ // DivineMC start - World and Noise gen optimizations
+ for (int posY = 0; posY < sliceSize; ++posY) {
+ for (int posZ = 0; posZ < sliceSize; ++posZ) {
+ for (int posX = 0; posX < sliceSize; ++posX) {
+ palettedContainer.getAndSetUnchecked(posX, posY, posZ, biomeResolver.getNoiseBiome(x + posX, y + posY, z + posZ, climateSampler));
}
}
}
+ // DivineMC end - World and Noise gen optimizations
this.biomes = palettedContainer;
}
diff --git a/net/minecraft/world/level/levelgen/Aquifer.java b/net/minecraft/world/level/levelgen/Aquifer.java
index c62a15ea4a1bb22e7bcc2fc544acf8a601892029..43dd5f63fe7834d41874ea30651f3fb738d88ba6 100644
--- a/net/minecraft/world/level/levelgen/Aquifer.java
+++ b/net/minecraft/world/level/levelgen/Aquifer.java
@@ -85,6 +85,15 @@ public interface Aquifer {
private final int minGridZ;
private final int gridSizeX;
private final int gridSizeZ;
+ // DivineMC start - World gen optimizations
+ private int c2me$dist1;
+ private int c2me$dist2;
+ private int c2me$dist3;
+ private long c2me$pos1;
+ private long c2me$pos2;
+ private long c2me$pos3;
+ private double c2me$mutableDoubleThingy;
+ // DivineMC end - World gen optimizations
private static final int[][] SURFACE_SAMPLING_OFFSETS_IN_CHUNKS = new int[][]{
{0, 0}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}
};
@@ -120,6 +129,36 @@ public interface Aquifer {
this.aquiferCache = new Aquifer.FluidStatus[i4];
this.aquiferLocationCache = new long[i4];
Arrays.fill(this.aquiferLocationCache, Long.MAX_VALUE);
+ // DivineMC start - World gen optimizations
+ if (this.aquiferLocationCache.length % (this.gridSizeX * this.gridSizeZ) != 0) {
+ throw new AssertionError("Array length");
+ }
+
+ int sizeY = this.aquiferLocationCache.length / (this.gridSizeX * this.gridSizeZ);
+
+ final RandomSource random = org.bxteam.divinemc.util.RandomUtil.getRandom(this.positionalRandomFactory);
+ // index: y, z, x
+ for (int y = 0; y < sizeY; y++) {
+ for (int z = 0; z < this.gridSizeZ; z++) {
+ for (int x = 0; x < this.gridSizeX; x++) {
+ final int x1 = x + this.minGridX;
+ final int y1 = y + this.minGridY;
+ final int z1 = z + this.minGridZ;
+ org.bxteam.divinemc.util.RandomUtil.derive(this.positionalRandomFactory, random, x1, y1, z1);
+ int x2 = x1 * 16 + random.nextInt(10);
+ int y2 = y1 * 12 + random.nextInt(9);
+ int z2 = z1 * 16 + random.nextInt(10);
+ int index = this.getIndex(x1, y1, z1);
+ this.aquiferLocationCache[index] = BlockPos.asLong(x2, y2, z2);
+ }
+ }
+ }
+ for (long blockPosition : this.aquiferLocationCache) {
+ if (blockPosition == Long.MAX_VALUE) {
+ throw new AssertionError("Array initialization");
+ }
+ }
+ // DivineMC end - World gen optimizations
}
private int getIndex(int gridX, int gridY, int gridZ) {
@@ -132,140 +171,24 @@ public interface Aquifer {
@Nullable
@Override
public BlockState computeSubstance(DensityFunction.FunctionContext context, double substance) {
+ // DivineMC start - World gen optimizations
int i = context.blockX();
- int i1 = context.blockY();
- int i2 = context.blockZ();
+ int j = context.blockY();
+ int k = context.blockZ();
if (substance > 0.0) {
this.shouldScheduleFluidUpdate = false;
return null;
} else {
- Aquifer.FluidStatus fluidStatus = this.globalFluidPicker.computeFluid(i, i1, i2);
- if (fluidStatus.at(i1).is(Blocks.LAVA)) {
+ Aquifer.FluidStatus fluidLevel = this.globalFluidPicker.computeFluid(i, j, k);
+ if (fluidLevel.at(j).is(Blocks.LAVA)) {
this.shouldScheduleFluidUpdate = false;
return Blocks.LAVA.defaultBlockState();
} else {
- int i3 = Math.floorDiv(i - 5, 16);
- int i4 = Math.floorDiv(i1 + 1, 12);
- int i5 = Math.floorDiv(i2 - 5, 16);
- int i6 = Integer.MAX_VALUE;
- int i7 = Integer.MAX_VALUE;
- int i8 = Integer.MAX_VALUE;
- int i9 = Integer.MAX_VALUE;
- long l = 0L;
- long l1 = 0L;
- long l2 = 0L;
- long l3 = 0L;
-
- for (int i10 = 0; i10 <= 1; i10++) {
- for (int i11 = -1; i11 <= 1; i11++) {
- for (int i12 = 0; i12 <= 1; i12++) {
- int i13 = i3 + i10;
- int i14 = i4 + i11;
- int i15 = i5 + i12;
- int index = this.getIndex(i13, i14, i15);
- long l4 = this.aquiferLocationCache[index];
- long l5;
- if (l4 != Long.MAX_VALUE) {
- l5 = l4;
- } else {
- RandomSource randomSource = this.positionalRandomFactory.at(i13, i14, i15);
- l5 = BlockPos.asLong(
- i13 * 16 + randomSource.nextInt(10), i14 * 12 + randomSource.nextInt(9), i15 * 16 + randomSource.nextInt(10)
- );
- this.aquiferLocationCache[index] = l5;
- }
-
- int i16 = BlockPos.getX(l5) - i;
- int i17 = BlockPos.getY(l5) - i1;
- int i18 = BlockPos.getZ(l5) - i2;
- int i19 = i16 * i16 + i17 * i17 + i18 * i18;
- if (i6 >= i19) {
- l3 = l2;
- l2 = l1;
- l1 = l;
- l = l5;
- i9 = i8;
- i8 = i7;
- i7 = i6;
- i6 = i19;
- } else if (i7 >= i19) {
- l3 = l2;
- l2 = l1;
- l1 = l5;
- i9 = i8;
- i8 = i7;
- i7 = i19;
- } else if (i8 >= i19) {
- l3 = l2;
- l2 = l5;
- i9 = i8;
- i8 = i19;
- } else if (i9 >= i19) {
- l3 = l5;
- i9 = i19;
- }
- }
- }
- }
-
- Aquifer.FluidStatus aquiferStatus = this.getAquiferStatus(l);
- double d = similarity(i6, i7);
- BlockState blockState = aquiferStatus.at(i1);
- if (d <= 0.0) {
- if (d >= FLOWING_UPDATE_SIMULARITY) {
- Aquifer.FluidStatus aquiferStatus1 = this.getAquiferStatus(l1);
- this.shouldScheduleFluidUpdate = !aquiferStatus.equals(aquiferStatus1);
- } else {
- this.shouldScheduleFluidUpdate = false;
- }
-
- return blockState;
- } else if (blockState.is(Blocks.WATER) && this.globalFluidPicker.computeFluid(i, i1 - 1, i2).at(i1 - 1).is(Blocks.LAVA)) {
- this.shouldScheduleFluidUpdate = true;
- return blockState;
- } else {
- MutableDouble mutableDouble = new MutableDouble(Double.NaN);
- Aquifer.FluidStatus aquiferStatus2 = this.getAquiferStatus(l1);
- double d1 = d * this.calculatePressure(context, mutableDouble, aquiferStatus, aquiferStatus2);
- if (substance + d1 > 0.0) {
- this.shouldScheduleFluidUpdate = false;
- return null;
- } else {
- Aquifer.FluidStatus aquiferStatus3 = this.getAquiferStatus(l2);
- double d2 = similarity(i6, i8);
- if (d2 > 0.0) {
- double d3 = d * d2 * this.calculatePressure(context, mutableDouble, aquiferStatus, aquiferStatus3);
- if (substance + d3 > 0.0) {
- this.shouldScheduleFluidUpdate = false;
- return null;
- }
- }
-
- double d3 = similarity(i7, i8);
- if (d3 > 0.0) {
- double d4 = d * d3 * this.calculatePressure(context, mutableDouble, aquiferStatus2, aquiferStatus3);
- if (substance + d4 > 0.0) {
- this.shouldScheduleFluidUpdate = false;
- return null;
- }
- }
-
- boolean flag = !aquiferStatus.equals(aquiferStatus2);
- boolean flag1 = d3 >= FLOWING_UPDATE_SIMULARITY && !aquiferStatus2.equals(aquiferStatus3);
- boolean flag2 = d2 >= FLOWING_UPDATE_SIMULARITY && !aquiferStatus.equals(aquiferStatus3);
- if (!flag && !flag1 && !flag2) {
- this.shouldScheduleFluidUpdate = d2 >= FLOWING_UPDATE_SIMULARITY
- && similarity(i6, i9) >= FLOWING_UPDATE_SIMULARITY
- && !aquiferStatus.equals(this.getAquiferStatus(l3));
- } else {
- this.shouldScheduleFluidUpdate = true;
- }
-
- return blockState;
- }
- }
+ aquiferExtracted$refreshDistPosIdx(i, j, k);
+ return aquiferExtracted$applyPost(context, substance, j, i, k);
}
}
+ // DivineMC end - World gen optimizations
}
@Override
@@ -278,65 +201,28 @@ public interface Aquifer {
return 1.0 - Math.abs(secondDistance - firstDistance) / 25.0;
}
+ // DivineMC start - World gen optimizations
private double calculatePressure(
- DensityFunction.FunctionContext context, MutableDouble substance, Aquifer.FluidStatus firstFluid, Aquifer.FluidStatus secondFluid
+ DensityFunction.FunctionContext context, MutableDouble substance, Aquifer.FluidStatus fluidLevel, Aquifer.FluidStatus fluidLevel2 // DivineMC - rename args
) {
int i = context.blockY();
- BlockState blockState = firstFluid.at(i);
- BlockState blockState1 = secondFluid.at(i);
- if ((!blockState.is(Blocks.LAVA) || !blockState1.is(Blocks.WATER)) && (!blockState.is(Blocks.WATER) || !blockState1.is(Blocks.LAVA))) {
- int abs = Math.abs(firstFluid.fluidLevel - secondFluid.fluidLevel);
+ BlockState blockState = fluidLevel.at(i);
+ BlockState blockState2 = fluidLevel2.at(i);
+ if ((!blockState.is(Blocks.LAVA) || !blockState2.is(Blocks.WATER)) && (!blockState.is(Blocks.WATER) || !blockState2.is(Blocks.LAVA))) {
+ int abs = Math.abs(fluidLevel.fluidLevel - fluidLevel2.fluidLevel);
if (abs == 0) {
return 0.0;
} else {
- double d = 0.5 * (firstFluid.fluidLevel + secondFluid.fluidLevel);
- double d1 = i + 0.5 - d;
- double d2 = abs / 2.0;
- double d3 = 0.0;
- double d4 = 2.5;
- double d5 = 1.5;
- double d6 = 3.0;
- double d7 = 10.0;
- double d8 = 3.0;
- double d9 = d2 - Math.abs(d1);
- double d11;
- if (d1 > 0.0) {
- double d10 = 0.0 + d9;
- if (d10 > 0.0) {
- d11 = d10 / 1.5;
- } else {
- d11 = d10 / 2.5;
- }
- } else {
- double d10 = 3.0 + d9;
- if (d10 > 0.0) {
- d11 = d10 / 3.0;
- } else {
- d11 = d10 / 10.0;
- }
- }
-
- double d10x = 2.0;
- double d12;
- if (!(d11 < -2.0) && !(d11 > 2.0)) {
- double value = substance.getValue();
- if (Double.isNaN(value)) {
- double d13 = this.barrierNoise.compute(context);
- substance.setValue(d13);
- d12 = d13;
- } else {
- d12 = value;
- }
- } else {
- d12 = 0.0;
- }
+ double d = 0.5 * (double)(fluidLevel.fluidLevel + fluidLevel2.fluidLevel);
+ final double q = aquiferExtracted$getQ(i, d, abs);
- return 2.0 * (d12 + d11);
+ return aquiferExtracted$postCalculateDensity(context, substance, q);
}
} else {
return 2.0;
}
}
+ // DivineMC end - World gen optimizations
private int gridX(int x) {
return Math.floorDiv(x, 16);
@@ -350,23 +236,25 @@ public interface Aquifer {
return Math.floorDiv(z, 16);
}
- private Aquifer.FluidStatus getAquiferStatus(long packedPos) {
- int x = BlockPos.getX(packedPos);
- int y = BlockPos.getY(packedPos);
- int z = BlockPos.getZ(packedPos);
- int i = this.gridX(x);
- int i1 = this.gridY(y);
- int i2 = this.gridZ(z);
- int index = this.getIndex(i, i1, i2);
- Aquifer.FluidStatus fluidStatus = this.aquiferCache[index];
- if (fluidStatus != null) {
- return fluidStatus;
+ // DivineMC start - World gen optimizations
+ private Aquifer.FluidStatus getAquiferStatus(long pos) {
+ int i = BlockPos.getX(pos);
+ int j = BlockPos.getY(pos);
+ int k = BlockPos.getZ(pos);
+ int l = i >> 4; // C2ME - inline: floorDiv(i, 16)
+ int m = Math.floorDiv(j, 12); // C2ME - inline
+ int n = k >> 4; // C2ME - inline: floorDiv(k, 16)
+ int o = this.getIndex(l, m, n);
+ Aquifer.FluidStatus fluidLevel = this.aquiferCache[o];
+ if (fluidLevel != null) {
+ return fluidLevel;
} else {
- Aquifer.FluidStatus fluidStatus1 = this.computeFluid(x, y, z);
- this.aquiferCache[index] = fluidStatus1;
- return fluidStatus1;
+ Aquifer.FluidStatus fluidLevel2 = this.computeFluid(i, j, k);
+ this.aquiferCache[o] = fluidLevel2;
+ return fluidLevel2;
}
}
+ // DivineMC end - World gen optimizations
private Aquifer.FluidStatus computeFluid(int x, int y, int z) {
Aquifer.FluidStatus fluidStatus = this.globalFluidPicker.computeFluid(x, y, z);
@@ -406,23 +294,22 @@ public interface Aquifer {
return new Aquifer.FluidStatus(i7, this.computeFluidType(x, y, z, fluidStatus, i7));
}
+ // DivineMC start - World gen optimizations
private int computeSurfaceLevel(int x, int y, int z, Aquifer.FluidStatus fluidStatus, int maxSurfaceLevel, boolean fluidPresent) {
- DensityFunction.SinglePointContext singlePointContext = new DensityFunction.SinglePointContext(x, y, z);
+ DensityFunction.SinglePointContext unblendedNoisePos = new DensityFunction.SinglePointContext(x, y, z);
double d;
double d1;
- if (OverworldBiomeBuilder.isDeepDarkRegion(this.erosion, this.depth, singlePointContext)) {
+ if (OverworldBiomeBuilder.isDeepDarkRegion(this.erosion, this.depth, unblendedNoisePos)) {
d = -1.0;
d1 = -1.0;
} else {
int i = maxSurfaceLevel + 8 - y;
- int i1 = 64;
- double d2 = fluidPresent ? Mth.clampedMap((double)i, 0.0, 64.0, 1.0, 0.0) : 0.0;
- double d3 = Mth.clamp(this.fluidLevelFloodednessNoise.compute(singlePointContext), -1.0, 1.0);
- double d4 = Mth.map(d2, 1.0, 0.0, -0.3, 0.8);
- double d5 = Mth.map(d2, 1.0, 0.0, -0.8, 0.4);
- d = d3 - d5;
- d1 = d3 - d4;
+ double f = fluidPresent ? Mth.clampedLerp(1.0, 0.0, ((double) i) / 64.0) : 0.0; // inline
+ double g = Mth.clamp(this.fluidLevelFloodednessNoise.compute(unblendedNoisePos), -1.0, 1.0);
+ d = g + 0.8 + (f - 1.0) * 1.2; // inline
+ d1 = g + 0.3 + (f - 1.0) * 1.1; // inline
}
+ // DivineMC end - World gen optimizations
int i;
if (d1 > 0.0) {
@@ -466,5 +353,183 @@ public interface Aquifer {
return blockState;
}
+
+ // DivineMC start - World gen optimizations
+ private @org.jetbrains.annotations.Nullable BlockState aquiferExtracted$applyPost(DensityFunction.FunctionContext pos, double density, int j, int i, int k) {
+ Aquifer.FluidStatus fluidLevel2 = this.getAquiferStatus(this.c2me$pos1);
+ double d = similarity(this.c2me$dist1, this.c2me$dist2);
+ BlockState blockState = fluidLevel2.at(j);
+ if (d <= 0.0) {
+ this.shouldScheduleFluidUpdate = d >= FLOWING_UPDATE_SIMULARITY;
+ return blockState;
+ } else if (blockState.is(Blocks.WATER) && this.globalFluidPicker.computeFluid(i, j - 1, k).at(j - 1).is(Blocks.LAVA)) {
+ this.shouldScheduleFluidUpdate = true;
+ return blockState;
+ } else {
+ this.c2me$mutableDoubleThingy = Double.NaN;
+ Aquifer.FluidStatus fluidLevel3 = this.getAquiferStatus(this.c2me$pos2);
+ double e = d * this.c2me$calculateDensityModified(pos, fluidLevel2, fluidLevel3);
+ if (density + e > 0.0) {
+ this.shouldScheduleFluidUpdate = false;
+ return null;
+ } else {
+ return aquiferExtracted$getFinalBlockState(pos, density, d, fluidLevel2, fluidLevel3, blockState);
+ }
+ }
+ }
+
+ private BlockState aquiferExtracted$getFinalBlockState(DensityFunction.FunctionContext pos, double density, double d, Aquifer.FluidStatus fluidLevel2, Aquifer.FluidStatus fluidLevel3, BlockState blockState) {
+ Aquifer.FluidStatus fluidLevel4 = this.getAquiferStatus(this.c2me$pos3);
+ double f = similarity(this.c2me$dist1, this.c2me$dist3);
+ if (aquiferExtracted$extractedCheckFG(pos, density, d, fluidLevel2, f, fluidLevel4)) return null;
+
+ double g = similarity(this.c2me$dist2, this.c2me$dist3);
+ if (aquiferExtracted$extractedCheckFG(pos, density, d, fluidLevel3, g, fluidLevel4)) return null;
+
+ this.shouldScheduleFluidUpdate = true;
+ return blockState;
+ }
+
+ private boolean aquiferExtracted$extractedCheckFG(DensityFunction.FunctionContext pos, double density, double d, Aquifer.FluidStatus fluidLevel2, double f, Aquifer.FluidStatus fluidLevel4) {
+ if (f > 0.0) {
+ double g = d * f * this.c2me$calculateDensityModified(pos, fluidLevel2, fluidLevel4);
+ if (density + g > 0.0) {
+ this.shouldScheduleFluidUpdate = false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void aquiferExtracted$refreshDistPosIdx(int x, int y, int z) {
+ int gx = (x - 5) >> 4;
+ int gy = Math.floorDiv(y + 1, 12);
+ int gz = (z - 5) >> 4;
+ int dist1 = Integer.MAX_VALUE;
+ int dist2 = Integer.MAX_VALUE;
+ int dist3 = Integer.MAX_VALUE;
+ long pos1 = 0;
+ long pos2 = 0;
+ long pos3 = 0;
+
+ for (int offY = -1; offY <= 1; ++offY) {
+ for (int offZ = 0; offZ <= 1; ++offZ) {
+ for (int offX = 0; offX <= 1; ++offX) {
+ int posIdx = this.getIndex(gx + offX, gy + offY, gz + offZ);
+
+ long position = this.aquiferLocationCache[posIdx];
+
+ int dx = BlockPos.getX(position) - x;
+ int dy = BlockPos.getY(position) - y;
+ int dz = BlockPos.getZ(position) - z;
+ int dist = dx * dx + dy * dy + dz * dz;
+
+ if (dist3 >= dist) {
+ pos3 = position;
+ dist3 = dist;
+ }
+ if (dist2 >= dist) {
+ pos3 = pos2;
+ dist3 = dist2;
+ pos2 = position;
+ dist2 = dist;
+ }
+ if (dist1 >= dist) {
+ pos2 = pos1;
+ dist2 = dist1;
+ pos1 = position;
+ dist1 = dist;
+ }
+ }
+ }
+ }
+
+ this.c2me$dist1 = dist1;
+ this.c2me$dist2 = dist2;
+ this.c2me$dist3 = dist3;
+ this.c2me$pos1 = pos1;
+ this.c2me$pos2 = pos2;
+ this.c2me$pos3 = pos3;
+ }
+
+ private double c2me$calculateDensityModified(
+ DensityFunction.FunctionContext pos, Aquifer.FluidStatus fluidLevel, Aquifer.FluidStatus fluidLevel2
+ ) {
+ int i = pos.blockY();
+ BlockState blockState = fluidLevel.at(i);
+ BlockState blockState2 = fluidLevel2.at(i);
+ if ((!blockState.is(Blocks.LAVA) || !blockState2.is(Blocks.WATER)) && (!blockState.is(Blocks.WATER) || !blockState2.is(Blocks.LAVA))) {
+ int j = Math.abs(fluidLevel.fluidLevel - fluidLevel2.fluidLevel);
+ if (j == 0) {
+ return 0.0;
+ } else {
+ double d = 0.5 * (double)(fluidLevel.fluidLevel + fluidLevel2.fluidLevel);
+ final double q = aquiferExtracted$getQ(i, d, j);
+
+ return aquiferExtracted$postCalculateDensityModified(pos, q);
+ }
+ } else {
+ return 2.0;
+ }
+ }
+
+ private double aquiferExtracted$postCalculateDensity(DensityFunction.FunctionContext pos, MutableDouble mutableDouble, double q) {
+ double r;
+ if (!(q < -2.0) && !(q > 2.0)) {
+ double s = mutableDouble.getValue();
+ if (Double.isNaN(s)) {
+ double t = this.barrierNoise.compute(pos);
+ mutableDouble.setValue(t);
+ r = t;
+ } else {
+ r = s;
+ }
+ } else {
+ r = 0.0;
+ }
+
+ return 2.0 * (r + q);
+ }
+
+ private double aquiferExtracted$postCalculateDensityModified(DensityFunction.FunctionContext pos, double q) {
+ double r;
+ if (!(q < -2.0) && !(q > 2.0)) {
+ double s = this.c2me$mutableDoubleThingy;
+ if (Double.isNaN(s)) {
+ double t = this.barrierNoise.compute(pos);
+ this.c2me$mutableDoubleThingy = t;
+ r = t;
+ } else {
+ r = s;
+ }
+ } else {
+ r = 0.0;
+ }
+
+ return 2.0 * (r + q);
+ }
+
+ private static double aquiferExtracted$getQ(double i, double d, double j) {
+ double e = i + 0.5 - d;
+ double f = j / 2.0;
+ double o = f - Math.abs(e);
+ double q;
+ if (e > 0.0) {
+ if (o > 0.0) {
+ q = o / 1.5;
+ } else {
+ q = o / 2.5;
+ }
+ } else {
+ double p = 3.0 + o;
+ if (p > 0.0) {
+ q = p / 3.0;
+ } else {
+ q = p / 10.0;
+ }
+ }
+ return q;
+ }
+ // DivineMC end - World gen optimizations
}
}
diff --git a/net/minecraft/world/level/levelgen/Beardifier.java b/net/minecraft/world/level/levelgen/Beardifier.java
index 131923282c9ecbcb1d7f45a826da907c02bd2716..36dd3eb0cb29d546531aec91a9c486be09975797 100644
--- a/net/minecraft/world/level/levelgen/Beardifier.java
+++ b/net/minecraft/world/level/levelgen/Beardifier.java
@@ -29,6 +29,17 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
});
private final ObjectListIterator<Beardifier.Rigid> pieceIterator;
private final ObjectListIterator<JigsawJunction> junctionIterator;
+ // DivineMC start - World gen optimizations
+ private Beardifier.Rigid[] c2me$pieceArray;
+ private JigsawJunction[] c2me$junctionArray;
+
+ private void c2me$initArrays() {
+ this.c2me$pieceArray = com.google.common.collect.Iterators.toArray(this.pieceIterator, Beardifier.Rigid.class);
+ this.pieceIterator.back(Integer.MAX_VALUE);
+ this.c2me$junctionArray = com.google.common.collect.Iterators.toArray(this.junctionIterator, JigsawJunction.class);
+ this.junctionIterator.back(Integer.MAX_VALUE);
+ }
+ // DivineMC end - World gen optimizations
public static Beardifier forStructuresInChunk(StructureManager structureManager, ChunkPos chunkPos) {
int minBlockX = chunkPos.getMinBlockX();
@@ -76,50 +87,44 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
this.junctionIterator = junctionIterator;
}
+ // DivineMC start - World gen optimizations
@Override
public double compute(DensityFunction.FunctionContext context) {
+ if (this.c2me$pieceArray == null || this.c2me$junctionArray == null) {
+ this.c2me$initArrays();
+ }
int i = context.blockX();
- int i1 = context.blockY();
- int i2 = context.blockZ();
+ int j = context.blockY();
+ int k = context.blockZ();
double d = 0.0;
- while (this.pieceIterator.hasNext()) {
- Beardifier.Rigid rigid = this.pieceIterator.next();
- BoundingBox boundingBox = rigid.box();
- int groundLevelDelta = rigid.groundLevelDelta();
- int max = Math.max(0, Math.max(boundingBox.minX() - i, i - boundingBox.maxX()));
- int max1 = Math.max(0, Math.max(boundingBox.minZ() - i2, i2 - boundingBox.maxZ()));
- int i3 = boundingBox.minY() + groundLevelDelta;
- int i4 = i1 - i3;
-
- int i5 = switch (rigid.terrainAdjustment()) {
- case NONE -> 0;
- case BURY, BEARD_THIN -> i4;
- case BEARD_BOX -> Math.max(0, Math.max(i3 - i1, i1 - boundingBox.maxY()));
- case ENCAPSULATE -> Math.max(0, Math.max(boundingBox.minY() - i1, i1 - boundingBox.maxY()));
- };
+ for (Beardifier.Rigid piece : this.c2me$pieceArray) {
+ BoundingBox blockBox = piece.box();
+ int l = piece.groundLevelDelta();
+ int m = Math.max(0, Math.max(blockBox.minX() - i, i - blockBox.maxX()));
+ int n = Math.max(0, Math.max(blockBox.minZ() - k, k - blockBox.maxZ()));
+ int o = blockBox.minY() + l;
+ int p = j - o;
- d += switch (rigid.terrainAdjustment()) {
+ d += switch (piece.terrainAdjustment()) { // 2 switch statement merged
case NONE -> 0.0;
- case BURY -> getBuryContribution(max, i5 / 2.0, max1);
- case BEARD_THIN, BEARD_BOX -> getBeardContribution(max, i5, max1, i4) * 0.8;
- case ENCAPSULATE -> getBuryContribution(max / 2.0, i5 / 2.0, max1 / 2.0) * 0.8;
+ case BURY -> getBuryContribution(m, (double)p / 2.0, n);
+ case BEARD_THIN -> getBeardContribution(m, p, n, p) * 0.8;
+ case BEARD_BOX -> getBeardContribution(m, Math.max(0, Math.max(o - j, j - blockBox.maxY())), n, p) * 0.8;
+ case ENCAPSULATE -> getBuryContribution((double)m / 2.0, (double)Math.max(0, Math.max(blockBox.minY() - j, j - blockBox.maxY())) / 2.0, (double)n / 2.0) * 0.8;
};
}
- this.pieceIterator.back(Integer.MAX_VALUE);
-
- while (this.junctionIterator.hasNext()) {
- JigsawJunction jigsawJunction = this.junctionIterator.next();
- int i6 = i - jigsawJunction.getSourceX();
- int groundLevelDelta = i1 - jigsawJunction.getSourceGroundY();
- int max = i2 - jigsawJunction.getSourceZ();
- d += getBeardContribution(i6, groundLevelDelta, max, groundLevelDelta) * 0.4;
+ for (JigsawJunction jigsawJunction : this.c2me$junctionArray) {
+ int r = i - jigsawJunction.getSourceX();
+ int l = j - jigsawJunction.getSourceGroundY();
+ int m = k - jigsawJunction.getSourceZ();
+ d += getBeardContribution(r, l, m, l) * 0.4;
}
- this.junctionIterator.back(Integer.MAX_VALUE);
return d;
}
+ // DivineMC end - World gen optimizations
@Override
public double minValue() {
@@ -132,8 +137,14 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
}
private static double getBuryContribution(double x, double y, double z) {
- double len = Mth.length(x, y, z);
- return Mth.clampedMap(len, 0.0, 6.0, 1.0, 0.0);
+ // DivineMC start - World gen optimizations
+ double d = Math.sqrt(x * x + y * y + z * z);
+ if (d > 6.0) {
+ return 0.0;
+ } else {
+ return 1.0 - d / 6.0;
+ }
+ // DivineMC end - World gen optimizations
}
private static double getBeardContribution(int x, int y, int z, int height) {
diff --git a/net/minecraft/world/level/levelgen/LegacyRandomSource.java b/net/minecraft/world/level/levelgen/LegacyRandomSource.java
index c67168517774a0ad9ca43422a79ef14a8ea0c2e8..026dfbbb6c3fd5cd274dcbf721e5cf3af889e3d9 100644
--- a/net/minecraft/world/level/levelgen/LegacyRandomSource.java
+++ b/net/minecraft/world/level/levelgen/LegacyRandomSource.java
@@ -53,13 +53,7 @@ public class LegacyRandomSource implements BitRandomSource {
return this.gaussianSource.nextGaussian();
}
- public static class LegacyPositionalRandomFactory implements PositionalRandomFactory {
- private final long seed;
-
- public LegacyPositionalRandomFactory(long seed) {
- this.seed = seed;
- }
-
+ public record LegacyPositionalRandomFactory(long seed) implements PositionalRandomFactory { // DivineMC - make record
@Override
public RandomSource at(int x, int y, int z) {
long seed = Mth.getSeed(x, y, z);
diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
index 65728ef17e63d71833677fdcbd5bb90794b4822b..6ef91bd952d4a0c1ffa6f534e4fcdd5c0a9db40b 100644
--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
@@ -65,11 +65,13 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
}
private static Aquifer.FluidPicker createFluidPicker(NoiseGeneratorSettings settings) {
- Aquifer.FluidStatus fluidStatus = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
- int seaLevel = settings.seaLevel();
- Aquifer.FluidStatus fluidStatus1 = new Aquifer.FluidStatus(seaLevel, settings.defaultFluid());
- Aquifer.FluidStatus fluidStatus2 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
- return (x, y, z) -> y < Math.min(-54, seaLevel) ? fluidStatus : fluidStatus1;
+ // DivineMC start - World gen optimizations
+ Aquifer.FluidStatus fluidLevel = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
+ int i = settings.seaLevel();
+ Aquifer.FluidStatus fluidLevel2 = new Aquifer.FluidStatus(i, settings.defaultFluid());
+ final int min = Math.min(-54, i);
+ return (j, k, lx) -> k < min ? fluidLevel : fluidLevel2;
+ // DivineMC end - World gen optimizations
}
@Override
diff --git a/net/minecraft/world/level/levelgen/NoiseSettings.java b/net/minecraft/world/level/levelgen/NoiseSettings.java
index 4cf3a364595ba5f81f741295695cb9a449bdf672..44df2ac0bd972c4d97fc89cd0c2d2d83480ca3e1 100644
--- a/net/minecraft/world/level/levelgen/NoiseSettings.java
+++ b/net/minecraft/world/level/levelgen/NoiseSettings.java
@@ -8,7 +8,7 @@ import net.minecraft.core.QuartPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.dimension.DimensionType;
-public record NoiseSettings(int minY, int height, int noiseSizeHorizontal, int noiseSizeVertical) {
+public record NoiseSettings(int minY, int height, int noiseSizeHorizontal, int noiseSizeVertical, int horizontalCellBlockCount, int verticalCellBlockCount) { // DivineMC - NoiseSettings optimizations
public static final Codec<NoiseSettings> CODEC = RecordCodecBuilder.<NoiseSettings>create(
instance -> instance.group(
Codec.intRange(DimensionType.MIN_Y, DimensionType.MAX_Y).fieldOf("min_y").forGetter(NoiseSettings::minY),
@@ -16,7 +16,10 @@ public record NoiseSettings(int minY, int height, int noiseSizeHorizontal, int n
Codec.intRange(1, 4).fieldOf("size_horizontal").forGetter(NoiseSettings::noiseSizeHorizontal),
Codec.intRange(1, 4).fieldOf("size_vertical").forGetter(NoiseSettings::noiseSizeVertical)
)
- .apply(instance, NoiseSettings::new)
+ // DivineMC start - NoiseSettings optimizations
+ .apply(instance, (Integer minY1, Integer height1, Integer noiseSizeHorizontal1, Integer noiseSizeVertical1) -> new NoiseSettings(minY1, height1, noiseSizeHorizontal1, noiseSizeVertical1,
+ QuartPos.toBlock(noiseSizeHorizontal1), QuartPos.toBlock(noiseSizeVertical1)))
+ // DivineMC end - NoiseSettings optimizations
)
.comapFlatMap(NoiseSettings::guardY, Function.identity());
protected static final NoiseSettings OVERWORLD_NOISE_SETTINGS = create(-64, 384, 1, 2);
@@ -36,7 +39,7 @@ public record NoiseSettings(int minY, int height, int noiseSizeHorizontal, int n
}
public static NoiseSettings create(int minY, int height, int noiseSizeHorizontal, int noiseSizeVertical) {
- NoiseSettings noiseSettings = new NoiseSettings(minY, height, noiseSizeHorizontal, noiseSizeVertical);
+ NoiseSettings noiseSettings = new NoiseSettings(minY, height, noiseSizeHorizontal, noiseSizeVertical, QuartPos.toBlock(noiseSizeHorizontal), QuartPos.toBlock(noiseSizeVertical)); // DivineMC - NoiseSettings optimizations
guardY(noiseSettings).error().ifPresent(error -> {
throw new IllegalStateException(error.message());
});
@@ -44,16 +47,16 @@ public record NoiseSettings(int minY, int height, int noiseSizeHorizontal, int n
}
public int getCellHeight() {
- return QuartPos.toBlock(this.noiseSizeVertical());
+ return verticalCellBlockCount(); // DivineMC - NoiseSettings optimizations
}
public int getCellWidth() {
- return QuartPos.toBlock(this.noiseSizeHorizontal());
+ return horizontalCellBlockCount(); // DivineMC - NoiseSettings optimizations
}
public NoiseSettings clampToHeightAccessor(LevelHeightAccessor heightAccessor) {
int max = Math.max(this.minY, heightAccessor.getMinY());
int i = Math.min(this.minY + this.height, heightAccessor.getMaxY() + 1) - max;
- return new NoiseSettings(max, i, this.noiseSizeHorizontal, this.noiseSizeVertical);
+ return new NoiseSettings(max, i, this.noiseSizeHorizontal, this.noiseSizeVertical, QuartPos.toBlock(this.noiseSizeHorizontal), QuartPos.toBlock(this.noiseSizeVertical)); // DivineMC - NoiseSettings optimizations
}
}
diff --git a/net/minecraft/world/level/levelgen/XoroshiroRandomSource.java b/net/minecraft/world/level/levelgen/XoroshiroRandomSource.java
index 9d3a9ca1e13cd80f468f1352bbb74345f03903dd..d97b9b43686bda0a95fc02f6ca31b2d07d603a32 100644
--- a/net/minecraft/world/level/levelgen/XoroshiroRandomSource.java
+++ b/net/minecraft/world/level/levelgen/XoroshiroRandomSource.java
@@ -106,15 +106,7 @@ public class XoroshiroRandomSource implements RandomSource {
return this.randomNumberGenerator.nextLong() >>> 64 - bits;
}
- public static class XoroshiroPositionalRandomFactory implements PositionalRandomFactory {
- private final long seedLo;
- private final long seedHi;
-
- public XoroshiroPositionalRandomFactory(long seedLo, long seedHi) {
- this.seedLo = seedLo;
- this.seedHi = seedHi;
- }
-
+ public record XoroshiroPositionalRandomFactory(long seedLo, long seedHi) implements PositionalRandomFactory { // DivineMC - make record
@Override
public RandomSource at(int x, int y, int z) {
long seed = Mth.getSeed(x, y, z);
diff --git a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
index ffac5b7b1eb1364ab8442d7145a7b4ebde68ee10..ef28df96ed569113a9d61f6ac4b4d84d578c02da 100644
--- a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
+++ b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
@@ -187,7 +187,7 @@ public class PerlinNoise {
}
public static double wrap(double value) {
- return value - Mth.lfloor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
+ return value - Math.floor(value / 3.3554432E7 + 0.5) * 3.3554432E7; // DivineMC - avoid casting
}
protected int firstOctave() {