diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index 28f75b5d..e900466e 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -509,19 +509,18 @@ 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_density()`, `sample_density(pos, ... types?)` 1.19+ +### `sample_noise()`, `sample_noise(pos, ... types?)` 1.18+ -**Note: Replaces the old defunct `sample_noise` function** - -Samples the density function(s) / worldgen noise values at a given position. +Samples the world generation noise values / data driven density function(s) at a given position. If no types are passed in, or no arguments are given, it returns a list of all the available registry defined density functions. -Function accepts any registry defined density functions, both built in, as well as namespaced defined in datapacks. -On top of that, scarpet provides the following list of functions for convenience (not returned with no-argument call): - With a single function name passed in, it returns a scalar. With multiple function names passed in, it returns a list of results. +Function accepts any registry defined density functions, both built in, as well as namespaced defined in datapacks. +On top of that, scarpet provides the following list of noises sampled directly from the current level (and not returned with no-argument call): + + `'barrier_noise'`, `'fluid_level_floodedness_noise'`, `'fluid_level_spread_noise'`, `'lava_noise'`, `'temperature'`, `'vegetation'`, `'continents'`, `'erosion'`, `'depth'`, `'ridges'`, `'initial_density_without_jaggedness'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'` diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index e87e81ee..d90729fd 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_density +sample_noise save scan schedule diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 8e09742c..8d84d458 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_density inhabited_time spawn_potential chunk_tickets + place_item set_biome biome loaded_status generation_status sample_noise 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/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index 969d971c..44d3d5e8 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -52,6 +52,7 @@ 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.DensityFunctions; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseRouter; import net.minecraft.world.level.levelgen.RandomState; @@ -1632,7 +1633,7 @@ public class WorldAccess { return new NumericValue(ticket.timeout()); }); - expression.addContextFunction("sample_density", -1, (c, t, lv) -> + expression.addContextFunction("sample_noise", -1, (c, t, lv) -> { final CarpetContext cc = (CarpetContext) c; if (lv.size() == 0) { @@ -1645,14 +1646,53 @@ public class WorldAccess { if (densityFunctionQueries.length == 0) { return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of)); } + NoiseRouter router = level.getChunkSource().randomState().router(); if (densityFunctionQueries.length == 1) { - return NumericValue.of(stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, densityFunctionQueries[0])).apply(pos)); + return NumericValue.of(sampleNoise(router, level, densityFunctionQueries[0], pos)); } - return ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, s)).apply(pos)))); + return ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(sampleNoise(router, level, s, pos)))); }); } - public static Function, Function> stupidWorldgenNoiseCacheGetter = Util.memoize(pair -> { + public static double sampleNoise(NoiseRouter router, ServerLevel level, String what, BlockPos pos) { + DensityFunction densityFunction = switch (what) { + 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 -> stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what)); + /*ResourceLocation densityFunctionKey = InputValidator.identifierOf(what); + Registry densityFunctionRegistry = level.registryAccess().registryOrThrow(Registries.DENSITY_FUNCTION); + if (densityFunctionRegistry.containsKey(densityFunctionKey) && level.getChunkSource().getGenerator() instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { + DensityFunction densityFunction1 = densityFunctionRegistry.get(densityFunctionKey); + RandomState randomState = RandomState.create( + noiseBasedChunkGenerator.generatorSettings().value(), + level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed() + ); + DensityFunction.Visitor visitor = ((RandomStateVisitorAccessor) (Object) randomState).getVisitor(); + + DensityFunction temp = densityFunction.mapAll(visitor); + } + + throw new InternalExpressionException("Density function '" + what + "' is not defined in the registies.");*/ + + }; + return densityFunction.compute(new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ())); + } + + // to be used with future seedable noise + public static Function, DensityFunction> stupidWorldgenNoiseCacheGetter = Util.memoize(pair -> { ServerLevel level = pair.getKey(); String densityFunctionQuery = pair.getValue(); ChunkGenerator generator = level.getChunkSource().getGenerator(); @@ -1695,8 +1735,8 @@ public class WorldAccess { DensityFunction temp = densityFunction.mapAll(visitor); - return pos -> temp.compute(new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ())); + return temp; } - return origin -> 0.0; + return DensityFunctions.zero(); }); }