diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index 1eb30747..883fd87b 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -509,30 +509,46 @@ Returns the map colour of a block at position. One of: `'brown_terracotta'`, `'green_terracotta'`, `'red_terracotta'`, `'black_terracotta'`, `'crimson_nylium'`, `'crimson_stem'`, `'crimson_hyphae'`, `'warped_nylium'`, `'warped_stem'`, `'warped_hyphae'`, `'warped_wart'` -### `sample_noise(pos, ...type?)` 1.18+ only +### `compute_density_function(pos, ...types?)` 1.19+ only - Samples the multi noise value(s) on the given position. -If no type is passed, returns a map of `continentalness`, `depth`, `erosion`, `humidity`, `temperature`, `weirdness`. -Otherwise, returns the map of that specific noise. +**Note: Replaces the old `sample_noise` function** + +Computes the density function(s) on the given position. Check the [Available Types](#available-types) for list of available density functions. + +If no types are passed in, it returns a list of all the available density functions. Built-in and custom ones.
-// without type
-sample_noise(pos) => {continentalness: 0.445300012827, erosion: 0.395399987698, temperature: 0.165399998426, ...}
 // passing type as multiple arguments
-sample_noise(pos, 'pillarRareness', 'aquiferBarrier') => {aquiferBarrier: -0.205013844481, pillarRareness: 1.04772473438}
+compute_density_function(pos, 'continents', 'depth') => {continents: -0.205013844481, depth: 1.04772473438}
 // passing types as a list with unpacking operator
-sample_noise(pos, ...['spaghetti3dFirst', 'spaghetti3dSecond']) => {spaghetti3dFirst: -0.186052125186, spaghetti3dSecond: 0.211626790923}
+compute_density_function(pos, ...['ridges', 'overworld/caves/pillars']) => {ridges: -0.186052125186, overworld/caves/pillars: 0.211626790923}
+// Custom Defined types
+compute_density_function(pos, 'mydatapack:my_density_func') => {mydatapack:my_density_func: -0.186052125186}
 
