Skip to content

Commit

Permalink
feat: mainlined elevated bridges (#3913)
Browse files Browse the repository at this point in the history
* Fix underbridge shore rotation

* Mainlined elevated bridges

* Elevate post-mapgen bridges

* Fix minefield test
  • Loading branch information
Vollch authored Dec 16, 2023
1 parent 240d6c9 commit d9aef17
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 134 deletions.
34 changes: 34 additions & 0 deletions data/json/construction.json
Original file line number Diff line number Diff line change
Expand Up @@ -2702,6 +2702,40 @@
"pre_terrain": "t_rock",
"post_special": "done_mine_upstair"
},
{
"type": "construction",
"id": "constr_concrete_ramp_low",
"group": "build_low_end_of_a_concrete_ramp",
"//": "Builds a low end of a concrete ramp going up on this level and down on the level above.",
"pre_note": "Build a concrete ramp leading to the next z-level above, and the corresponding ramp down leading from the z-level above to this level. The high end of a ramp must be built adjacent to allow moving between z-levels in both directions.",
"category": "DIG",
"required_skills": [ [ "fabrication", 3 ] ],
"time": "150 m",
"tools": [ [ [ "con_mix", 125 ] ] ],
"qualities": [ [ { "id": "SMOOTH", "level": 1 } ] ],
"components": [ [ [ "concrete", 5 ] ], [ [ "water", 5 ] ] ],
"pre_terrain": "t_pit_shallow",
"pre_special": "check_ramp_low",
"post_terrain": "t_ramp_up_low",
"post_special": "done_ramp_low"
},
{
"type": "construction",
"id": "constr_concrete_ramp_high",
"group": "build_high_end_of_a_concrete_ramp",
"//": "Builds a high end of a concrete ramp going up on this level and down on the level above.",
"pre_note": "Build a concrete ramp leading to the next z-level above, and the corresponding ramp down leading from the z-level above to this level. It must be built next to a low end of a ramp to allow moving between z-levels in both directions.",
"category": "DIG",
"required_skills": [ [ "fabrication", 3 ] ],
"time": "150 m",
"tools": [ [ [ "con_mix", 125 ] ] ],
"qualities": [ [ { "id": "SMOOTH", "level": 1 } ] ],
"components": [ [ [ "concrete", 5 ] ], [ [ "water", 5 ] ] ],
"pre_terrain": "t_pit_shallow",
"pre_special": "check_ramp_high",
"post_terrain": "t_ramp_up_high",
"post_special": "done_ramp_high"
},
{
"type": "construction",
"id": "constr_veh",
Expand Down
10 changes: 10 additions & 0 deletions data/json/construction_group.json
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@
"id": "rewire_street_light",
"name": "Rewire Street Light"
},
{
"type": "construction_group",
"id": "build_high_end_of_a_concrete_ramp",
"name": "Build High End of a Concrete Ramp"
},
{
"type": "construction_group",
"id": "build_improvised_shelter",
Expand Down Expand Up @@ -349,6 +354,11 @@
"id": "build_log_wall",
"name": "Build Log Wall"
},
{
"type": "construction_group",
"id": "build_low_end_of_a_concrete_ramp",
"name": "Build Low End of a Concrete Ramp"
},
{
"type": "construction_group",
"id": "build_mailbox",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@
"id": "bridge",
"copy-from": "generic_bridge",
"extras": "bridgehead_ground",
"flags": [ "RIVER" ]
"flags": [ "RIVER", "IGNORE_ROTATION_FOR_ADJACENCY" ]
},
{
"type": "overmap_terrain",
"id": "bridge_under",
"copy-from": "generic_bridge",
"color": "blue",
"flags": [ "RIVER" ]
"flags": [ "RIVER", "IGNORE_ROTATION_FOR_ADJACENCY" ]
},
{
"type": "overmap_terrain",
Expand All @@ -97,7 +97,7 @@
"name": "bridgehead (ground)",
"sym": "v",
"extras": "bridgehead_ground",
"flags": [ "RIVER" ]
"flags": [ "RIVER", "IGNORE_ROTATION_FOR_ADJACENCY" ]
},
{
"type": "overmap_terrain",
Expand Down
1 change: 0 additions & 1 deletion data/mods/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"no_npc_food",
"novitamins",
"No_Rail_Stations",
"elevated_bridges",
"no_reviving_zombies",
"limit_fungal_growth"
]
12 changes: 0 additions & 12 deletions data/mods/elevated_bridges/construction_group.json

This file was deleted.

43 changes: 0 additions & 43 deletions data/mods/elevated_bridges/content.json

This file was deleted.

2 changes: 2 additions & 0 deletions data/mods/elevated_bridges/modinfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"authors": [ "olanti-p" ],
"description": "Enables generation of elevated bridges and construction of ramps. Requires z-levels to be ON to properly work. Elevated bridges do not block river tiles and allow boats to pass underneath.",
"category": "content",
"//": "Mainlined in 0.4, mod preserved to prevent loading errors",
"obsolete": true,
"dependencies": [ "bn" ],
"path": ""
}
Expand Down
88 changes: 36 additions & 52 deletions src/map_extras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ static const mtype_id mon_zombie_soldier( "mon_zombie_soldier" );
static const mtype_id mon_zombie_spitter( "mon_zombie_spitter" );
static const mtype_id mon_zombie_tough( "mon_zombie_tough" );

