Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add regional terrain/furniture resolution to mapgen
Browse files Browse the repository at this point in the history
Adds functionality to the regional map settings and mapgen so that
regional terrains like a "t_region_shrub" can be used in JSON mapgen to
denote regional appropriate terrain/furniture should be used, and the
actual weighted list of valid terrain/furniture can be defined in the
region settings and resolved from the regional "pseudo terrain" to an
actual terrain/furniture during mapgen.
ralreegorganon committed Nov 20, 2019

Verified

This commit was signed with the committer’s verified signature.
sandhose Quentin Gliech
1 parent 14e05ae commit c3e6861
Showing 12 changed files with 374 additions and 25 deletions.
13 changes: 13 additions & 0 deletions data/json/furniture_and_terrain/furniture-regional-pseudo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"type": "furniture",
"id": "f_region_flower",
"name": "this should never actually show up, it's a pseudo furniture",
"description": "this should never actually show up, it's a pseudo furniture",
"symbol": " ",
"color": "black",
"move_cost_mod": 0,
"required_str": 0,
"flags": [ "TRANSPARENT", "NOITEM" ]
}
]
32 changes: 32 additions & 0 deletions data/json/furniture_and_terrain/terrain-regional-pseudo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"type": "terrain",
"id": "t_region_groundcover",
"name": "this should never actually show up, it's a pseudo terrain",
"description": "this should never actually show up, it's a pseudo terrain",
"symbol": " ",
"color": "black",
"move_cost": 0,
"flags": [ "TRANSPARENT", "NOITEM" ]
},
{
"type": "terrain",
"id": "t_region_tree",
"name": "this should never actually show up, it's a pseudo terrain",
"description": "this should never actually show up, it's a pseudo terrain",
"symbol": " ",
"color": "black",
"move_cost": 0,
"flags": [ "TRANSPARENT", "NOITEM" ]
},
{
"type": "terrain",
"id": "t_region_shrub",
"name": "this should never actually show up, it's a pseudo terrain",
"description": "this should never actually show up, it's a pseudo terrain",
"symbol": " ",
"color": "black",
"move_cost": 0,
"flags": [ "TRANSPARENT", "NOITEM" ]
}
]
33 changes: 22 additions & 11 deletions data/json/mapgen/trailhead.json
Original file line number Diff line number Diff line change
@@ -20,9 +20,20 @@
":": "t_window_bars",
"c": "t_woodchips",
"W": "t_water_pump",
"T": "t_floor"
"T": "t_floor",
"7": [ "t_region_tree", "t_region_shrub" ],
"f": "t_dirt"
},
"furniture": {
"b": "f_boulder_small",
"s": "f_sign",
"B": "f_bench",
"=": "f_bench",
"w": "f_woodstove",
",": [ [ "f_region_flower", 1 ], [ "f_null", 100 ] ],
";": [ [ "f_region_flower", 1 ], [ "f_null", 100 ] ],
".": [ [ "f_region_flower", 1 ], [ "f_null", 100 ] ]
},
"furniture": { "b": "f_boulder_small", "s": "f_sign", "B": "f_bench", "=": "f_bench", "w": "f_woodstove" },
"toilets": { "T": { } }
},
{
@@ -54,8 +65,8 @@
";;;.. ;;;;;",
";;;;. ;;;;;",
";;;;; ;;;;;",
";;;;;tttt tttt;;;;;",
";;;;;b..b ss b..b;;;;;"
";77;;tttt tttt;;;;;",
"7777;b..b ss b..b;;;;;"
],
"palettes": [ "trailhead" ],
"place_vehicles": [
@@ -91,11 +102,11 @@
";;;... ...;;",
";;... |-|;;",
";;... . . . +T|;;",
";;;.. . |-|;;",
";;;;. . . . +T|;;",
";;;.. . |-|;7",
";;;;. . . . +T|;7",
";;;;; ;|-|;;",
";;;;;==== sss;;;;;;",
";;;;;;;;; ;;;;;;;;;"
";;;;;==== sss;;;;;7",
";;;;77;77 ;;;;;;;7;"
],
"palettes": [ "trailhead" ],
"place_vehicles": [ { "chance": 100, "fuel": 0, "rotation": 0, "status": 1, "vehicle": "campground_vehicles", "x": 17, "y": 9 } ],
@@ -136,7 +147,7 @@
";;;;. . . . ;;;;;",
";;;;; ;;;;;",
";;;;;tttt tttt;;;;;",
";;;;;b..b s s b..b;;;;;"
";;7;;b..b s s b..b;;7;;"
],
"palettes": [ "trailhead" ],
"place_vehicles": [
@@ -175,8 +186,8 @@
";;;c|B###+ ..;;;;;;;b",
";;;c|BB#w|s ..;;;;;;;;",
";;;c|--:-| ;;;;;;;;;",
";;;ccccccc ;;;;;;b;;",
";;;b;b;b; ;;b;;;;;;"
";7;ccccccc ;;;;;;b;;",
";;;b;b;b; ;;b;;;;7;"
],
"palettes": [ "trailhead" ],
"place_items": [ { "item": "camping", "x": [ 5, 5 ], "y": [ 18, 20 ], "chance": 70 } ],
62 changes: 61 additions & 1 deletion data/json/regional_map_settings.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,67 @@
"type": "region_settings",
"id": "default",
"default_oter": "field",
"default_groundcover": [ [ "t_grass", 4 ], [ "t_grass_long", 2 ], [ "t_dirt", 1 ] ],
"default_groundcover": [ [ "t_region_groundcover", 1 ] ],
"region_terrain_and_furniture": {
"terrain": {
"t_region_groundcover": { "t_grass": 4, "t_grass_long": 2, "t_dirt": 1 },
"t_region_shrub": {
"t_underbrush": 30,
"t_shrub": 5,
"t_shrub_blueberry": 1,
"t_shrub_strawberry": 1,
"t_shrub_blackberry": 1,
"t_shrub_raspberry": 1,
"t_shrub_huckleberry": 1,
"t_shrub_grape": 1,
"t_shrub_rose": 1,
"t_shrub_hydrangea": 1,
"t_shrub_lilac": 1
},
"t_region_tree": {
"t_tree": 128,
"t_tree_young": 128,
"t_tree_birch": 16,
"t_tree_elm": 16,
"t_tree_cottonwood": 16,
"t_tree_pine": 32,
"t_tree_maple": 32,
"t_tree_willow": 32,
"t_tree_hickory": 16,
"t_tree_walnut": 8,
"t_tree_chestnut": 8,
"t_tree_hazelnut": 2,
"t_tree_beech": 2,
"t_tree_blackjack": 8,
"t_tree_coffee": 2,
"t_tree_apple": 2,
"t_tree_apricot": 2,
"t_tree_cherry": 2,
"t_tree_juniper": 2,
"t_tree_peach": 2,
"t_tree_pear": 2,
"t_tree_plum": 2,
"t_tree_elderberry": 2,
"t_tree_mulberry": 2,
"t_tree_deadpine": 16,
"t_tree_hickory_dead": 16,
"t_tree_dead": 16
}
},
"furniture": {
"f_region_flower": {
"f_black_eyed_susan": 1,
"f_lily": 1,
"f_flower_tulip": 1,
"f_flower_spurge": 1,
"f_chamomile": 1,
"f_dandelion": 1,
"f_datura": 1,
"f_dahlia": 1,
"f_bluebell": 1
}
}
},
"river_scale": 1.0,
"field_coverage": {
"percent_coverage": 0.9333,
10 changes: 9 additions & 1 deletion data/json/test_regions.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,15 @@
"type": "region_settings",
"id": "desert_test",
"default_oter": "field",
"default_groundcover": [ [ "t_searth_test", 3 ], [ "t_sand", 1 ] ],
"default_groundcover": [ [ "t_region_groundcover", 1 ] ],
"region_terrain_and_furniture": {
"terrain": {
"t_region_groundcover": { "t_searth_test": 3, "t_sand": 1 },
"t_region_shrub": { "t_shrub": 1 },
"t_region_tree": { "t_tree_willow": 1, "t_tree_dead": 1 }
},
"furniture": { "f_region_flower": { "f_mutcactus_test": 1 } }
},
"field_coverage": {
"percent_coverage": 1.9333,
"default_ter": "t_sand",
10 changes: 9 additions & 1 deletion data/mods/desert_region/desert_regional_map_settings.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,15 @@
"type": "region_settings",
"id": "default",
"default_oter": "desert",
"default_groundcover": [ [ "t_searth_test", 4 ], [ "t_sand", 1 ] ],
"default_groundcover": [ [ "t_region_groundcover", 1 ] ],
"region_terrain_and_furniture": {
"terrain": {
"t_region_groundcover": { "t_searth_test": 4, "t_sand": 1 },
"t_region_shrub": { "t_shrub": 1 },
"t_region_tree": { "t_tree_willow": 1, "t_tree_dead": 1 }
},
"furniture": { "f_region_flower": { "f_mutcactus_test": 1 } }
},
"river_scale": 0.0,
"field_coverage": {
"percent_coverage": 0.1333,
66 changes: 55 additions & 11 deletions doc/REGION_SETTINGS.md
Original file line number Diff line number Diff line change
@@ -4,17 +4,18 @@ The **region_settings** define the attributes for map generation that apply to a
The general settings define the default overmap terrain and ground cover. Additional sections are
as follows:

| Section | Description |
| ------------------------------- | ------------------------------------------------------------------- |
| `field_coverage` | Defines the flora that cover the `field` overmap terrain. |
| `overmap_lake_settings` | Defines parameters for generating lakes in the region. |
| `overmap_forest_settings` | Defines parameters for generating forests and swamps in the region. |
| `forest_mapgen_settings` | Defines flora (and "stuff") that cover the `forest` terrain types. |
| `forest_trail_settings` | Defines the overmap and local structure of forest trails. |
| `city` | Defines the structural compositions of cities. |
| `map_extras` | Defines the map extra groups referenced by overmap terrains. |
| `weather` | Defines the base weather attributes for the region. |
| `overmap_feature_flag_settings` | Defines operations on overmap features based on their flags. |
| Section | Description |
| ------------------------------- | --------------------------------------------------------------------- |
| `region_terrain_and_furniture` | Defines the resolution of regional terrain/furniture to actual types. |
| `field_coverage` | Defines the flora that cover the `field` overmap terrain. |
| `overmap_lake_settings` | Defines parameters for generating lakes in the region. |
| `overmap_forest_settings` | Defines parameters for generating forests and swamps in the region. |
| `forest_mapgen_settings` | Defines flora (and "stuff") that cover the `forest` terrain types. |
| `forest_trail_settings` | Defines the overmap and local structure of forest trails. |
| `city` | Defines the structural compositions of cities. |
| `map_extras` | Defines the map extra groups referenced by overmap terrains. |
| `weather` | Defines the base weather attributes for the region. |
| `overmap_feature_flag_settings` | Defines operations on overmap features based on their flags. |

Note that for the default region, all attributes and sections are required.

@@ -41,6 +42,49 @@ Note that for the default region, all attributes and sections are required.
}
```

## Region Terrain / Furniture

The **region_terrain_and_furniture** section defines the resolution of regional terrain/furniture
to their actual terrain and furniture types for the region, with a weighted list for
terrain/furniture entry that defines the relative weight of a given entry when mapgen resolves the
regional entry to an actual entry.

### Fields

| Identifier | Description |
| ----------- | ------------------------------------------------------------------ |
| `terrain` | List of regional terrain and their corresponding weighted lists. |
| `furniture` | List of regional furniture and their corresponding weighted lists. |

### Example
```json
{
"region_terrain_and_furniture": {
"terrain": {
"t_region_groundcover": {
"t_grass": 4,
"t_grass_long": 2,
"t_dirt": 1
}
},
"furniture": {
"f_region_flower": {
"f_black_eyed_susan": 1,
"f_lily": 1,
"f_flower_tulip": 1,
"f_flower_spurge": 1,
"f_chamomile": 1,
"f_dandelion": 1,
"f_datura": 1,
"f_dahlia": 1,
"f_bluebell": 1
}
}
}
}
```


## Field Coverage

The **field_coverage** section defines the furniture and terrain that make up the flora that
8 changes: 8 additions & 0 deletions src/mapgen.cpp
Original file line number Diff line number Diff line change
@@ -2599,6 +2599,8 @@ void mapgen_function_json::generate( mapgendata &md )

objects.apply( md, point_zero );

resolve_regional_terrain_and_furniture( md );

m->rotate( rotation.get() );

if( md.terrain_type()->is_rotatable() ) {
@@ -2620,6 +2622,8 @@ void mapgen_function_json_nested::nest( mapgendata &dat, const point &offset ) c
}

objects.apply( dat, offset );

resolve_regional_terrain_and_furniture( dat );
}

/*
@@ -6263,6 +6267,8 @@ void map::draw_connections( mapgendata &dat )
}
}
}

resolve_regional_terrain_and_furniture( dat );
}

void map::place_spawns( const mongroup_id &group, const int chance,
@@ -7754,6 +7760,8 @@ bool update_mapgen_function_json::update_map( mapgendata &md, const point &offse
}
objects.apply( md, offset );

resolve_regional_terrain_and_furniture( md );

return true;
}

16 changes: 16 additions & 0 deletions src/mapgen_functions.cpp
Original file line number Diff line number Diff line change
@@ -4608,3 +4608,19 @@ void place_stairs( mapgendata &dat )
}
}
}

void resolve_regional_terrain_and_furniture( const mapgendata &dat )
{
for( const tripoint &p : dat.m.points_on_zlevel() ) {
const ter_id tid_before = dat.m.ter( p );
const ter_id tid_after = dat.region.region_terrain_and_furniture.resolve( tid_before );
if( tid_after != tid_before ) {
dat.m.ter_set( p, tid_after );
}
const furn_id fid_before = dat.m.furn( p );
const furn_id fid_after = dat.region.region_terrain_and_furniture.resolve( fid_before );
if( fid_after != fid_before ) {
dat.m.furn_set( p, fid_after );
}
}
}
3 changes: 3 additions & 0 deletions src/mapgen_functions.h
Original file line number Diff line number Diff line change
@@ -99,4 +99,7 @@ bool run_mapgen_update_func( const std::string &update_mapgen_id, const tripoint
bool run_mapgen_func( const std::string &mapgen_id, mapgendata &dat );
std::pair<std::map<ter_id, int>, std::map<furn_id, int>> get_changed_ids_from_update(
const std::string &update_mapgen_id );

void resolve_regional_terrain_and_furniture( const mapgendata &dat );

#endif
133 changes: 133 additions & 0 deletions src/regional_settings.cpp
Original file line number Diff line number Diff line change
@@ -359,6 +359,72 @@ static void load_overmap_lake_settings( JsonObject &jo,
}
}

static void load_region_terrain_and_furniture_settings( JsonObject &jo,
region_terrain_and_furniture_settings &region_terrain_and_furniture_settings,
const bool strict, const bool overlay )
{
if( !jo.has_object( "region_terrain_and_furniture" ) ) {
if( strict ) {
jo.throw_error( "\"region_terrain_and_furniture\": { ... } required for default" );
}
} else {
JsonObject region_terrain_and_furniture_settings_jo =
jo.get_object( "region_terrain_and_furniture" );

if( !region_terrain_and_furniture_settings_jo.has_object( "terrain" ) ) {
if( !overlay ) {
region_terrain_and_furniture_settings_jo.throw_error( "terrain required" );
}
} else {
JsonObject template_terrain_jo = region_terrain_and_furniture_settings_jo.get_object( "terrain" );
std::set<std::string> template_terrain_ids = template_terrain_jo.get_member_names();
for( const auto &template_terrain_id : template_terrain_ids ) {
if( template_terrain_id == "//" ) {
continue;
}
JsonObject terrain_jo = template_terrain_jo.get_object( template_terrain_id );
std::set<std::string> terrain_ids = terrain_jo.get_member_names();
for( const auto &terrain_id : terrain_ids ) {
if( terrain_id == "//" ) {
continue;
}
int weight = 0;
if( terrain_jo.read( terrain_id, weight ) ) {
region_terrain_and_furniture_settings.unfinalized_terrain[template_terrain_id][terrain_id] = weight;
}
}
}
}

if( !region_terrain_and_furniture_settings_jo.has_object( "furniture" ) ) {
if( !overlay ) {
region_terrain_and_furniture_settings_jo.throw_error( "furniture required" );
}
} else {
JsonObject template_furniture_jo =
region_terrain_and_furniture_settings_jo.get_object( "furniture" );
std::set<std::string> template_furniture_ids = template_furniture_jo.get_member_names();
for( const auto &template_furniture_id : template_furniture_ids ) {
if( template_furniture_id == "//" ) {
continue;
}
JsonObject furniture_jo = template_furniture_jo.get_object( template_furniture_id );
std::set<std::string> furniture_ids = furniture_jo.get_member_names();
for( const auto &furniture_id : furniture_ids ) {
if( furniture_id == "//" ) {
continue;
}
int weight = 0;
if( furniture_jo.read( furniture_id, weight ) ) {
region_terrain_and_furniture_settings.unfinalized_furniture[template_furniture_id][furniture_id] =
weight;
}
}
}
}
}
}

void load_region_settings( JsonObject &jo )
{
regional_settings new_region;
@@ -539,6 +605,9 @@ void load_region_settings( JsonObject &jo )

load_overmap_lake_settings( jo, new_region.overmap_lake, strict, false );

load_region_terrain_and_furniture_settings( jo, new_region.region_terrain_and_furniture, strict,
false );

region_settings_map[new_region.id] = new_region;
}

@@ -701,6 +770,8 @@ void apply_region_overlay( JsonObject &jo, regional_settings &region )
load_overmap_forest_settings( jo, region.overmap_forest, false, true );

load_overmap_lake_settings( jo, region.overmap_lake, false, true );

load_region_terrain_and_furniture_settings( jo, region.region_terrain_and_furniture, false, true );
}

void groundcover_extra::finalize() // FIXME: return bool for failure
@@ -899,6 +970,67 @@ void overmap_lake_settings::finalize()
}
}

void region_terrain_and_furniture_settings::finalize()
{
for( auto const &template_pr : unfinalized_terrain ) {
const ter_str_id template_tid( template_pr.first );
if( !template_tid.is_valid() ) {
debugmsg( "Tried to add invalid regional template terrain %s to region_terrain_and_furniture terrain.",
template_tid.c_str() );
continue;
}
for( auto const &actual_pr : template_pr.second ) {
const ter_str_id tid( actual_pr.first );
if( !tid.is_valid() ) {
debugmsg( "Tried to add invalid regional terrain %s to region_terrain_and_furniture terrain template %s.",
tid.c_str(), template_tid.c_str() );
continue;
}
terrain[template_tid.id()].add( tid.id(), actual_pr.second );
}
}

for( auto const &template_pr : unfinalized_furniture ) {
const furn_str_id template_fid( template_pr.first );
if( !template_fid.is_valid() ) {
debugmsg( "Tried to add invalid regional template furniture %s to region_terrain_and_furniture furniture.",
template_fid.c_str() );
continue;
}
for( auto const &actual_pr : template_pr.second ) {
const furn_str_id fid( actual_pr.first );
if( !fid.is_valid() ) {
debugmsg( "Tried to add invalid regional furniture %s to region_terrain_and_furniture furniture template %s.",
fid.c_str(), template_fid.c_str() );
continue;
}
furniture[template_fid.id()].add( fid.id(), actual_pr.second );
}
}
}

ter_id region_terrain_and_furniture_settings::resolve( const ter_id tid ) const
{
ter_id result = tid;
auto region_list = terrain.find( result );
while( region_list != terrain.end() ) {
result = *region_list->second.pick();
region_list = terrain.find( result );
}
return result;
}

furn_id region_terrain_and_furniture_settings::resolve( const furn_id fid ) const
{
furn_id result = fid;
auto region_list = furniture.find( result );
while( region_list != furniture.end() ) {
result = *region_list->second.pick();
region_list = furniture.find( result );
}
return result;
}

void regional_settings::finalize()
{
if( default_groundcover_str != nullptr ) {
@@ -912,6 +1044,7 @@ void regional_settings::finalize()
forest_composition.finalize();
forest_trail.finalize();
overmap_lake.finalize();
region_terrain_and_furniture.finalize();
get_options().add_value( "DEFAULT_REGION", id, no_translation( id ) );
}
}
13 changes: 13 additions & 0 deletions src/regional_settings.h
Original file line number Diff line number Diff line change
@@ -214,6 +214,18 @@ struct map_extras {
map_extras( const unsigned int embellished ) : chance( embellished ) {}
};

struct region_terrain_and_furniture_settings {
std::map<std::string, std::map<std::string, int>> unfinalized_terrain;
std::map<std::string, std::map<std::string, int>> unfinalized_furniture;
std::map<ter_id, weighted_int_list<ter_id>> terrain;
std::map<furn_id, weighted_int_list<furn_id>> furniture;

void finalize();
ter_id resolve( ter_id ) const;
furn_id resolve( furn_id ) const;
region_terrain_and_furniture_settings() = default;
};

/*
* Spationally relevant overmap and mapgen variables grouped into a set of suggested defaults;
* eventually region mapping will modify as required and allow for transitions of biomes / demographics in a smoooth fashion
@@ -233,6 +245,7 @@ struct regional_settings {
overmap_feature_flag_settings overmap_feature_flag;
overmap_forest_settings overmap_forest;
overmap_lake_settings overmap_lake;
region_terrain_and_furniture_settings region_terrain_and_furniture;

std::unordered_map<std::string, map_extras> region_extras;

0 comments on commit c3e6861

Please sign in to comment.