diff --git a/doc/JSON/REGION_SETTINGS.md b/doc/JSON/REGION_SETTINGS.md index 45a97648c20f3..e87da0cae008f 100644 --- a/doc/JSON/REGION_SETTINGS.md +++ b/doc/JSON/REGION_SETTINGS.md @@ -241,6 +241,11 @@ are interpreted. | `lake_depth` | Depth of lakes, expressed in Z-levels (e.g. -1 to -10). | | `shore_extendable_overmap_terrain` | List of overmap terrains that can be extended to the shore if adjacent. | | `shore_extendable_overmap_terrain_aliases` | Overmap terrains to treat as different overmap terrain for extending shore. | +| `invert_lakes` | Invert drawing of lakes. What would be a lake is land, what would be land is a lake. | +| `shore_ter` | Overmap terrain id of shore terrain place on boundary with land. | +| `surface_ter` | Overmap terrain id of surface terrain, placed on z = 0. | +| `interior_ter` | Overmap terrain id of interior terrain, placed between surface terrain and bed terrain. | +| `bed_ter` | Overmap terrain id of bed terrain, placed on bottom of the lake. | ### Example diff --git a/src/overmap_water.cpp b/src/overmap_water.cpp index ba69d0397ba14..76c7fa831654d 100644 --- a/src/overmap_water.cpp +++ b/src/overmap_water.cpp @@ -9,6 +9,7 @@ #include #include "coordinates.h" +#include "cuboid_rectangle.h" #include "debug.h" #include "enums.h" #include "flood_fill.h" @@ -261,15 +262,16 @@ void overmap::place_lakes( const std::vector &neighbor_overmaps double noise_threshold = settings_lake.noise_threshold_lake; const int lake_depth = settings_lake.lake_depth; + // For cases where lakes take up most or all of the map, we need to stop the flood-fill + // from being unbounded. However, the bounds cannot be simply the overmap edges, or the + // shorelines will not be generated properly. + inclusive_rectangle considered_bounds( point_om_omt( -5, -5 ), + point_om_omt( OMAPX + 5, OMAPY + 5 ) ); const auto is_lake = [&]( const point_om_omt & p ) { - return omt_lake_noise_threshold( origin, p, noise_threshold ); + return considered_bounds.contains( p ) && + settings_lake.invert_lakes ^ omt_lake_noise_threshold( origin, p, noise_threshold ); }; - const oter_id lake_surface( "lake_surface" ); - const oter_id lake_shore( "lake_shore" ); - const oter_id lake_water_cube( "lake_water_cube" ); - const oter_id lake_bed( "lake_bed" ); - // We'll keep track of our visited lake points so we don't repeat the work. std::unordered_set visited; @@ -281,7 +283,7 @@ void overmap::place_lakes( const std::vector &neighbor_overmaps } // It's a lake if it exceeds the noise threshold defined in the region settings. - if( !omt_lake_noise_threshold( origin, seed_point, noise_threshold ) ) { + if( !is_lake( seed_point ) ) { continue; } @@ -350,14 +352,14 @@ void overmap::place_lakes( const std::vector &neighbor_overmaps } } - ter_set( tripoint_om_omt( p, 0 ), shore ? lake_shore : lake_surface ); + ter_set( tripoint_om_omt( p, 0 ), shore ? settings_lake.shore : settings_lake.surface ); // If this is not a shore, we'll make our subsurface lake cubes and beds. if( !shore ) { for( int z = -1; z > lake_depth; z-- ) { - ter_set( tripoint_om_omt( p, z ), lake_water_cube ); + ter_set( tripoint_om_omt( p, z ), settings_lake.interior ); } - ter_set( tripoint_om_omt( p, lake_depth ), lake_bed ); + ter_set( tripoint_om_omt( p, lake_depth ), settings_lake.bed ); } } } diff --git a/src/regional_settings.cpp b/src/regional_settings.cpp index 725a60708298a..0aea0b666d37f 100644 --- a/src/regional_settings.cpp +++ b/src/regional_settings.cpp @@ -21,6 +21,11 @@ class mapgendata; +static const oter_str_id oter_lake_bed( "lake_bed" ); +static const oter_str_id oter_lake_shore( "lake_shore" ); +static const oter_str_id oter_lake_surface( "lake_surface" ); +static const oter_str_id oter_lake_water_cube( "lake_water_cube" ); + static const weighted_string_id_reader building_bin_reader( 1 ); static const weighted_string_id_reader furn_reader( 1 ); static const weighted_string_id_reader ter_reader( 1 ); @@ -516,6 +521,13 @@ void region_settings_overmap_connection::deserialize( const JsonObject &jo ) optional( jo, was_loaded, "inter_city_road_connection", inter_city_road_connection ); } +region_settings_lake::region_settings_lake() : + surface( oter_lake_surface ), + shore( oter_lake_shore ), + interior( oter_lake_water_cube ), + bed( oter_lake_bed ) +{} + void region_settings_lake::load( const JsonObject &jo, std::string_view ) { optional( jo, was_loaded, "noise_threshold_lake", noise_threshold_lake ); @@ -526,6 +538,11 @@ void region_settings_lake::load( const JsonObject &jo, std::string_view ) shore_extendable_overmap_terrain, sid_reader ); optional( jo, was_loaded, "shore_extendable_overmap_terrain_aliases", shore_extendable_overmap_terrain_aliases ); + optional( jo, was_loaded, "invert_lakes", invert_lakes, false ); + optional( jo, was_loaded, "surface_ter", surface, oter_lake_surface ); + optional( jo, was_loaded, "shore_ter", shore, oter_lake_shore ); + optional( jo, was_loaded, "interior_ter", interior, oter_lake_water_cube ); + optional( jo, was_loaded, "bed_ter", bed, oter_lake_bed ); } void shore_extendable_overmap_terrain_alias::deserialize( const JsonObject &jo ) diff --git a/src/regional_settings.h b/src/regional_settings.h index 4c0078bf73945..3830a469436cb 100644 --- a/src/regional_settings.h +++ b/src/regional_settings.h @@ -324,8 +324,13 @@ struct region_settings_lake { double noise_threshold_lake = 0.25; int lake_size_min = 20; int lake_depth = -5; + oter_str_id surface; + oter_str_id shore; + oter_str_id interior; + oter_str_id bed; std::vector shore_extendable_overmap_terrain; std::vector shore_extendable_overmap_terrain_aliases; + bool invert_lakes = false; bool was_loaded = false; void load( const JsonObject &jo, std::string_view ); @@ -333,7 +338,7 @@ struct region_settings_lake { static void load_region_settings_lake( const JsonObject &jo, const std::string &src ); static void reset(); - region_settings_lake() = default; + region_settings_lake(); }; struct region_settings_ocean {