From 5f54cc34f39814948eab3d842e3a4275b60a478e Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Thu, 10 Jul 2025 04:03:15 +0300 Subject: [PATCH] Optimize Aquifer and Beardifier --- build-data/divinemc.at | 3 + ...C2ME-Optimize-Aquifer-and-Beardifier.patch | 705 +++++++++++++++++ .../divinemc/util/CollectionWrapperUtil.java | 744 ------------------ .../org/bxteam/divinemc/util/RandomUtil.java | 40 + .../util/map/Int2ObjectConcurrentHashMap.java | 160 ---- 5 files changed, 748 insertions(+), 904 deletions(-) create mode 100644 divinemc-server/minecraft-patches/features/0085-C2ME-Optimize-Aquifer-and-Beardifier.patch delete mode 100644 divinemc-server/src/main/java/org/bxteam/divinemc/util/CollectionWrapperUtil.java create mode 100644 divinemc-server/src/main/java/org/bxteam/divinemc/util/RandomUtil.java delete mode 100644 divinemc-server/src/main/java/org/bxteam/divinemc/util/map/Int2ObjectConcurrentHashMap.java diff --git a/build-data/divinemc.at b/build-data/divinemc.at index af17be0..457eb6b 100644 --- a/build-data/divinemc.at +++ b/build-data/divinemc.at @@ -36,6 +36,9 @@ public net.minecraft.world.level.levelgen.NoiseChunk$BlendOffset public net.minecraft.world.level.levelgen.NoiseRouterData$QuantizedSpaghettiRarity public net.minecraft.world.level.levelgen.NoiseRouterData$QuantizedSpaghettiRarity getSpaghettiRarity3D(D)D public net.minecraft.world.level.levelgen.NoiseRouterData$QuantizedSpaghettiRarity getSphaghettiRarity2D(D)D +public net.minecraft.world.level.levelgen.Xoroshiro128PlusPlus seedHi +public net.minecraft.world.level.levelgen.Xoroshiro128PlusPlus seedLo +public net.minecraft.world.level.levelgen.XoroshiroRandomSource randomNumberGenerator public net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool rawTemplates public net.minecraft.world.level.pathfinder.SwimNodeEvaluator allowBreaching public-f ca.spottedleaf.moonrise.paper.PaperHooks diff --git a/divinemc-server/minecraft-patches/features/0085-C2ME-Optimize-Aquifer-and-Beardifier.patch b/divinemc-server/minecraft-patches/features/0085-C2ME-Optimize-Aquifer-and-Beardifier.patch new file mode 100644 index 0000000..04bc812 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0085-C2ME-Optimize-Aquifer-and-Beardifier.patch @@ -0,0 +1,705 @@ +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 c62a15ea4a1bb22e7bcc2fc544acf8a601892029..2efa0b8bb7189d768cb43e55376b397f4f806374 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 - C2ME: Optimize Aquifer ++ 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 - 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} + }; +@@ -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 - 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); ++ ++ 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 - C2ME: Optimize Aquifer + } + + 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 - C2ME: Optimize Aquifer + 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 - C2ME: Optimize Aquifer + } + + @Override +@@ -278,65 +201,28 @@ public interface Aquifer { + return 1.0 - Math.abs(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 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 - C2ME: Optimize Aquifer + + 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 - C2ME: Optimize Aquifer ++ 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 - C2ME: Optimize Aquifer + + private Aquifer.FluidStatus computeFluid(int x, int y, int z) { + Aquifer.FluidStatus fluidStatus = this.globalFluidPicker.computeFluid(x, y, z); +@@ -407,22 +295,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) { +@@ -453,12 +340,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(); + } +@@ -466,5 +353,183 @@ public interface Aquifer { + + return blockState; + } ++ ++ // DivineMC start - C2ME: Optimize Aquifer ++ 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 - C2ME: Optimize Aquifer + } + } +diff --git a/net/minecraft/world/level/levelgen/Beardifier.java b/net/minecraft/world/level/levelgen/Beardifier.java +index 86c15d2d90e63d21cb83622a7b29e11151a4f64a..2c0c0546046857056b8445f59828fdf9821ea001 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 pieceIterator; + private final ObjectListIterator junctionIterator; ++ // DivineMC start - C2ME: Optimize Beardifier ++ 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 - C2ME: Optimize Beardifier + + public static Beardifier forStructuresInChunk(StructureManager structureManager, ChunkPos chunkPos) { + int minBlockX = chunkPos.getMinBlockX(); +@@ -75,50 +86,44 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker { + this.junctionIterator = junctionIterator; + } + ++ // DivineMC start - C2ME: Optimize Beardifier + @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 - 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); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/util/CollectionWrapperUtil.java b/divinemc-server/src/main/java/org/bxteam/divinemc/util/CollectionWrapperUtil.java deleted file mode 100644 index 1edb1f2..0000000 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/util/CollectionWrapperUtil.java +++ /dev/null @@ -1,744 +0,0 @@ -package org.bxteam.divinemc.util; - -import it.unimi.dsi.fastutil.bytes.ByteIterator; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.IntCollection; -import it.unimi.dsi.fastutil.ints.IntIterator; -import it.unimi.dsi.fastutil.ints.IntSet; -import it.unimi.dsi.fastutil.longs.LongIterator; -import it.unimi.dsi.fastutil.longs.LongListIterator; -import it.unimi.dsi.fastutil.objects.ObjectCollection; -import it.unimi.dsi.fastutil.objects.ObjectIterator; -import it.unimi.dsi.fastutil.objects.ObjectSet; -import it.unimi.dsi.fastutil.objects.ReferenceSet; -import it.unimi.dsi.fastutil.shorts.ShortIterator; -import org.apache.commons.lang3.ArrayUtils; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.Iterator; -import java.util.ListIterator; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -public final class CollectionWrapperUtil { - private CollectionWrapperUtil() { - throw new IllegalStateException("This class cannot be instantiated"); - } - - private static Int2ObjectMap.@NotNull Entry intEntryForwards(Map.Entry entry) { - return new Int2ObjectMap.Entry<>() { - @Override - public T getValue() { - return entry.getValue(); - } - - @Override - public T setValue(T value) { - return entry.setValue(value); - } - - @Override - public int getIntKey() { - return entry.getKey(); - } - - @Override - public boolean equals(Object obj) { - if (obj == entry) { - return true; - } - return super.equals(obj); - } - - @Override - public int hashCode() { - return entry.hashCode(); - } - }; - } - - private static Map.Entry intEntryBackwards(Int2ObjectMap.Entry entry) { - return entry; - } - - public static ObjectSet> entrySetIntWrap(Map map) { - return new ConvertingObjectSet<>( - map.entrySet(), - CollectionWrapperUtil::intEntryForwards, - CollectionWrapperUtil::intEntryBackwards - ); - } - - public static IntSet wrapIntSet(Set intset) { - return new WrappingIntSet(intset); - } - - public static ByteIterator itrByteWrap(Iterator backing) { - return new WrappingByteIterator(backing); - } - - public static ByteIterator itrByteWrap(Iterable backing) { - return itrByteWrap(backing.iterator()); - } - - public static IntIterator itrIntWrap(Iterator backing) { - return new WrappingIntIterator(backing); - } - - public static IntIterator itrIntWrap(Iterable backing) { - return itrIntWrap(backing.iterator()); - } - - public static LongIterator itrLongWrap(Iterator backing) { - return new WrappingLongIterator(backing); - } - - public static LongIterator itrLongWrap(Iterable backing) { - return itrLongWrap(backing.iterator()); - } - - public static ShortIterator itrShortWrap(Iterator backing) { - return new WrappingShortIterator(backing); - } - - public static ShortIterator itrShortWrap(Iterable backing) { - return itrShortWrap(backing.iterator()); - } - - public static LongListIterator wrap(ListIterator c) { - return new WrappingLongListIterator(c); - } - - public static LongListIterator wrap(Iterator c) { - return new SlimWrappingLongListIterator(c); - } - - public static ObjectCollection wrap(Collection c) { - return new WrappingObjectCollection<>(c); - } - - public static ReferenceSet wrap(Set s) { - return new WrappingRefSet<>(s); - } - - public static ObjectIterator itrWrap(Iterable in) { - return new WrapperObjectIterator<>(in.iterator()); - } - - public static class ConvertingObjectSet implements ObjectSet { - private final Set backing; - private final Function forward; - private final Function back; - - public ConvertingObjectSet(Set backing, Function forward, Function back) { - this.backing = Objects.requireNonNull(backing, "Backing set cannot be null"); - this.forward = Objects.requireNonNull(forward, "Forward function cannot be null"); - this.back = Objects.requireNonNull(back, "Backward function cannot be null"); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public boolean isEmpty() { - return backing.isEmpty(); - } - - @SuppressWarnings("unchecked") - @Override - public boolean contains(Object o) { - try { - return backing.contains(back.apply((T) o)); - } catch (ClassCastException cce) { - return false; - } - } - - @Override - public Object[] toArray() { - return backing.stream().map(forward).toArray(); - } - - @Override - public R[] toArray(R[] a) { - return backing.stream().map(forward).collect(Collectors.toSet()).toArray(a); - } - - @Override - public boolean add(T e) { - return backing.add(back.apply(e)); - } - - @SuppressWarnings("unchecked") - @Override - public boolean remove(Object o) { - try { - return backing.remove(back.apply((T) o)); - } catch (ClassCastException cce) { - return false; - } - } - - @SuppressWarnings("unchecked") - @Override - public boolean containsAll(Collection c) { - try { - return backing.containsAll(c.stream() - .map(i -> back.apply((T) i)) - .collect(Collectors.toSet())); - } catch (ClassCastException cce) { - return false; - } - } - - @Override - public boolean addAll(Collection c) { - return backing.addAll(c.stream().map(back).collect(Collectors.toSet())); - } - - @SuppressWarnings("unchecked") - @Override - public boolean removeAll(Collection c) { - try { - return backing.removeAll(c.stream() - .map(i -> back.apply((T) i)) - .collect(Collectors.toSet())); - } catch (ClassCastException cce) { - return false; - } - } - - @SuppressWarnings("unchecked") - @Override - public boolean retainAll(Collection c) { - try { - return backing.retainAll(c.stream() - .map(i -> back.apply((T) i)) - .collect(Collectors.toSet())); - } catch (ClassCastException cce) { - return false; - } - } - - @Override - public void clear() { - backing.clear(); - } - - @Override - public ObjectIterator iterator() { - return new ObjectIterator<>() { - private final Iterator backg = backing.iterator(); - - @Override - public boolean hasNext() { - return backg.hasNext(); - } - - @Override - public T next() { - return forward.apply(backg.next()); - } - - @Override - public void remove() { - backg.remove(); - } - }; - } - } - - static class WrappingIntIterator implements IntIterator { - private final Iterator backing; - - WrappingIntIterator(Iterator backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public int nextInt() { - return backing.next(); - } - - @Override - public Integer next() { - return backing.next(); - } - - @Override - public void remove() { - backing.remove(); - } - } - - static class WrappingLongIterator implements LongIterator { - private final Iterator backing; - - WrappingLongIterator(Iterator backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public long nextLong() { - return backing.next(); - } - - @Override - public Long next() { - return backing.next(); - } - - @Override - public void remove() { - backing.remove(); - } - } - - static class WrappingShortIterator implements ShortIterator { - private final Iterator backing; - - WrappingShortIterator(Iterator backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public short nextShort() { - return backing.next(); - } - - @Override - public Short next() { - return backing.next(); - } - - @Override - public void remove() { - backing.remove(); - } - } - - static class WrappingByteIterator implements ByteIterator { - private final Iterator backing; - - WrappingByteIterator(Iterator backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public byte nextByte() { - return next(); - } - - @Override - public Byte next() { - return backing.next(); - } - - @Override - public void remove() { - backing.remove(); - } - } - - public static class WrappingIntSet implements IntSet { - private final Set backing; - - public WrappingIntSet(Set backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public boolean add(int key) { - return backing.add(key); - } - - @Override - public boolean contains(int key) { - return backing.contains(key); - } - - @Override - public int[] toIntArray() { - return backing.stream().mapToInt(Integer::intValue).toArray(); - } - - @Override - public int[] toArray(int[] a) { - return ArrayUtils.toPrimitive(backing.toArray(new Integer[0])); - } - - @Override - public boolean addAll(IntCollection c) { - return backing.addAll(c); - } - - @Override - public boolean containsAll(IntCollection c) { - return backing.containsAll(c); - } - - @Override - public boolean removeAll(IntCollection c) { - return backing.removeAll(c); - } - - @Override - public boolean retainAll(IntCollection c) { - return backing.retainAll(c); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public boolean isEmpty() { - return backing.isEmpty(); - } - - @Override - public Object[] toArray() { - return backing.toArray(); - } - - @Override - public T[] toArray(T[] a) { - return backing.toArray(a); - } - - @Override - public boolean containsAll(Collection c) { - return backing.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - return backing.addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - return backing.removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return backing.retainAll(c); - } - - @Override - public void clear() { - backing.clear(); - } - - @Override - public IntIterator iterator() { - return new WrappingIntIterator(backing.iterator()); - } - - @Override - public boolean remove(int k) { - return backing.remove(k); - } - } - - public static class WrappingRefSet implements ReferenceSet { - private final Set backing; - - public WrappingRefSet(Set backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public boolean add(V key) { - return backing.add(key); - } - - @Override - public boolean remove(final Object o) { - return backing.remove(o); - } - - @Override - public boolean containsAll(@NotNull final Collection c) { - return backing.containsAll(c); - } - - @Override - public boolean addAll(@NotNull final Collection c) { - return backing.addAll(c); - } - - @Override - public boolean removeAll(@NotNull final Collection c) { - return backing.removeAll(c); - } - - @Override - public boolean retainAll(@NotNull final Collection c) { - return backing.retainAll(c); - } - - @Override - public void clear() { - this.backing.clear(); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public boolean isEmpty() { - return backing.isEmpty(); - } - - @Override - public boolean contains(final Object o) { - return backing.contains(o); - } - - @Override - public ObjectIterator iterator() { - return null; - } - - @Override - public @NotNull Object[] toArray() { - return this.backing.toArray(); - } - - @Override - public @NotNull T[] toArray(@NotNull final T[] a) { - return this.backing.toArray(a); - } - } - - public static class WrappingLongListIterator implements LongListIterator { - private final ListIterator backing; - - WrappingLongListIterator(ListIterator backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public long previousLong() { - return backing.previous(); - } - - @Override - public long nextLong() { - return backing.next(); - } - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public boolean hasPrevious() { - return backing.hasPrevious(); - } - - @Override - public int nextIndex() { - return backing.nextIndex(); - } - - @Override - public int previousIndex() { - return backing.previousIndex(); - } - - @Override - public void add(long k) { - backing.add(k); - } - - @Override - public void remove() { - backing.remove(); - } - - @Override - public void set(long k) { - backing.set(k); - } - } - - public static class SlimWrappingLongListIterator implements LongListIterator { - private final Iterator backing; - - SlimWrappingLongListIterator(Iterator backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public long previousLong() { - throw new UnsupportedOperationException(); - } - - @Override - public long nextLong() { - return backing.next(); - } - - @Override - public boolean hasNext() { - return backing.hasNext(); - } - - @Override - public boolean hasPrevious() { - throw new UnsupportedOperationException(); - } - - @Override - public int nextIndex() { - throw new UnsupportedOperationException(); - } - - @Override - public int previousIndex() { - throw new UnsupportedOperationException(); - } - - @Override - public void add(long k) { - throw new UnsupportedOperationException(); - } - - @Override - public void remove() { - backing.remove(); - } - - @Override - public void set(long k) { - throw new UnsupportedOperationException(); - } - } - - public static class WrappingObjectCollection implements ObjectCollection { - private final Collection backing; - - public WrappingObjectCollection(Collection backing) { - this.backing = Objects.requireNonNull(backing); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public boolean isEmpty() { - return backing.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return backing.contains(o); - } - - @Override - public Object[] toArray() { - return backing.toArray(); - } - - @Override - public T[] toArray(T[] a) { - return backing.toArray(a); - } - - @Override - public boolean add(V e) { - return backing.add(e); - } - - @Override - public boolean remove(Object o) { - return backing.remove(o); - } - - @Override - public boolean containsAll(Collection c) { - return backing.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - return backing.addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - return backing.removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return backing.retainAll(c); - } - - @Override - public void clear() { - backing.clear(); - } - - @Override - public ObjectIterator iterator() { - return itrWrap(backing); - } - } - - private record WrapperObjectIterator(Iterator parent) implements ObjectIterator { - private WrapperObjectIterator(Iterator parent) { - this.parent = Objects.requireNonNull(parent); - } - - @Override - public boolean hasNext() { - return parent.hasNext(); - } - - @Override - public T next() { - return parent.next(); - } - - @Override - public void remove() { - parent.remove(); - } - } -} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/util/RandomUtil.java b/divinemc-server/src/main/java/org/bxteam/divinemc/util/RandomUtil.java new file mode 100644 index 0000000..5f47188 --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/util/RandomUtil.java @@ -0,0 +1,40 @@ +package org.bxteam.divinemc.util; + +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.levelgen.LegacyRandomSource; +import net.minecraft.world.level.levelgen.PositionalRandomFactory; +import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; +import net.minecraft.world.level.levelgen.Xoroshiro128PlusPlus; +import net.minecraft.world.level.levelgen.XoroshiroRandomSource; +import org.jetbrains.annotations.NotNull; + +public final class RandomUtil { + public static @NotNull RandomSource getRandom(PositionalRandomFactory deriver) { + if (deriver instanceof XoroshiroRandomSource.XoroshiroPositionalRandomFactory) { + return new XoroshiroRandomSource(0L, 0L); + } + if (deriver instanceof LegacyRandomSource.LegacyPositionalRandomFactory) { + return new SingleThreadedRandomSource(0L); + } + throw new IllegalArgumentException(); + } + + private static final ThreadLocal xoroshiro = ThreadLocal.withInitial(() -> new XoroshiroRandomSource(0L, 0L)); + private static final ThreadLocal simple = ThreadLocal.withInitial(() -> new SingleThreadedRandomSource(0L)); + + public static void derive(PositionalRandomFactory deriver, RandomSource random, int x, int y, int z) { + if (deriver instanceof final XoroshiroRandomSource.XoroshiroPositionalRandomFactory deriver1) { + final Xoroshiro128PlusPlus implementation = ((XoroshiroRandomSource) random).randomNumberGenerator; + implementation.seedLo = (Mth.getSeed(x, y, z) ^ deriver1.seedLo()); + implementation.seedHi = (deriver1.seedHi()); + return; + } + if (deriver instanceof LegacyRandomSource.LegacyPositionalRandomFactory(long seed)) { + final SingleThreadedRandomSource random1 = (SingleThreadedRandomSource) random; + random1.setSeed(Mth.getSeed(x, y, z) ^ seed); + return; + } + throw new IllegalArgumentException(); + } +} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/util/map/Int2ObjectConcurrentHashMap.java b/divinemc-server/src/main/java/org/bxteam/divinemc/util/map/Int2ObjectConcurrentHashMap.java deleted file mode 100644 index cac8e64..0000000 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/util/map/Int2ObjectConcurrentHashMap.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.bxteam.divinemc.util.map; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.IntSet; -import it.unimi.dsi.fastutil.objects.ObjectCollection; -import it.unimi.dsi.fastutil.objects.ObjectSet; -import org.bxteam.divinemc.util.CollectionWrapperUtil; - -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -public final class Int2ObjectConcurrentHashMap implements Int2ObjectMap { - private final ConcurrentHashMap backing; - private V defaultReturnValue; - - public Int2ObjectConcurrentHashMap() { - this(16); - } - - public Int2ObjectConcurrentHashMap(int initialCapacity) { - if (initialCapacity < 0) { - throw new IllegalArgumentException("Initial capacity cannot be negative: " + initialCapacity); - } - - this.backing = new ConcurrentHashMap<>(initialCapacity); - } - - public Int2ObjectConcurrentHashMap(Map map) { - this(Math.max(16, map.size())); - putAll(Objects.requireNonNull(map, "Source map cannot be null")); - } - - @Override - public V get(int key) { - V value = backing.get(key); - return value != null ? value : defaultReturnValue; - } - - @Override - public V get(Object key) { - V value = backing.get(key); - return value != null ? value : defaultReturnValue; - } - - @Override - public boolean isEmpty() { - return backing.isEmpty(); - } - - @Override - public boolean containsValue(Object value) { - return backing.containsValue(value); - } - - @Override - public void putAll(Map m) { - Objects.requireNonNull(m, "Source map cannot be null"); - backing.putAll(m); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public void defaultReturnValue(V rv) { - this.defaultReturnValue = rv; - } - - @Override - public V defaultReturnValue() { - return defaultReturnValue; - } - - @Override - public ObjectSet> int2ObjectEntrySet() { - return CollectionWrapperUtil.entrySetIntWrap(backing); - } - - @Override - public IntSet keySet() { - return CollectionWrapperUtil.wrapIntSet(backing.keySet()); - } - - @Override - public ObjectCollection values() { - return CollectionWrapperUtil.wrap(backing.values()); - } - - @Override - public boolean containsKey(int key) { - return backing.containsKey(key); - } - - @Override - public V put(int key, V value) { - return backing.put(key, value); - } - - @Override - public V remove(int key) { - return backing.remove(key); - } - - @Override - public void clear() { - backing.clear(); - } - - public V compute(int key, java.util.function.BiFunction remappingFunction) { - Objects.requireNonNull(remappingFunction); - return backing.compute(key, remappingFunction); - } - - public ConcurrentHashMap concurrentView() { - return backing; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Int2ObjectMap that)) return false; - - if (size() != that.size()) return false; - return int2ObjectEntrySet().containsAll(that.int2ObjectEntrySet()); - } - - @Override - public int hashCode() { - return backing.hashCode(); - } - - @Override - public String toString() { - return backing.toString(); - } - - public V getOrDefault(int key, V defaultValue) { - V value = get(key); - return value != null ? value : defaultValue; - } - - public V putIfAbsent(int key, V value) { - return backing.putIfAbsent(key, value); - } - - public boolean remove(int key, Object value) { - return backing.remove(key, value); - } - - public boolean replace(int key, V oldValue, V newValue) { - return backing.replace(key, oldValue, newValue); - } - - public V replace(int key, V value) { - return backing.replace(key, value); - } -}