From eeedbe2c41a5e10b861ba07d04ae3b6aa500a6ef Mon Sep 17 00:00:00 2001 From: Volch Date: Wed, 15 Nov 2023 21:06:23 +0300 Subject: [PATCH] Sewer rework --- data/json/overmap/overmap_connections.json | 2 +- src/mapgen_functions.cpp | 125 ++++++--------------- src/mapgen_functions.h | 5 +- src/overmap.cpp | 37 +++--- src/overmap.h | 3 +- 5 files changed, 58 insertions(+), 114 deletions(-) diff --git a/data/json/overmap/overmap_connections.json b/data/json/overmap/overmap_connections.json index b79d2d98c95b..739b1e876841 100644 --- a/data/json/overmap/overmap_connections.json +++ b/data/json/overmap/overmap_connections.json @@ -4,11 +4,11 @@ "id": "local_road", "default_terrain": "road", "subtypes": [ + { "terrain": "road_nesw_manhole", "locations": [ ] }, { "terrain": "road", "locations": [ "field", "road" ] }, { "terrain": "road", "locations": [ "forest_without_trail" ], "basic_cost": 20 }, { "terrain": "road", "locations": [ "forest_trail" ], "basic_cost": 25 }, { "terrain": "road", "locations": [ "swamp" ], "basic_cost": 40 }, - { "terrain": "road_nesw_manhole", "locations": [ ] }, { "terrain": "bridge", "locations": [ "water" ], "basic_cost": 120 } ] }, diff --git a/src/mapgen_functions.cpp b/src/mapgen_functions.cpp index 15f40f5b5b68..d20e332fa073 100644 --- a/src/mapgen_functions.cpp +++ b/src/mapgen_functions.cpp @@ -124,17 +124,15 @@ building_gen_pointer get_mapgen_cfunction( const std::string &ident ) { "subway_straight", &mapgen_subway }, { "subway_curved", &mapgen_subway }, - // TODO: Add a dedicated dead-end function. For now it copies the straight section above. { "subway_end", &mapgen_subway }, { "subway_tee", &mapgen_subway }, { "subway_four_way", &mapgen_subway }, - { "sewer_straight", &mapgen_sewer_straight }, - { "sewer_curved", &mapgen_sewer_curved }, - // TODO: Add a dedicated dead-end function. For now it copies the straight section above. - { "sewer_end", &mapgen_sewer_straight }, - { "sewer_tee", &mapgen_sewer_tee }, - { "sewer_four_way", &mapgen_sewer_four_way }, + { "sewer_straight", &mapgen_sewer }, + { "sewer_curved", &mapgen_sewer }, + { "sewer_end", &mapgen_sewer }, + { "sewer_tee", &mapgen_sewer }, + { "sewer_four_way", &mapgen_sewer }, { "tutorial", &mapgen_tutorial }, { "lake_shore", &mapgen_lake_shore }, @@ -1188,99 +1186,46 @@ void mapgen_subway( mapgendata &dat ) m->rotate( rot ); } -void mapgen_sewer_straight( mapgendata &dat ) +void mapgen_sewer( mapgendata &dat ) { map *const m = &dat.m; - for( int i = 0; i < SEEX * 2; i++ ) { - for( int j = 0; j < SEEY * 2; j++ ) { - if( i < SEEX - 2 || i > SEEX + 1 ) { - m->ter_set( point( i, j ), t_rock ); - } else { - m->ter_set( point( i, j ), t_sewage ); - } - } - } - m->place_items( item_group_id( "sewer" ), 10, point_zero, point( SEEX * 2 - 1, SEEY * 2 - 1 ), true, - dat.when() ); - if( dat.terrain_type() == "sewer_ew" ) { - m->rotate( 1 ); - } -} -void mapgen_sewer_curved( mapgendata &dat ) -{ - map *const m = &dat.m; - for( int i = 0; i < SEEX * 2; i++ ) { - for( int j = 0; j < SEEY * 2; j++ ) { - if( ( i > SEEX + 1 && j < SEEY - 2 ) || i < SEEX - 2 || j > SEEY + 1 ) { - m->ter_set( point( i, j ), t_rock ); - } else { - m->ter_set( point( i, j ), t_sewage ); - } - } - } - m->place_items( item_group_id( "sewer" ), 18, point_zero, point( SEEX * 2 - 1, SEEY * 2 - 1 ), true, - dat.when() ); - if( dat.terrain_type() == "sewer_es" ) { - m->rotate( 1 ); - } - if( dat.terrain_type() == "sewer_sw" ) { - m->rotate( 2 ); - } - if( dat.terrain_type() == "sewer_wn" ) { - m->rotate( 3 ); - } -} + bool sewer_nesw[4] = {}; + int num_dirs = terrain_type_to_nesw_array( dat.terrain_type(), sewer_nesw ); -void mapgen_sewer_tee( mapgendata &dat ) -{ - map *const m = &dat.m; for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { - if( i < SEEX - 2 || ( i > SEEX + 1 && ( j < SEEY - 2 || j > SEEY + 1 ) ) ) { - m->ter_set( point( i, j ), t_rock ); - } else { - m->ter_set( point( i, j ), t_sewage ); + bool fill = true; + if( j >= SEEY - 2 && j <= SEEY + 1 ) { + if( i <= SEEX - 2 ) { + if( sewer_nesw[3] ) { + fill = false; + } + } else if( i >= SEEX + 1 ) { + if( sewer_nesw[1] ) { + fill = false; + } + } else { + // Central area, always empty + fill = false; + } + } else if( i >= SEEX - 2 && i <= SEEX + 1 ) { + if( j <= SEEY - 2 ) { + if( sewer_nesw[0] ) { + fill = false; + } + } else { + if( sewer_nesw[2] ) { + fill = false; + } + } } - } - } - m->place_items( item_group_id( "sewer" ), 23, point_zero, point( SEEX * 2 - 1, SEEY * 2 - 1 ), true, - dat.when() ); - if( dat.terrain_type() == "sewer_esw" ) { - m->rotate( 1 ); - } - if( dat.terrain_type() == "sewer_nsw" ) { - m->rotate( 2 ); - } - if( dat.terrain_type() == "sewer_new" ) { - m->rotate( 3 ); - } -} -void mapgen_sewer_four_way( mapgendata &dat ) -{ - map *const m = &dat.m; - int rn = rng( 0, 3 ); - for( int i = 0; i < SEEX * 2; i++ ) { - for( int j = 0; j < SEEY * 2; j++ ) { - if( ( i < SEEX - 2 || i > SEEX + 1 ) && ( j < SEEY - 2 || j > SEEY + 1 ) ) { - m->ter_set( point( i, j ), t_rock ); - } else { - m->ter_set( point( i, j ), t_sewage ); - } - if( rn == 0 && ( trig_dist( point( i, j ), point( SEEX - 1, SEEY - 1 ) ) <= 6 || - trig_dist( point( i, j ), point( SEEX - 1, SEEY ) ) <= 6 || - trig_dist( point( i, j ), point( SEEX, SEEY - 1 ) ) <= 6 || - trig_dist( point( i, j ), point( SEEX, SEEY ) ) <= 6 ) ) { - m->ter_set( point( i, j ), t_sewage ); - } - if( rn == 0 && ( i == SEEX - 1 || i == SEEX ) && ( j == SEEY - 1 || j == SEEY ) ) { - m->ter_set( point( i, j ), t_grate ); - } + m->ter_set( point( i, j ), fill ? t_rock : t_sewage ); } } - m->place_items( item_group_id( "sewer" ), 28, point_zero, point( SEEX * 2 - 1, SEEY * 2 - 1 ), true, - dat.when() ); + m->place_items( item_group_id( "sewer" ), 4 + ( num_dirs * 6 ), point_zero, + point( SEEX * 2 - 1, SEEY * 2 - 1 ), true, dat.when() ); } void mapgen_highway( mapgendata &dat ) diff --git a/src/mapgen_functions.h b/src/mapgen_functions.h index f1549ec0292f..496dffb5fae6 100644 --- a/src/mapgen_functions.h +++ b/src/mapgen_functions.h @@ -64,10 +64,7 @@ void mapgen_open_air( mapgendata &dat ); void mapgen_rift( mapgendata &dat ); void mapgen_hellmouth( mapgendata &dat ); void mapgen_subway( mapgendata &dat ); -void mapgen_sewer_curved( mapgendata &dat ); -void mapgen_sewer_four_way( mapgendata &dat ); -void mapgen_sewer_straight( mapgendata &dat ); -void mapgen_sewer_tee( mapgendata &dat ); +void mapgen_sewer( mapgendata &dat ); void mapgen_tutorial( mapgendata &dat ); void mapgen_lake_shore( mapgendata &dat ); diff --git a/src/overmap.cpp b/src/overmap.cpp index ce02e1750884..3ea17e2fd3ee 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -3205,7 +3205,6 @@ bool overmap::generate_sub( const int z ) { // We need to generate at least 3 z-levels for labs bool requires_sub = z > -4; - std::vector sewer_points; std::vector mine_points; @@ -3226,12 +3225,7 @@ bool overmap::generate_sub( const int z ) continue; } - if( oter_above == "road_nesw_manhole" ) { - ter_set( p, oter_id( "sewer_isolated" ) ); - sewer_points.emplace_back( i, j ); - } else if( oter_above == "sewage_treatment" ) { - sewer_points.emplace_back( i, j ); - } else if( is_ot_match( "mine_entrance", oter_ground, ot_match_type::prefix ) && z == -2 ) { + if( is_ot_match( "mine_entrance", oter_ground, ot_match_type::prefix ) && z == -2 ) { mine_points.emplace_back( ( p + tripoint_west ).xy(), rng( 6 + z, 10 + z ) ); requires_sub = true; } else if( oter_above == "mine_down" ) { @@ -3244,9 +3238,6 @@ bool overmap::generate_sub( const int z ) } } - const overmap_connection_id sewer_tunnel( "sewer_tunnel" ); - connect_closest_points( sewer_points, z, *sewer_tunnel ); - for( auto &i : cities ) { tripoint_om_omt omt_pos( i.pos, z ); tripoint_om_sm sm_pos = project_to( omt_pos ); @@ -4476,6 +4467,7 @@ void overmap::place_cities() const int NUM_CITIES = roll_remainder( omts_per_overmap * city_map_coverage_ratio / omts_per_city ); + const overmap_connection_id sewer_tunnel( "sewer_tunnel" ); const overmap_connection_id local_road_id( "local_road" ); const overmap_connection &local_road( *local_road_id ); @@ -4508,7 +4500,8 @@ void overmap::place_cities() if( ter( p ) == settings->default_oter ) { placement_attempts = 0; - ter_set( p, oter_id( "road_nesw" ) ); // every city starts with an intersection + ter_set( p, oter_id( "road_nesw_manhole" ) ); // every city starts with an intersection + ter_set( p + tripoint_below, oter_id( "sewer_isolated" ) ); city tmp; tmp.pos = p.xy(); tmp.size = size; @@ -4516,10 +4509,15 @@ void overmap::place_cities() const auto start_dir = om_direction::random(); auto cur_dir = start_dir; + std::vector sewers; do { - build_city_street( local_road, tmp.pos, size, cur_dir, tmp ); + build_city_street( local_road, tmp.pos, size, cur_dir, tmp, sewers ); } while( ( cur_dir = om_direction::turn_right( cur_dir ) ) != start_dir ); + + for( const tripoint_om_omt &p : sewers ) { + build_connection( tmp.pos, p.xy(), p.z(), *sewer_tunnel, false ); + } } } } @@ -4569,7 +4567,8 @@ void overmap::place_building( const tripoint_om_omt &p, om_direction::type dir, void overmap::build_city_street( const overmap_connection &connection, const point_om_omt &p, int cs, - om_direction::type dir, const city &town, int block_width ) + om_direction::type dir, const city &town, std::vector &sewers, + int block_width ) { int c = cs; int croad = cs; @@ -4611,15 +4610,17 @@ void overmap::build_city_street( } build_city_street( connection, iter->pos, left, om_direction::turn_left( dir ), - town, new_width ); + town, sewers, new_width ); build_city_street( connection, iter->pos, right, om_direction::turn_right( dir ), - town, new_width ); + town, sewers, new_width ); const oter_id &oter = ter( rp ); // TODO: Get rid of the hardcoded terrain ids. - if( one_in( 2 ) && oter->get_line() == 15 && oter->type_is( oter_type_id( "road" ) ) ) { + if( one_in( 8 ) && oter->get_line() == 15 && oter->type_is( oter_type_id( "road" ) ) ) { ter_set( rp, oter_id( "road_nesw_manhole" ) ); + ter_set( rp + tripoint_below, oter_id( "sewer_isolated" ) ); + sewers.push_back( rp + tripoint_below ); } } @@ -4638,10 +4639,10 @@ void overmap::build_city_street( if( cs >= 2 && c == 0 ) { const auto &last_node = street_path.nodes.back(); const auto rnd_dir = om_direction::turn_random( dir ); - build_city_street( connection, last_node.pos, cs, rnd_dir, town ); + build_city_street( connection, last_node.pos, cs, rnd_dir, town, sewers ); if( one_in( 5 ) ) { build_city_street( connection, last_node.pos, cs, om_direction::opposite( rnd_dir ), - town, new_width ); + town, sewers, new_width ); } } } diff --git a/src/overmap.h b/src/overmap.h index 1713f40dbf1a..cefe5d599cc7 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -434,7 +434,8 @@ class overmap void place_building( const tripoint_om_omt &p, om_direction::type dir, const city &town ); void build_city_street( const overmap_connection &connection, const point_om_omt &p, int cs, - om_direction::type dir, const city &town, int block_width = 2 ); + om_direction::type dir, const city &town, std::vector &sewers, + int block_width = 2 ); void build_mine( const tripoint_om_omt &origin, int s ); // Connection laying