Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parametric mapgen part 1: global random terrain selection #48529

Merged
merged 6 commits into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion data/json/mapgen/house/crack_house.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,14 @@
" ",
" "
],
"parameters": {
"roof_type": {
"type": "ter_str_id",
"default": { "distribution": [ [ "t_flat_roof", 2 ], [ "t_tar_flat_roof", 1 ], [ "t_shingle_flat_roof", 1 ] ] }
}
},
"palettes": [ "roof_palette" ],
"terrain": { ".": "t_shingle_flat_roof" }
"terrain": { ".": { "param": "roof_type" } }
}
},
{
Expand Down
55 changes: 55 additions & 0 deletions doc/MAPGEN.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
* [Place a zone for an NPC faction with "zones"](#place-a-zone-for-an-npc-faction-with-zones)
* [Translate terrain type with "translate_ter"](#translate-terrain-type-with-translate_ter)
* [Apply mapgen transformation with "ter_furn_transforms"](#apply-mapgen-transformation-with-ter_furn_transforms)
* [Mapgen values](#mapgen-values)
* [Mapgen parameters](#mapgen-parameters)
* [Rotate the map with "rotation"](#rotate-the-map-with-rotation)
* [Pre-load a base mapgen with "predecessor_mapgen"](#pre-load-a-base-mapgen-with-predecessor_mapgen)
* [Using update_mapgen](#using-update_mapgen)
Expand Down Expand Up @@ -1037,6 +1039,59 @@ an `update_mapgen`, as normal mapgen can just specify the terrain directly.
- "transform": (required, string) the id of the `ter_furn_transform` to run.


## Mapgen values

A *mapgen value* can be used in various places where a specific id is expected.
For example, the default value of a parameter, or a terrain id in the
`"terrain"` object. A mapgen value can take one of three forms:

* A simple string, which should be a literal id. For example, `"t_flat_roof"`.
* A JSON object containing the key `"distribution"`, whose corresponding value
is a list of lists, each a pair of a string id and an integer weight. For
example:
```
{ "distribution": [ [ "t_flat_roof", 2 ], [ "t_tar_flat_roof", 1 ], [ "t_shingle_flat_roof", 1 ] ] }
```
* A JSON object containing the key `"param"`, whose corresponding value is the
string name of a parameter as discussed in [Mapgen
parameters](#mapgen-parameters). For example, `{ "param": "roof_type" }`.


## Mapgen parameters

(Note that this feature is under development and functionality may not line up exactly
with the documentation.)

Another entry within a mapgen definition can be a `"parameters"` key. For
example:
```
"parameters": {
"roof_type": {
"type": "ter_str_id",
"default": { "distribution": [ [ "t_flat_roof", 2 ], [ "t_tar_flat_roof", 1 ], [ "t_shingle_flat_roof", 1 ] ] }
}
},
```

Each entry in the `"parameters"` JSON object defines a parameter. The key is
the parameter name. Each such key should have an associated JSON object. That
object must provide its type (which should be a type string as for a
`cata_variant`) and may optionally provide a default value. The default value
should be a [mapgen value](#mapgen-value) as defined above.

At time of writing, the only way for a parameter to get a value is via the
`"default"`, so you probably want to always have one.

The primary application of parameters is that you can use a `"distribution"`
mapgen value to select a value at random, and then apply that value to every
use of that parameter. In the above example, a random roof terrain is picked.
By using the parameter with some `"terrain"` key, via a `"param"` mapgen value,
you can use a random but consistent choice of roof terrain across your map.
In contrast, placing the `"distribution"` directly in the `"terrain"` object would
cause mapgen to choose a terrain at random for each roof tile, leading to a
mishmash of roof terrains.


## Rotate the map with "rotation"

Rotates the generated map after all the other mapgen stuff has been done. The value can be a single integer or a range
Expand Down
6 changes: 6 additions & 0 deletions src/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,12 @@ void JsonArray::verify_index( const size_t i ) const

/* iterative access */

JsonValue JsonArray::next()
{
verify_index( index );
return JsonValue( *jsin, positions[index++] );
}

bool JsonArray::next_bool()
{
verify_index( index );
Expand Down
1 change: 1 addition & 0 deletions src/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,7 @@ class JsonArray
[[noreturn]] void string_error( const std::string &err, int idx, int offset );

// iterative access
JsonValue next();
bool next_bool();
int next_int();
double next_float();
Expand Down
9 changes: 1 addition & 8 deletions src/magic_ter_fur_transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,7 @@ static void load_transform_results( const JsonObject &jsi, const std::string &js
list.add( T( jsi.get_string( json_key ) ), 1 );
return;
}
for( const JsonValue entry : jsi.get_array( json_key ) ) {
if( entry.test_array() ) {
JsonArray inner = entry.get_array();
list.add( T( inner.get_string( 0 ) ), inner.get_int( 1 ) );
} else {
list.add( T( entry.get_string() ), 1 );
}
}
load_weighted_list( jsi.get_member( json_key ), list, 1 );
}

template<class T>
Expand Down
Loading