diff --git a/doc/MAPGEN.md b/doc/MAPGEN.md index cdb182236fc19..b9f2630b6ced5 100644 --- a/doc/MAPGEN.md +++ b/doc/MAPGEN.md @@ -297,24 +297,35 @@ Examples: # JSON object definition -The JSON object for a mapgen entry must include either `"fill_ter"`, or `"rows"` and `"terrain"`. All other fields are -optional. - - ## Fill terrain using "fill_ter" Fill with the given terrain. -Value: `"string"`: Valid terrain id from data/json/terrain.json +terrain id string or [mapgen value](#mapgen-values) -Example: `"fill_ter": "t_region_groundcover"` +### Examples + +Every tile lacking a terrain character definition will be `t_region_groundcover` +`"fill_ter": "t_region_groundcover"` + +Every tile lacking a terrain character definition will the same one of `t_floor`, `t_pavement` and `t_concrete` across the omt, with `t_floor`being twice as likely to be picked +```json +"parameters": { + "floor_type": { + "type": "ter_str_id", + "scope": "omt", + "default": { "distribution": [ [ "t_floor", 2 ], [ "t_pavement", 1 ], [ "t_concrete", 1 ] ] } + } +}, +"fill_ter": { "param": "floor_type" }, +``` ## ASCII map using "rows" array Nested array usually of 24 strings, each 24 characters long but can vary for nests (in which case between 1 and 24) and defining multiple overmap terrains maps at once (in which case a multiple of 24), -where each character is defined by "terrain" and optionally "furniture" or other entries below. -Defaults to all spaces " " if unset. +where each character can be defined by "terrain" and "furniture" or other entries below. +`"rows"` can be omitted entirely in which case each row is set to all `" "` (of the appropriate size if used with nests). Usage: @@ -325,19 +336,9 @@ Usage: Other parts can be linked with this map, for example one can place things like a gaspump (with gasoline) or a toilet (with water) or items from an item group or fields at the square given by a character. -Any character used here must have some definition elsewhere to indicate its purpose. Failing to do so is an error which -will be caught by running the tests. The tests will run automatically when you make a pull request for adding new maps -to the game. If you have defined `fill_ter` or you are writing nested mapgen, then there are a couple of exceptions. -The space and period characters (` ` and `.`) are permitted to have no definition and be used for 'background' in the -`rows`. - -As keys, you can use any Unicode characters which are not double-width. This includes for example most European -alphabets but not Chinese characters. If you intend to take advantage of this, ensure that your editor is saving the -file with a UTF-8 encoding. Accents are acceptable, even when using [combining -characters](https://en.wikipedia.org/wiki/Combining_character). No normalization is performed; comparison is done at -the raw bytes (code unit) level. Therefore, there are literally an infinite number of mapgen key characters available. -Please don't abuse this by using distinct characters that are visually indistinguishable, or which are so rare as to be -unlikely to render correctly for other developers. +If you specify one of `fill_ter`, `predecessor_mapgen`, `fallback_predecessor_mapgen` or you are writing nested mapgen +then the space and period characters (` ` and `.`) are permitted to have no definition and be used for 'background' in the `rows`. +Otherwise any character used must have some definition to indicate its purpose, whether directly in the mapgen or in a specified palette. Example: @@ -374,7 +375,8 @@ Example: ### Row terrains in "terrain" **usually required by "rows"** -Defines terrain ids for "rows", each key is a single character with a terrain id string +Defines terrain ids for `"rows"`, each key is a single character with a terrain id string or [mapgen value](#mapgen-values) +If you want to remove a terrain definition from a palette in preference of a fallback you can use `t_null` Value: `{object}: { "a", "t_identifier", ... }` @@ -405,8 +407,8 @@ Example: ### Furniture symbols in "furniture" array **optional** -Defines furniture ids for "rows" ( each character in rows is a terrain -or- terrain/furniture combo ). "f_null" means no -furniture but the entry can be left out +Defines furniture ids for `"rows"`, each key is a single character with a furniture id string or [mapgen value](#mapgen-values) +If you want to remove a furniture definition from a palette you can use `f_null` Example: @@ -426,6 +428,15 @@ Example: }, ``` +### Acceptable characters + +You should aim to make the rows as clear as possible with your character choice but +you can use any Unicode characters which are not double-width. This includes for example most European +alphabets but not Chinese characters. If you intend to take advantage of this, ensure that your editor is saving the +file with a UTF-8 encoding. Accents are acceptable, even when using [combining +characters](https://en.wikipedia.org/wiki/Combining_character). No normalization is performed; comparison is done at +the raw bytes (code unit) level. Therefore, there are literally an infinite number of mapgen key characters available. + ## Mapgen flags `"flags"` may provide a list of flags to be applied to the mapgen. diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 4015eb59017b6..0b83f05d02f49 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -969,7 +969,6 @@ mapgen_function_json::mapgen_function_json( const JsonObject &jsobj, dbl_or_var w, const std::string &context, const point &grid_offset, const point &grid_total ) : mapgen_function( std::move( w ) ) , mapgen_function_json_base( jsobj, context ) - , fill_ter( t_null ) , rotation( 0 ) , fallback_predecessor_mapgen_( oter_str_id::NULL_ID() ) { @@ -4519,9 +4518,8 @@ bool mapgen_function_json::setup_internal( const JsonObject &jo ) jo.throw_error( "\"mapgensize\" only allowed for nested mapgen" ); } - // something akin to mapgen fill_background. - if( jo.has_string( "fill_ter" ) ) { - fill_ter = ter_str_id( jo.get_string( "fill_ter" ) ).id(); + if( jo.has_member( "fill_ter" ) ) { + fill_ter = cata::make_value>( jo.get_member( "fill_ter" ) ); } if( jo.has_member( "rotation" ) ) { @@ -4536,7 +4534,7 @@ bool mapgen_function_json::setup_internal( const JsonObject &jo ) jo.read( "fallback_predecessor_mapgen", fallback_predecessor_mapgen_ ); - return fill_ter != t_null || predecessor_mapgen != oter_str_id::NULL_ID() || + return fill_ter || predecessor_mapgen != oter_str_id::NULL_ID() || fallback_predecessor_mapgen_ != oter_str_id::NULL_ID(); } @@ -4730,10 +4728,10 @@ bool mapgen_function_json_base::setup_common( const JsonObject &jo ) } fallback_terrain_exists = true; - // No fill_ter? No format? GTFO. + // TODO: Pointless check??? if( !fallback_terrain_exists ) { jo.throw_error( - "Need one of 'fill_terrain', 'predecessor_mapgen', 'fallback_predecessor_mapgen', 'terrain' or a palette providing 'terrain'." ); + "Need one of 'fill_ter', 'predecessor_mapgen', 'fallback_predecessor_mapgen', 'terrain' or a palette providing 'terrain'." ); // TODO: write TFM. } @@ -4880,6 +4878,16 @@ std::unordered_set nested_mapgen::all_placement_coords() const return result; } +void nested_mapgen::add( const std::shared_ptr &p, int weight ) +{ + funcs_.add( p, weight ); +} + +void update_mapgen::add( std::unique_ptr &&p ) +{ + funcs_.push_back( std::move( p ) ); +} + void jmapgen_objects::finalize() { std::stable_sort( objects.begin(), objects.end(), compare_phases ); @@ -5338,9 +5346,6 @@ static ret_val apply_mapgen_in_phases( void mapgen_function_json::generate( mapgendata &md ) { map *const m = &md.m; - if( fill_ter != t_null ) { - m->draw_fill_background( fill_ter ); - } const oter_t &ter = *md.terrain_type(); auto do_predecessor_mapgen = [&]( mapgendata & predecessor_md ) { @@ -5386,6 +5391,15 @@ void mapgen_function_json::generate( mapgendata &md ) mapgendata md_with_params( md, get_args( md, mapgen_parameter_scope::omt ), flags_ ); + if( fill_ter ) { + const ter_id chosen_fill_ter = fill_ter->get( md_with_params ); + if( chosen_fill_ter != t_null ) { + m->draw_fill_background( chosen_fill_ter ); + } else { + debugmsg( "fill_ter resolved to t_null" ); + } + } + apply_mapgen_in_phases( md_with_params, setmap_points, objects, tripoint_rel_ms( tripoint_zero ), context_ ); @@ -7898,7 +7912,6 @@ bool update_mapgen_function_json::setup_update( const JsonObject &jo ) bool update_mapgen_function_json::setup_internal( const JsonObject &/*jo*/ ) { - fill_ter = t_null; /* update_mapgen doesn't care about fill_ter or rows */ return true; } diff --git a/src/mapgen.h b/src/mapgen.h index 22f6ddef916ce..85bd276b0fca0 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -511,7 +511,7 @@ class mapgen_function_json : public mapgen_function_json_base, public virtual ma const point &grid_offset, const point &grid_total ); ~mapgen_function_json() override = default; - ter_id fill_ter; + cata::value_ptr> fill_ter; oter_id predecessor_mapgen; protected: @@ -544,7 +544,7 @@ class update_mapgen_function_json : public mapgen_function_json_base protected: bool setup_internal( const JsonObject &/*jo*/ ) override; - ter_id fill_ter; + cata::value_ptr> fill_ter; }; class mapgen_function_json_nested : public mapgen_function_json_base @@ -571,9 +571,7 @@ class nested_mapgen const weighted_int_list> &funcs() const { return funcs_; } - void add( const std::shared_ptr &p, int weight ) { - funcs_.add( p, weight ); - } + void add( const std::shared_ptr &p, int weight ); // Returns a set containing every relative coordinate of a point that // might have something placed by this mapgen std::unordered_set all_placement_coords() const; @@ -587,9 +585,7 @@ class update_mapgen const std::vector> &funcs() const { return funcs_; } - void add( std::unique_ptr &&p ) { - funcs_.push_back( std::move( p ) ); - } + void add( std::unique_ptr &&p ); private: std::vector> funcs_; };