diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index 883fd87b..76a55997 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -509,47 +509,28 @@ 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'` -### `compute_density_function(pos, ...types?)` 1.19+ only +### `sample_density()`, `sample_density(pos, ... types?)` 1.19+ -**Note: Replaces the old `sample_noise` function** +**Note: Replaces the old defunct `sample_noise` function** -Computes the density function(s) on the given position. Check the [Available Types](#available-types) for list of available density functions. +Samples the density function(s) / worldgen noise values at a given position. -If no types are passed in, it returns a list of all the available density functions. Built-in and custom ones. +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): + +`'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'`
+// requesting single value
+sample_density(pos, 'continents') => 0.211626790923
 // passing type as multiple arguments
-compute_density_function(pos, 'continents', 'depth') => {continents: -0.205013844481, depth: 1.04772473438}
-// passing types as a list with unpacking operator
-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}
+sample_density(pos, 'continents', 'depth', 'overworld/caves/pillars', 'mydatapack:foo/my_function') => [-0.205013844481, 1.04772473438, 0.211626790923, 0.123]
 
-#### Available types: - -##### 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)` Boolean function, true if the block is accessible for the game mechanics. Normally `scarpet` doesn't check if operates diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index e26ea19d..e87e81ee 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 -compute_density_function +sample_density save scan schedule diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 3f3b6b0a..8e09742c 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 compute_density_function inhabited_time spawn_potential chunk_tickets + place_item set_biome biome loaded_status generation_status sample_density 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 5e983124..969d971c 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -1632,6 +1632,24 @@ public class WorldAccess { return new NumericValue(ticket.timeout()); }); + expression.addContextFunction("sample_density", -1, (c, t, lv) -> + { + final CarpetContext cc = (CarpetContext) c; + if (lv.size() == 0) { + return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of)); + } + final ServerLevel level = cc.level(); + final BlockArgument locator = BlockArgument.findIn(cc, lv, 0); + final BlockPos pos = locator.block.getPos(); + final String[] densityFunctionQueries = lv.stream().skip(locator.offset).map(Value::getString).toArray(String[]::new); + if (densityFunctionQueries.length == 0) { + return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of)); + } + if (densityFunctionQueries.length == 1) { + return NumericValue.of(stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, densityFunctionQueries[0])).apply(pos)); + } + return ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, s)).apply(pos)))); + }); } public static Function, Function> stupidWorldgenNoiseCacheGetter = Util.memoize(pair -> { @@ -1665,10 +1683,7 @@ public class WorldAccess { 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." - ); + throw new InternalExpressionException("Density function '" + densityFunctionQuery + "' is not defined in the registies."); } }; @@ -1684,17 +1699,4 @@ public class WorldAccess { } return origin -> 0.0; }); - - @ScarpetFunction(maxParams = -1) - public Value compute_density_function(Context c, @Locator.Block BlockPos pos, String... densityFunctionQueries) { - final CarpetContext cc = (CarpetContext) c; - if (densityFunctionQueries.length == 0) { - return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of)); - } - final ServerLevel level = cc.level(); - if (densityFunctionQueries.length == 1) { - return NumericValue.of(stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, densityFunctionQueries[0])).apply(pos)); - } - return ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, s)).apply(pos)))); - } }