From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Thu, 10 Jul 2025 03:48:14 +0300 Subject: [PATCH] C2ME: Optimize Aquifer and Beardifier This patch is based on the following mixins: * "com/ishland/c2me/opts/worldgen/vanilla/mixin/aquifer/MixinAquiferSamplerImpl.java" * "com/ishland/c2me/opts/worldgen/general/common/random_instances/RandomUtils.java" By: ishland As part of: C2ME (https://github.com/RelativityMC/C2ME-fabric) Licensed under: MIT (https://opensource.org/licenses/MIT) diff --git a/net/minecraft/world/level/levelgen/Aquifer.java b/net/minecraft/world/level/levelgen/Aquifer.java index 1e1536099261f578fa56b9f84f28157e4a9abafa..e88890ef7de33c30e062d7da2beef6d12d75d296 100644 --- a/net/minecraft/world/level/levelgen/Aquifer.java +++ b/net/minecraft/world/level/levelgen/Aquifer.java @@ -98,6 +98,13 @@ public interface Aquifer { private final int minGridZ; private final int gridSizeX; private final int gridSizeZ; + // DivineMC start - C2ME: Optimize Aquifer + private int c2me$packed1; + private int c2me$packed2; + private int c2me$packed3; + private double c2me$mutableDoubleThingy; + private short[] c2me$packedBlockPositions; + // DivineMC end - C2ME: Optimize Aquifer 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} }; @@ -133,6 +140,41 @@ public interface Aquifer { this.aquiferCache = new Aquifer.FluidStatus[i4]; this.aquiferLocationCache = new long[i4]; Arrays.fill(this.aquiferLocationCache, Long.MAX_VALUE); + // DivineMC start - C2ME: Optimize Aquifer + if (this.aquiferLocationCache.length % (this.gridSizeX * this.gridSizeZ) != 0) { + throw new AssertionError("Array length"); + } + + int sizeY = this.aquiferLocationCache.length / (this.gridSizeX * this.gridSizeZ); + + this.c2me$packedBlockPositions = new short[this.aquiferLocationCache.length]; + + final RandomSource random = com.ishland.c2me.opts.worldgen.general.common.random_instances.RandomUtils.getRandom(this.positionalRandomFactory); + 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; + com.ishland.c2me.opts.worldgen.general.common.random_instances.RandomUtils.derive(this.positionalRandomFactory, random, x1, y1, z1); + int r0 = random.nextInt(10); + int r1 = random.nextInt(9); + int r2 = random.nextInt(10); + int x2 = x1 * 16 + r0; + int y2 = y1 * 12 + r1; + int z2 = z1 * 16 + r2; + int index = this.getIndex(x1, y1, z1); + this.aquiferLocationCache[index] = BlockPos.asLong(x2, y2, z2); + this.c2me$packedBlockPositions[index] = (short) ((r0 << 8) | (r1 << 4) | r2); + } + } + } + for (long blockPosition : this.aquiferLocationCache) { + if (blockPosition == Long.MAX_VALUE) { + throw new AssertionError("Array initialization"); + } + } + // DivineMC end - C2ME: Optimize Aquifer int i5 = this.adjustSurfaceLevel( noiseChunk.maxPreliminarySurfaceLevel(fromGridX(this.minGridX, 0), fromGridZ(this.minGridZ, 0), fromGridX(i, 9), fromGridZ(i3, 9)) ); @@ -154,142 +196,23 @@ public interface Aquifer { this.shouldScheduleFluidUpdate = false; return null; } else { + // DivineMC start - C2ME: Optimize Aquifer int i = context.blockX(); - int i1 = context.blockY(); - int i2 = context.blockZ(); - Aquifer.FluidStatus fluidStatus = this.globalFluidPicker.computeFluid(i, i1, i2); - if (i1 > this.skipSamplingAboveY) { + int j = context.blockY(); + int k = context.blockZ(); + Aquifer.FluidStatus fluidStatus = this.globalFluidPicker.computeFluid(i, j, k); + if (j > this.skipSamplingAboveY) { this.shouldScheduleFluidUpdate = false; - return fluidStatus.at(i1); - } else if (fluidStatus.at(i1).is(Blocks.LAVA)) { + return fluidStatus.at(j); + } else if (fluidStatus.at(j).is(Blocks.LAVA)) { this.shouldScheduleFluidUpdate = false; return SharedConstants.DEBUG_DISABLE_FLUID_GENERATION ? Blocks.AIR.defaultBlockState() : Blocks.LAVA.defaultBlockState(); } else { - int i3 = gridX(i + -5); - int i4 = gridY(i1 + 1); - int i5 = gridZ(i2 + -5); - int i6 = Integer.MAX_VALUE; - int i7 = Integer.MAX_VALUE; - int i8 = Integer.MAX_VALUE; - int i9 = Integer.MAX_VALUE; - int i10 = 0; - int i11 = 0; - int i12 = 0; - int i13 = 0; - - for (int i14 = 0; i14 <= 1; i14++) { - for (int i15 = -1; i15 <= 1; i15++) { - for (int i16 = 0; i16 <= 1; i16++) { - int i17 = i3 + i14; - int i18 = i4 + i15; - int i19 = i5 + i16; - int index = this.getIndex(i17, i18, i19); - long l = this.aquiferLocationCache[index]; - long l1; - if (l != Long.MAX_VALUE) { - l1 = l; - } else { - RandomSource randomSource = this.positionalRandomFactory.at(i17, i18, i19); - l1 = BlockPos.asLong( - fromGridX(i17, randomSource.nextInt(10)), - fromGridY(i18, randomSource.nextInt(9)), - fromGridZ(i19, randomSource.nextInt(10)) - ); - this.aquiferLocationCache[index] = l1; - } - - int i20 = BlockPos.getX(l1) - i; - int i21 = BlockPos.getY(l1) - i1; - int i22 = BlockPos.getZ(l1) - i2; - int i23 = i20 * i20 + i21 * i21 + i22 * i22; - if (i6 >= i23) { - i13 = i12; - i12 = i11; - i11 = i10; - i10 = index; - i9 = i8; - i8 = i7; - i7 = i6; - i6 = i23; - } else if (i7 >= i23) { - i13 = i12; - i12 = i11; - i11 = index; - i9 = i8; - i8 = i7; - i7 = i23; - } else if (i8 >= i23) { - i13 = i12; - i12 = index; - i9 = i8; - i8 = i23; - } else if (i9 >= i23) { - i13 = index; - i9 = i23; - } - } - } - } - - Aquifer.FluidStatus aquiferStatus = this.getAquiferStatus(i10); - double d = similarity(i6, i7); - BlockState blockState = aquiferStatus.at(i1); - BlockState blockState1 = SharedConstants.DEBUG_DISABLE_FLUID_GENERATION ? Blocks.AIR.defaultBlockState() : blockState; - if (d <= 0.0) { - if (d >= FLOWING_UPDATE_SIMULARITY) { - Aquifer.FluidStatus aquiferStatus1 = this.getAquiferStatus(i11); - this.shouldScheduleFluidUpdate = !aquiferStatus.equals(aquiferStatus1); - } else { - this.shouldScheduleFluidUpdate = false; - } - - return blockState1; - } else if (blockState.is(Blocks.WATER) && this.globalFluidPicker.computeFluid(i, i1 - 1, i2).at(i1 - 1).is(Blocks.LAVA)) { - this.shouldScheduleFluidUpdate = true; - return blockState1; - } else { - MutableDouble mutableDouble = new MutableDouble(Double.NaN); - Aquifer.FluidStatus aquiferStatus2 = this.getAquiferStatus(i11); - 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(i12); - 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(i13)); - } else { - this.shouldScheduleFluidUpdate = true; - } - - return blockState1; - } - } + aquiferExtracted$refreshDistPosIdx(i, j, k); + return aquiferExtracted$applyPost(context, substance, j, i, k); } } + // DivineMC end - C2ME: Optimize Aquifer } @Override @@ -302,65 +225,28 @@ public interface Aquifer { return 1.0 - (secondDistance - firstDistance) / 25.0; } + // DivineMC start - C2ME: Optimize Aquifer 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 d = 0.5 * (double)(fluidLevel.fluidLevel + fluidLevel2.fluidLevel); + final double q = aquiferExtracted$getQ(i, d, abs); - 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; - } - - return 2.0 * (d12 + d11); + return aquiferExtracted$postCalculateDensity(context, substance, q); } } else { return 2.0; } } + // DivineMC end - C2ME: Optimize Aquifer private static int gridX(int x) { return x >> 4; @@ -441,22 +327,21 @@ public interface Aquifer { } 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); + // DivineMC start - C2ME: Optimize Aquifer + 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 - C2ME: Optimize Aquifer int i; if (d1 > 0.0) { @@ -487,12 +372,12 @@ public interface Aquifer { private BlockState computeFluidType(int x, int y, int z, Aquifer.FluidStatus fluidStatus, int surfaceLevel) { BlockState blockState = fluidStatus.fluidType; if (surfaceLevel <= -10 && surfaceLevel != DimensionType.WAY_BELOW_MIN_Y && fluidStatus.fluidType != Blocks.LAVA.defaultBlockState()) { - int i = 64; - int i1 = 40; - int i2 = Math.floorDiv(x, 64); - int i3 = Math.floorDiv(y, 40); - int i4 = Math.floorDiv(z, 64); - double d = this.lavaNoise.compute(new DensityFunction.SinglePointContext(i2, i3, i4)); + // DivineMC start - C2ME: Optimize Aquifer + int k = x >> 6; + int l = Math.floorDiv(y, 40); + int m = z >> 6; + double d = this.lavaNoise.compute(new DensityFunction.SinglePointContext(k, l, m)); + // DivineMC end - C2ME: Optimize Aquifer if (Math.abs(d) > 0.3) { blockState = Blocks.LAVA.defaultBlockState(); } @@ -500,5 +385,218 @@ public interface Aquifer { return blockState; } + + // DivineMC start - C2ME: Optimize Aquifer + private @Nullable BlockState aquiferExtracted$applyPost(DensityFunction.FunctionContext pos, double density, int j, int i, int k) { + Aquifer.FluidStatus fluidLevel2 = this.c2me$getWaterLevelIndexed(c2me$unpackPackedPosIdx(this.c2me$packed1)); + double d = similarity(c2me$unpackPackedDist(this.c2me$packed1), c2me$unpackPackedDist(this.c2me$packed2)); + 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.c2me$getWaterLevelIndexed(c2me$unpackPackedPosIdx(this.c2me$packed2)); + 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.c2me$getWaterLevelIndexed(c2me$unpackPackedPosIdx(this.c2me$packed3)); + int dist3 = c2me$unpackPackedDist(this.c2me$packed3); + double f = similarity(c2me$unpackPackedDist(this.c2me$packed1), dist3); + if (aquiferExtracted$extractedCheckFG(pos, density, d, fluidLevel2, f, fluidLevel4)) return null; + + double g = similarity(c2me$unpackPackedDist(this.c2me$packed2), 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 A = Integer.MAX_VALUE; + int B = Integer.MAX_VALUE; + int C = Integer.MAX_VALUE; + + int index = 12; // 12 max + for (int offY = -1; offY <= 1; ++offY) { + int gymul = (gy + offY) * 12; + for (int offZ = 0; offZ <= 1; ++offZ) { + int gzmul = (gz + offZ) << 4; + + int index0 = index - 1; + int posIdx0 = this.getIndex(gx, gy + offY, gz + offZ); + int position0 = this.c2me$packedBlockPositions[posIdx0]; + int dx0 = (gx << 4) + c2me$unpackPackedX(position0) - x; + int dy0 = gymul + c2me$unpackPackedY(position0) - y; + int dz0 = gzmul + c2me$unpackPackedZ(position0) - z; + int dist_0 = dx0 * dx0 + dy0 * dy0 + dz0 * dz0; + + int index1 = index - 2; + int posIdx1 = posIdx0 + 1; + int position1 = this.c2me$packedBlockPositions[posIdx1]; + int dx1 = ((gx + 1) << 4) + c2me$unpackPackedX(position1) - x; + int dy1 = gymul + c2me$unpackPackedY(position1) - y; + int dz1 = gzmul + c2me$unpackPackedZ(position1) - z; + int dist_1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; + + int p0 = (dist_0 << 20) | (index0 << 16) | posIdx0; + if (p0 <= C) { + int n01 = Math.max(A, p0); + A = Math.min(A, p0); + + int n02 = Math.max(B, n01); + B = Math.min(B, n01); + + C = Math.min(C, n02); + } + + int p1 = (dist_1 << 20) | (index1 << 16) | posIdx1; + if (p1 <= C) { + int n11 = Math.max(A, p1); + A = Math.min(A, p1); + + int n12 = Math.max(B, n11); + B = Math.min(B, n11); + + C = Math.min(C, n12); + } + + index -= 2; + } + } + + this.c2me$packed1 = A; + this.c2me$packed2 = B; + this.c2me$packed3 = C; + } + + 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; + } + + private Aquifer.FluidStatus c2me$getWaterLevelIndexed(int index) { + return this.getAquiferStatus(index); + } + + private static int c2me$unpackPackedX(int packed) { + return packed >> 8; + } + + private static int c2me$unpackPackedY(int packed) { + return (packed >> 4) & 0b1111; + } + + private static int c2me$unpackPackedZ(int packed) { + return packed & 0b1111; + } + + private static int c2me$unpackPackedDist(int packed) { + return packed >> 20; + } + + private static int c2me$unpackPackedPosIdx(int packed) { + return packed & 0xffff; + } + // DivineMC end - C2ME: Optimize Aquifer } } diff --git a/net/minecraft/world/level/levelgen/Beardifier.java b/net/minecraft/world/level/levelgen/Beardifier.java index c9ddfc8670614c2d8629066b0cc805d18e4f662f..fc1f1fcac84197a2652dfd3869ef505f1a6140f1 100644 --- a/net/minecraft/world/level/levelgen/Beardifier.java +++ b/net/minecraft/world/level/levelgen/Beardifier.java @@ -35,6 +35,15 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker { private final List junctions; @Nullable private final BoundingBox affectedBox; + // DivineMC start - C2ME: Optimize Beardifier + private Beardifier.Rigid[] c2me$pieceArray; + private JigsawJunction[] c2me$junctionArray; + + private void c2me$initArrays() { + this.c2me$pieceArray = this.pieces.toArray(Beardifier.Rigid[]::new); + this.c2me$junctionArray = this.junctions.toArray(JigsawJunction[]::new); + } + // DivineMC end - C2ME: Optimize Beardifier public static Beardifier forStructuresInChunk(StructureManager structureManager, ChunkPos chunkPos) { List list = structureManager.startsForStructure(chunkPos, structure -> structure.terrainAdaptation() != TerrainAdjustment.NONE); @@ -109,53 +118,54 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker { } } + // DivineMC start - C2ME: Optimize Beardifier @Override public double compute(DensityFunction.FunctionContext context) { if (this.affectedBox == null) { return 0.0; - } else { - int i = context.blockX(); - int i1 = context.blockY(); - int i2 = context.blockZ(); - if (!this.affectedBox.isInside(i, i1, i2)) { - return 0.0; - } else { - double d = 0.0; - - for (Beardifier.Rigid rigid : this.pieces) { - 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())); - }; - - d += switch (rigid.terrainAdjustment()) { - 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; - }; - } + } - for (JigsawJunction jigsawJunction : this.junctions) { - int i6 = i - jigsawJunction.getSourceX(); - int groundLevelDelta = i1 - jigsawJunction.getSourceGroundY(); - int max = i2 - jigsawJunction.getSourceZ(); - d += getBeardContribution(i6, groundLevelDelta, max, groundLevelDelta) * 0.4; - } + int i = context.blockX(); + int j = context.blockY(); + int k = context.blockZ(); - return d; - } + if (this.affectedBox.isInside(i, j, k)) { + return 0.0; + } + + if (this.c2me$pieceArray == null || this.c2me$junctionArray == null) { + this.c2me$initArrays(); + } + + double d = 0.0; + + for (Beardifier.Rigid rigid : this.pieces) { + BoundingBox boundingBox = rigid.box(); + int l = rigid.groundLevelDelta(); + int m = Math.max(0, Math.max(boundingBox.minX() - i, i - boundingBox.maxX())); + int n = Math.max(0, Math.max(boundingBox.minZ() - k, k - boundingBox.maxZ())); + int o = boundingBox.minY() + l; + int p = j - o; + + d += switch (rigid.terrainAdjustment()) { + case NONE -> 0.0; + 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 - boundingBox.maxY())), n, p) * 0.8; + case ENCAPSULATE -> getBuryContribution((double)m / 2.0, (double)Math.max(0, Math.max(boundingBox.minY() - j, j - boundingBox.maxY())) / 2.0, (double)n / 2.0) * 0.8; + }; + } + + for (JigsawJunction jigsawJunction : this.junctions) { + int r = i - jigsawJunction.getSourceX(); + int l = j - jigsawJunction.getSourceGroundY(); + int m = k - jigsawJunction.getSourceZ(); + d += getBeardContribution(r, l, m, l) * 0.4; } + + return d; } + // DivineMC end - C2ME: Optimize Beardifier @Override public double minValue() { 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/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);