static const oter_type_str_id oter_type_bridgehead_ground( "bridgehead_ground" );
static const oter_type_str_id oter_type_bridge_under( "bridge_under" );
static const oter_type_str_id oter_type_road( "road" );

class npc_template;

namespace io
Expand Down Expand Up @@ -1058,55 +1062,38 @@ static bool mx_portal( map &m, const tripoint &abs_sub )
return true;
}

static bool mx_minefield( map &m_orig, const tripoint &abs_sub )
static bool mx_minefield( map &/*m_orig*/, const tripoint &abs_sub )
{
const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sub ) );

const oter_id &center = overmap_buffer.ter( abs_omt );
const bool bridgehead_at_center = center->get_type_id() == oter_type_bridgehead_ground;
if( !bridgehead_at_center ) {
return false;
}

const oter_id &north = overmap_buffer.ter( abs_omt + point_north );
const oter_id &south = overmap_buffer.ter( abs_omt + point_south );
const oter_id &west = overmap_buffer.ter( abs_omt + point_west );
const oter_id &east = overmap_buffer.ter( abs_omt + point_east );

std::string oter_name_base;
std::string oter_name_bridge;
bool use_tinymap;
if( get_option<bool>( "ELEVATED_BRIDGES" ) ) {
oter_name_base = "bridgehead_ground";
oter_name_bridge = "bridge_under";
use_tinymap = true;
} else {
oter_name_base = "bridge";
oter_name_bridge = "bridge";
use_tinymap = false;
}
tinymap m_tiny;
map &m = use_tinymap ? m_tiny : m_orig;

const bool bridgehead_at_center = is_ot_match( oter_name_base, center, ot_match_type::type );
const bool bridge_at_north = is_ot_match( oter_name_bridge, north, ot_match_type::type );
const bool bridge_at_south = is_ot_match( oter_name_bridge, south, ot_match_type::type );
const bool bridge_at_west = is_ot_match( oter_name_bridge, west, ot_match_type::type );
const bool bridge_at_east = is_ot_match( oter_name_bridge, east, ot_match_type::type );
const bool bridge_at_north = north->get_type_id() == oter_type_bridge_under;
const bool bridge_at_south = south->get_type_id() == oter_type_bridge_under;
const bool bridge_at_west = west->get_type_id() == oter_type_bridge_under;
const bool bridge_at_east = east->get_type_id() == oter_type_bridge_under;

const bool road_at_north = is_ot_match( "road", north, ot_match_type::type );
const bool road_at_south = is_ot_match( "road", south, ot_match_type::type );
const bool road_at_west = is_ot_match( "road", west, ot_match_type::type );
const bool road_at_east = is_ot_match( "road", east, ot_match_type::type );
const bool road_at_north = north->get_type_id() == oter_type_road;
const bool road_at_south = south->get_type_id() == oter_type_road;
const bool road_at_west = west->get_type_id() == oter_type_road;
const bool road_at_east = east->get_type_id() == oter_type_road;

const int num_mines = rng( 6, 20 );
const std::string text = _( "DANGER! MINEFIELD!" );
int x, y, x1, y1 = 0;
tinymap m;

bool did_something = false;

if( !bridgehead_at_center ) {
return false;
}