-Available types: +#### Available types: -`aquiferBarrier`, `aquiferFluidLevelFloodedness`, `aquiferFluidLevelSpread`, `aquiferLava`, `caveCheese`, -`caveEntrance`, `caveLayer`, `continentalness`, `depth`, `erosion`, `humidity`, `island`, `jagged`, `oreGap`, -`pillar`, `pillarRareness`, `pillarThickness`, `shiftX`, `shiftY`, `shiftZ`, `spaghetti2d`, `spaghetti2dElevation`, -`spaghetti2dModulator`, `spaghetti2dThickness`, `spaghetti3d`, `spaghetti3dFirst`, `spaghetti3dRarity`, -`spaghetti3dSecond`, `spaghetti3dThickness`, `spaghettiRoughness`, `spaghettiRoughnessModulator`, `temperature`, -`terrain`, `terrainFactor`, `terrainOffset`, `terrainPeaks`, `weirdness` +##### Built-in +`'barrier_noise'`, `'continents'`, `'depth'`, `'end/base_3d_noise'`, `'end/sloped_cheese'`, `'erosion'`, `'final_density'`, +`'fluid_level_floodedness_noise'`, `'fluid_level_spread_noise'`, `'initial_density_without_jaggedness'`, `'lava_noise'`, +`'nether/base_3d_noise'`, `'overworld/base_3d_noise'`, `'overworld/base_continents'`, `'overworld/caves/entrances'`, +`'overworld/caves/noodle'`, `'overworld/caves/pillars'`, `'overworld/caves/spaghetti_2d'`, `'overworld/caves/spaghetti_2d_thickness_modulator'`, +`'overworld/caves/spaghetti_roughness_function'`, `'overworld/continents'`, `'overworld/depth'`, `'overworld/erosion'`, +`'overworld/factor'`, `'overworld/jaggedness'`, `'overworld/offset'`, `'overworld/ridges'`, `'overworld/ridges_folded'`, +`'overworld/sloped_cheese'`, `'overworld_amplified/depth'`, `'overworld_amplified/factor'`, `'overworld_amplified/jaggedness'`, +`'overworld_amplified/offset'`, `'overworld_amplified/sloped_cheese'`, `'overworld_large_biomes/base_continents'`, +`'overworld_large_biomes/continents'`, `'overworld_large_biomes/depth'`, `'overworld_large_biomes/erosion'`, +`'overworld_large_biomes/factor'`, `'overworld_large_biomes/jaggedness'`, `'overworld_large_biomes/offset'`, +`'overworld_large_biomes/sloped_cheese'`, `'ridges'`, `'shift_x'`, `'shift_z'`, `'temperature'`, `'vegetation'`, +`'vein_gap'`, `'vein_gapbarrier_noise'`, `'vein_ridged'`, `'vein_toggle'`, `'y'`, `'zero'` + +##### Custom + +Custom defined density functions from datapacks are also available and can be used. However, unlike built-in types, these +ones must use full namespace. i.e. `namespace:path`. Examples: `'mydatapack:density_function'`, `'mydatapack:nested/density_function'` + +**Note: Custom density functions require a server relaunch after enabling the datapack.** ### `loaded(pos)` diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index d90729fd..e26ea19d 100644 --- a/docs/scarpet/resources/editors/idea/2.txt +++ b/docs/scarpet/resources/editors/idea/2.txt @@ -93,7 +93,7 @@ reload_chunk remove_all_markers reset_chunk run -sample_noise +compute_density_function save scan schedule diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 8d84d458..3f3b6b0a 100644 --- a/docs/scarpet/resources/editors/npp/scarpet.xml +++ b/docs/scarpet/resources/editors/npp/scarpet.xml @@ -57,7 +57,7 @@ hardness blast_resistance top loaded suffocates power ticks_randomly update block_tick random_tick in_slime_chunk set without_updates blocks_movement block_sound material map_colour block_state block_list block_tags block_data poi set_poi - place_item set_biome biome loaded_status generation_status sample_noise inhabited_time spawn_potential chunk_tickets + place_item set_biome biome loaded_status generation_status compute_density_function inhabited_time spawn_potential chunk_tickets plop harvest destroy create_explosion structure_eligibility structures structure_references set_structure reset_chunk reload_chunk create_datapack diff --git a/src/main/java/carpet/fakes/NoiseColumnSamplerInterface.java b/src/main/java/carpet/fakes/NoiseColumnSamplerInterface.java deleted file mode 100644 index 42efcc66..00000000 --- a/src/main/java/carpet/fakes/NoiseColumnSamplerInterface.java +++ /dev/null @@ -1,5 +0,0 @@ -package carpet.fakes; - -public interface NoiseColumnSamplerInterface { - double getNoiseSample(String name, int x, int y, int z); -} diff --git a/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java b/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java new file mode 100644 index 00000000..d423bb52 --- /dev/null +++ b/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java @@ -0,0 +1,7 @@ +package carpet.fakes; + +import net.minecraft.world.level.levelgen.DensityFunction; + +public interface RandomStateVisitorAccessor { + DensityFunction.Visitor getVisitor(); +} diff --git a/src/main/java/carpet/mixins/NoiseSampler_scarpetMixin.java b/src/main/java/carpet/mixins/NoiseSampler_scarpetMixin.java deleted file mode 100644 index 02ec89a5..00000000 --- a/src/main/java/carpet/mixins/NoiseSampler_scarpetMixin.java +++ /dev/null @@ -1,265 +0,0 @@ -package carpet.mixins; - -import carpet.fakes.NoiseColumnSamplerInterface; -import carpet.script.exception.InternalExpressionException; -import net.minecraft.core.QuartPos; -import net.minecraft.world.level.biome.Climate; -import net.minecraft.world.level.levelgen.NoiseRouter; -import net.minecraft.world.level.levelgen.NoiseRouterData; -//import net.minecraft.world.level.levelgen.NoiseSampler; -import net.minecraft.world.level.levelgen.NoiseSettings; -//import net.minecraft.world.level.levelgen.TerrainInfo; -import net.minecraft.world.level.levelgen.blending.Blender; -import net.minecraft.world.level.levelgen.synth.BlendedNoise; -import net.minecraft.world.level.levelgen.synth.NoiseUtils; -import net.minecraft.world.level.levelgen.synth.NormalNoise; -import net.minecraft.world.level.levelgen.synth.SimplexNoise; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(NoiseRouterData.class) -public abstract class NoiseSampler_scarpetMixin implements NoiseColumnSamplerInterface { - - /* - @Shadow @Final - private NoiseRouter router; - - @Shadow @Final - private BlendedNoise blendedNoise; - - @Shadow @Final @Nullable - private SimplexNoise islandNoise; - - @Shadow @Final - private NormalNoise barrierNoise; - - @Shadow @Final - private NormalNoise fluidLevelFloodednessNoise; - - @Shadow @Final - private NormalNoise fluidLevelSpreadNoise; - - @Shadow @Final - private NormalNoise lavaNoise; - - @Shadow @Final - private NormalNoise pillarRarenessModulator; - - @Shadow @Final - private NormalNoise pillarThicknessModulator; - - @Shadow @Final - private NormalNoise spaghetti2DElevationModulator; - - @Shadow @Final - private NormalNoise spaghetti2DRarityModulator; - - @Shadow @Final - private NormalNoise spaghetti2DThicknessModulator; - - @Shadow @Final - private NormalNoise spaghetti3DNoiseSource1; - - @Shadow @Final - private NormalNoise spaghetti3DNoiseSource2; - - @Shadow @Final - private NormalNoise spaghetti3DRarityModulator; - - @Shadow @Final - private NormalNoise spaghetti3DThicknessModulator; - - @Shadow @Final - private NormalNoise spaghettiRoughnessModulator; - - @Shadow @Final - private NormalNoise cheeseNoiseSource; - - @Shadow @Final - private NormalNoise gapNoise; - - @Shadow @Final - private NoiseSettings noiseSettings; - - @Shadow - protected abstract double sampleJaggedNoise(double d, double e, double f); - - @Shadow - protected abstract double getLayerizedCaverns(int x, int y, int z); - - @Shadow - protected abstract double getPillars(int x, int y, int z); - - @Shadow - protected abstract double getSpaghetti2D(int x, int y, int z); - - @Shadow - protected abstract double getSpaghetti3D(int x, int y, int z); - - @Shadow - protected abstract double spaghettiRoughness(int x, int y, int z); - - @Shadow - protected abstract double getBigEntrances(int x, int y, int z); - - @Shadow - public abstract double getOffset(int x, int y, int z); - - @Shadow - private static double sampleWithRarity(NormalNoise sampler, double x, double y, double z, double invertedScale) { - throw new AssertionError(); - } - - @Shadow - public abstract Climate.TargetPoint sample(int i, int j, int k); - - @Shadow - public abstract TerrainInfo terrainInfo(int x, int z, float continentalness, float weirdness, float erosion, Blender blender); - - @Override - public double getNoiseSample(String name, int x, int y, int z) { - Climate.TargetPoint noiseValuePoint = this.sample(x, y, z); - TerrainInfo terrainNoisePoint = terrainInfo( - x, - z, - Climate.unquantizeCoord(noiseValuePoint.continentalness()), - Climate.unquantizeCoord(noiseValuePoint.weirdness()), - Climate.unquantizeCoord(noiseValuePoint.erosion()), - Blender.empty() - ); - switch (name) { - case "temperature" -> { - return Climate.unquantizeCoord(noiseValuePoint.temperature()); - } - case "humidity" -> { - return Climate.unquantizeCoord(noiseValuePoint.humidity()); - } - case "continentalness" -> { - return Climate.unquantizeCoord(noiseValuePoint.continentalness()); - } - case "erosion" -> { - return Climate.unquantizeCoord(noiseValuePoint.erosion()); - } - case "weirdness" -> { - return Climate.unquantizeCoord(noiseValuePoint.weirdness()); - } - case "depth" -> { - return Climate.unquantizeCoord(noiseValuePoint.depth()); - } - case "shiftX" -> { - return x + this.getOffset(x, 0, z); - } - case "shiftY" -> { - return y + this.getOffset(y, z, x); - } - case "shiftZ" -> { - return z + this.getOffset(z, x, 0); - } - case "terrain" -> { - return this.blendedNoise.calculateNoise(x, y, z); - } - case "island" -> { - return this.islandNoise == null ? 0 : this.islandNoise.getValue(x, y, z); - } - case "jagged" -> { - return this.sampleJaggedNoise(terrainNoisePoint.jaggedness(), x, z); - } - case "aquiferBarrier" -> { - return this.barrierNoise.getValue(x, y, z); - } - case "aquiferFluidLevelFloodedness" -> { - return this.fluidLevelFloodednessNoise.getValue(x, y, z); - } - case "aquiferFluidLevelSpread" -> { - return this.fluidLevelSpreadNoise.getValue(x, y, z); - } - case "aquiferLava" -> { - return this.lavaNoise.getValue(x, y, z); - } - case "pillar" -> { - return this.getPillars(x, y, z); - } - case "pillarRareness" -> { - return NoiseUtils.sampleNoiseAndMapToRange(this.pillarRarenessModulator, x, y, z, 0.0D, 2.0D); - } - case "pillarThickness" -> { - return NoiseUtils.sampleNoiseAndMapToRange(this.pillarThicknessModulator, x, y, z, 0.0D, 1.1D); - } - case "spaghetti2d" -> { - return this.getSpaghetti2D(x, y, z); - } - case "spaghetti2dElevation" -> { - return NoiseUtils.sampleNoiseAndMapToRange(this.spaghetti2DElevationModulator, x, 0.0, z, this.noiseSettings.getMinCellY(), 8.0); - } - case "spaghetti2dModulator" -> { - return this.spaghetti2DRarityModulator.getValue(x * 2, y, z * 2); - } - case "spaghetti2dThickness" -> { - return NoiseUtils.sampleNoiseAndMapToRange(this.spaghetti2DThicknessModulator, x * 2, y, z * 2, 0.6, 1.3); - } - case "spaghetti3d" -> { - return this.getSpaghetti3D(x, y, z); - } - case "spaghetti3dFirst" -> { - double d = this.spaghetti3DRarityModulator.getValue(x * 2, y, z * 2); - double e = QuantizedSpaghettiRarityMixin_scarpetMixin.invokeGetSpaghettiRarity3D(d); - return sampleWithRarity(this.spaghetti3DNoiseSource1, x, y, z, e); - } - case "spaghetti3dSecond" -> { - double d = this.spaghetti3DRarityModulator.getValue(x * 2, y, z * 2); - double e = QuantizedSpaghettiRarityMixin_scarpetMixin.invokeGetSpaghettiRarity3D(d); - return sampleWithRarity(this.spaghetti3DNoiseSource2, x, y, z, e); - } - case "spaghetti3dRarity" -> { - return this.spaghetti3DRarityModulator.getValue(x * 2, y, z * 2); - } - case "spaghetti3dThickness" -> { - return NoiseUtils.sampleNoiseAndMapToRange(this.spaghetti3DThicknessModulator, x, y, z, 0.065, 0.088); - } - case "spaghettiRoughness" -> { - return this.spaghettiRoughness(x, y, z); - } - case "spaghettiRoughnessModulator" -> { - return NoiseUtils.sampleNoiseAndMapToRange(this.spaghettiRoughnessModulator, x, y, z, 0.0, 0.1); - } - case "caveEntrance" -> { - return this.getBigEntrances( - QuartPos.toBlock(x), - QuartPos.toBlock(y), - QuartPos.toBlock(z) - ); - } - case "caveLayer" -> { - // scaling them by 4 because it's sampled in normal coords - return this.getLayerizedCaverns( - QuartPos.toBlock(x), - QuartPos.toBlock(y), - QuartPos.toBlock(z) - ); - } - case "caveCheese" -> { - // same reason as above - return this.cheeseNoiseSource.getValue( - QuartPos.toBlock(x), - QuartPos.toBlock(y) / 1.5, - QuartPos.toBlock(z) - ); - } - case "terrainPeaks" -> { - return terrainNoisePoint.jaggedness(); - } - case "terrainOffset" -> { - return terrainNoisePoint.offset(); - } - case "terrainFactor" -> { - return terrainNoisePoint.factor(); - } - case "oreGap" -> { - return this.gapNoise.getValue(x, y, z); - } - } - throw new InternalExpressionException("Unknown noise type: " + name); - }*/ -} diff --git a/src/main/java/carpet/mixins/QuantizedSpaghettiRarityMixin_scarpetMixin.java b/src/main/java/carpet/mixins/QuantizedSpaghettiRarityMixin_scarpetMixin.java deleted file mode 100644 index f3eed7df..00000000 --- a/src/main/java/carpet/mixins/QuantizedSpaghettiRarityMixin_scarpetMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package carpet.mixins; - -//import net.minecraft.world.level.levelgen.NoiseRouterData; -//import net.minecraft.world.level.levelgen.NoiseSampler; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - - -@Mixin(targets = "net.minecraft.world.level.levelgen.NoiseRouterData$QuantizedSpaghettiRarity") -public interface QuantizedSpaghettiRarityMixin_scarpetMixin { - @Invoker - static double invokeGetSpaghettiRarity3D(double d) { - throw new AssertionError(); - } -} diff --git a/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java b/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java new file mode 100644 index 00000000..2e855238 --- /dev/null +++ b/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java @@ -0,0 +1,33 @@ +package carpet.mixins; + +import carpet.fakes.RandomStateVisitorAccessor; +import net.minecraft.world.level.levelgen.DensityFunction; +import net.minecraft.world.level.levelgen.RandomState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(RandomState.class) +public class RandomState_ScarpetMixin implements RandomStateVisitorAccessor { + @Unique + private DensityFunction.Visitor visitor; + + @ModifyArg( + method = "", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/levelgen/NoiseRouter;mapAll(Lnet/minecraft/world/level/levelgen/DensityFunction$Visitor;)Lnet/minecraft/world/level/levelgen/NoiseRouter;" + ), + index = 0 + ) + private DensityFunction.Visitor captureVisitor(DensityFunction.Visitor visitor) { + this.visitor = visitor; + return visitor; + } + + @Override + public DensityFunction.Visitor getVisitor() { + return this.visitor; + } +} diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index 2f6768fb..44fb1a09 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -3,6 +3,7 @@ package carpet.script.api; import carpet.CarpetSettings; import carpet.fakes.ChunkGeneratorInterface; import carpet.fakes.ChunkTicketManagerInterface; +import carpet.fakes.RandomStateVisitorAccessor; import carpet.fakes.ServerChunkManagerInterface; import carpet.fakes.ServerWorldInterface; import carpet.fakes.SpawnHelperInnerInterface; @@ -41,15 +42,22 @@ import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderSet; import net.minecraft.core.QuartPos; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.levelgen.DensityFunction; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.NoiseRouter; +import net.minecraft.world.level.levelgen.RandomState; import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.synth.NormalNoise; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -1626,23 +1634,68 @@ public class WorldAccess { } @ScarpetFunction(maxParams = -1) - public Value sample_noise(Context c, @Locator.Block BlockPos pos, String... noiseQueries) { - return Value.NULL; - /* - int mappedX = QuartPos.fromBlock(pos.getX()); - int mappedY = QuartPos.fromBlock(pos.getY()); - int mappedZ = QuartPos.fromBlock(pos.getZ()); - Climate.Sampler mns = ((CarpetContext) c).s.getLevel().getChunkSource().getGenerator().climateSampler(); - Map ret = new HashMap<>(); + public Value compute_density_function(Context c, @Locator.Block BlockPos pos, String... densityFunctionQueries) { - if (noiseQueries.length == 0) { - noiseQueries = new String[]{"continentalness", "erosion", "weirdness", "temperature", "humidity", "depth"}; + Map result = new HashMap<>(); + + ServerLevel level = ((CarpetContext) c).level(); + Registry densityFunctionRegistry = level.registryAccess().registryOrThrow(Registries.DENSITY_FUNCTION); + + if (densityFunctionQueries.length == 0) { + return ListValue.wrap(densityFunctionRegistry.keySet().stream().map(ValueConversions::of)); } - for (String noise : noiseQueries) { - double noiseValue = ((NoiseColumnSamplerInterface) mns).getNoiseSample(noise, mappedX, mappedY, mappedZ); - ret.put(new StringValue(noise), new NumericValue(noiseValue)); + ChunkGenerator chunkGenerator = level.getChunkSource().getGenerator(); + if (!(chunkGenerator instanceof NoiseBasedChunkGenerator generator)) { + return MapValue.wrap(result); } - return MapValue.wrap(ret);*/ + + RandomState randomState = RandomState.create( + generator.generatorSettings().value(), + level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed() + ); + + DensityFunction.Visitor visitor = ((RandomStateVisitorAccessor) (Object) randomState).getVisitor(); + DensityFunction.SinglePointContext singlePointContext = new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ()); + NoiseRouter router = generator.generatorSettings().value().noiseRouter(); + + for (String densityFunctionQuery : densityFunctionQueries) { + DensityFunction densityFunction = switch (densityFunctionQuery) { + case "barrier_noise" -> router.barrierNoise(); + case "fluid_level_floodedness_noise" -> router.fluidLevelFloodednessNoise(); + case "fluid_level_spread_noise" -> router.fluidLevelSpreadNoise(); + case "lava_noise" -> router.lavaNoise(); + case "temperature" -> router.temperature(); + case "vegetation" -> router.vegetation(); + case "continents" -> router.continents(); + case "erosion" -> router.erosion(); + case "depth" -> router.depth(); + case "ridges" -> router.ridges(); + case "initial_density_without_jaggedness" -> router.initialDensityWithoutJaggedness(); + case "final_density" -> router.finalDensity(); + case "vein_toggle" -> router.veinToggle(); + case "vein_ridged" -> router.veinRidged(); + case "vein_gap" -> router.veinGap(); + default -> { + ResourceLocation densityFunctionKey = InputValidator.identifierOf(densityFunctionQuery); + + if (densityFunctionRegistry.containsKey(densityFunctionKey)) { + yield densityFunctionRegistry.get(densityFunctionKey); + } + + throw new InternalExpressionException( + "Density function '" + densityFunctionQuery + "' doesn't exist. " + + "Please check the spelling or use with full 'namespace:value' if its custom defined." + ); + } + }; + + if (densityFunction == null) // IDE thinks may be null as Registry.get is Nullable, but we checked it + throw new IllegalStateException("density function can't be null here"); + + double value = densityFunction.mapAll(visitor).compute(singlePointContext); + result.put(StringValue.of(densityFunctionQuery), new NumericValue(value)); + } + return MapValue.wrap(result); } } diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 13bd6b23..f154e797 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -162,8 +162,7 @@ "BlockPredicate_scarpetMixin", "TagPredicate_scarpetMixin", "HorseBaseEntity_scarpetMixin", - "NoiseSampler_scarpetMixin", - "QuantizedSpaghettiRarityMixin_scarpetMixin", + "RandomState_ScarpetMixin", "Biome_scarpetMixin", "BlockEntity_movableBEMixin",