if( bridge_at_north && bridgehead_at_center && road_at_south ) {
if( use_tinymap ) {
m.load( project_to<coords::sm>( abs_omt + point_south ), false );
}
if( bridge_at_north && road_at_south ) {
m.load( project_to<coords::sm>( abs_omt + point_south ), false );

//Sandbag block at the left edge
line_furn( &m, f_sandbag_half, point( 3, 4 ), point( 3, 7 ) );
Expand Down Expand Up @@ -1202,13 +1189,12 @@ static bool mx_minefield( map &m_orig, const tripoint &abs_sub )
m.furn_set( point( x1, SEEY * 2 - 1 ), furn_str_id( "f_sign_warning" ) );
m.set_signage( tripoint( x1, SEEY * 2 - 1, abs_sub.z ), text );

did_something = true;
return true;
}

if( bridge_at_south && bridgehead_at_center && road_at_north ) {
if( use_tinymap ) {
m.load( project_to<coords::sm>( abs_omt + point_north ), false );
}
if( bridge_at_south && road_at_north ) {
m.load( project_to<coords::sm>( abs_omt + point_north ), false );

//Two horizontal lines of sandbags
line_furn( &m, f_sandbag_half, point( 5, 15 ), point( 10, 15 ) );
line_furn( &m, f_sandbag_half, point( 13, 15 ), point( 18, 15 ) );
Expand Down Expand Up @@ -1305,13 +1291,12 @@ static bool mx_minefield( map &m_orig, const tripoint &abs_sub )
m.furn_set( point( x1, 0 ), furn_str_id( "f_sign_warning" ) );
m.set_signage( tripoint( x1, 0, abs_sub.z ), text );

did_something = true;
return true;
}

if( bridge_at_west && bridgehead_at_center && road_at_east ) {
if( use_tinymap ) {
m.load( project_to<coords::sm>( abs_omt + point_east ), false );
}
if( bridge_at_west && road_at_east ) {
m.load( project_to<coords::sm>( abs_omt + point_east ), false );

//Draw walls of first tent
square_furn( &m, f_canvas_wall, point( 0, 3 ), point( 4, 13 ) );

Expand Down Expand Up @@ -1454,13 +1439,12 @@ static bool mx_minefield( map &m_orig, const tripoint &abs_sub )
m.furn_set( point( SEEX * 2 - 1, y1 ), furn_str_id( "f_sign_warning" ) );
m.set_signage( tripoint( SEEX * 2 - 1, y1, abs_sub.z ), text );

did_something = true;
return true;
}

if( bridge_at_east && bridgehead_at_center && road_at_west ) {
if( use_tinymap ) {
m.load( project_to<coords::sm>( abs_omt + point_west ), false );
}
if( bridge_at_east && road_at_west ) {
m.load( project_to<coords::sm>( abs_omt + point_west ), false );

//Spawn military cargo truck blocking the entry
m.add_vehicle( vproto_id( "military_cargo_truck" ), point( 15, 11 ), 270_degrees, 70, 1 );

Expand Down Expand Up @@ -1591,10 +1575,10 @@ static bool mx_minefield( map &m_orig, const tripoint &abs_sub )
m.furn_set( point( 0, y1 ), furn_str_id( "f_sign_warning" ) );
m.set_signage( tripoint( 0, y1, abs_sub.z ), text );

did_something = true;
return true;
}

return did_something;
return false;
}

static bool mx_crater( map &m, const tripoint &abs_sub )
Expand Down
6 changes: 0 additions & 6 deletions src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2391,12 +2391,6 @@ void options_manager::add_options_world_default()
translate_marker( "If true, strength checks and/or lifting qualities no longer need to be met in order to change parts." ),
false, COPT_ALWAYS_HIDE
);

add( "ELEVATED_BRIDGES", world_default,
translate_marker( "Generate elevated bridges." ),
translate_marker( "If true, bridges are generated at z+1 level, allowing boats to pass underneath." ),
false, COPT_ALWAYS_HIDE
);
}

void options_manager::add_options_android()
Expand Down
32 changes: 21 additions & 11 deletions src/overmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ static const mongroup_id GROUP_SWAMP( "GROUP_SWAMP" );
static const mongroup_id GROUP_WORM( "GROUP_WORM" );
static const mongroup_id GROUP_ZOMBIE( "GROUP_ZOMBIE" );

static const oter_type_str_id oter_type_bridge( "bridge" );

class map_extra;

#define dbg(x) DebugLogFL((x),DC::MapGen)
Expand Down Expand Up @@ -3453,10 +3455,6 @@ bool overmap::generate_over( const int z )
bool requires_over = false;
std::vector<point_om_omt> bridge_points;

if( !get_option<bool>( "ELEVATED_BRIDGES" ) ) {
return requires_over;
}

// These are so common that it's worth checking first as int.
const std::set<oter_id> skip_below = {
oter_id( "empty_rock" ), oter_id( "forest" ), oter_id( "field" ),
Expand All @@ -3476,7 +3474,7 @@ bool overmap::generate_over( const int z )
continue;
}

if( is_ot_match( "bridge", oter_ground, ot_match_type::type ) ) {
if( oter_ground->get_type_id() == oter_type_bridge ) {
bridge_points.emplace_back( i, j );
}
}
Expand All @@ -3485,12 +3483,8 @@ bool overmap::generate_over( const int z )

elevate_bridges(
*this, bridge_points,
"bridge_road",
"bridge_under",
"bridgehead_ground",
"bridgehead_ramp",
"road_ew",
"road_ns"
"bridge_road", "bridge_under", "bridgehead_ground",
"bridgehead_ramp", "road_ew", "road_ns"
);

return requires_over;
Expand Down Expand Up @@ -5097,6 +5091,22 @@ bool overmap::build_connection(

if( connection_cache ) {
connection_cache->add( connection.id, z, start.pos );
} else if( z == 0 && connection.id.str() == "local_road" ) {
// If there's no cache, it means we're placing road after
// normal mapgen, and need to elevate bridges manually
std::vector<point_om_omt> bridge_points;
for( const auto &node : path.nodes ) {
const tripoint_om_omt pos( node.pos, z );
if( ter( pos )->get_type_id() == oter_type_bridge ) {
bridge_points.emplace_back( pos.xy() );
}
}

elevate_bridges(
*this, bridge_points,
"bridge_road", "bridge_under", "bridgehead_ground",
"bridgehead_ramp", "road_ew", "road_ns"
);
}
return true;
}
Expand Down
Loading

0 comments on commit d9aef17

Please sign in to comment.