diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index 47f5577928f83..84b9f6d539212 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -1330,7 +1330,7 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da if( data.select != tripoint( -1, -1, -1 ) ) { curs = tripoint( data.select ); } - + bool chosen_water_option = false; // Configure input context for navigating the map. input_context ictxt( "OVERMAP" ); ictxt.register_action( "ANY_INPUT" ); @@ -1429,21 +1429,30 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da curs.y = p.y; } } else if( action == "CHOOSE_DESTINATION" ) { - bool in_road_vehicle = g->u.in_vehicle && g->u.controlling_vehicle; + path_type ptype; + bool in_vehicle = g->u.in_vehicle && g->u.controlling_vehicle; const optional_vpart_position vp = g->m.veh_at( g->u.pos() ); - bool in_boat = false; - if( vp && in_road_vehicle ) { + if( vp && in_vehicle ) { vehicle &veh = vp->vehicle(); - in_boat = veh.can_float() && veh.is_watercraft() && veh.is_in_water(); - if( in_boat ) { - in_road_vehicle = false; + ptype.only_water = veh.can_float() && veh.is_watercraft() && veh.is_in_water(); + ptype.only_road = !ptype.only_water; + } else { + const oter_id oter = overmap_buffer.ter( curs ); + // if we choose a water tile, then we dont need to be prompted if we want to swim + if( is_river_or_lake( oter ) ) { + ptype.amphibious = true; + } else if( !chosen_water_option ) { + if( query_yn( _( "Allow swimming to get to destination?" ) ) ) { + ptype.amphibious = true; + } + chosen_water_option = true; } } const tripoint player_omt_pos = g->u.global_omt_location(); if( !g->u.omt_path.empty() && g->u.omt_path.front() == curs ) { if( query_yn( _( "Travel to this point?" ) ) ) { // renew the path incase of a leftover dangling path point - g->u.omt_path = overmap_buffer.get_npc_path( player_omt_pos, curs, in_road_vehicle, in_boat ); + g->u.omt_path = overmap_buffer.get_npc_path( player_omt_pos, curs, ptype ); if( g->u.in_vehicle && g->u.controlling_vehicle ) { vehicle *player_veh = veh_pointer_or_null( g->m.veh_at( g->u.pos() ) ); player_veh->omt_path = g->u.omt_path; @@ -1459,7 +1468,7 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da if( curs == player_omt_pos ) { g->u.omt_path.clear(); } else { - g->u.omt_path = overmap_buffer.get_npc_path( player_omt_pos, curs, in_road_vehicle, in_boat ); + g->u.omt_path = overmap_buffer.get_npc_path( player_omt_pos, curs, ptype ); } } else if( action == "TOGGLE_BLINKING" ) { uistate.overmap_blinking = !uistate.overmap_blinking; diff --git a/src/overmap_ui.h b/src/overmap_ui.h index da2a9d4042a83..2edd29ffc02bc 100644 --- a/src/overmap_ui.h +++ b/src/overmap_ui.h @@ -17,6 +17,8 @@ namespace ui namespace omap { +struct path_type; + /** * Display overmap centered at the player's position. */ diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index ec2bc9d205830..bccaff5c8395b 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -666,8 +666,14 @@ bool overmapbuffer::reveal( const tripoint ¢er, int radius, return result; } +std::vector overmapbuffer::get_npc_path( const tripoint &src, const tripoint &dest ) +{ + path_type ptype; + return get_npc_path( src, dest, ptype ); +} + std::vector overmapbuffer::get_npc_path( const tripoint &src, const tripoint &dest, - bool road_only, bool do_boat ) + path_type &ptype ) { std::vector path; static const int RADIUS = 4; // Maximal radius of search (in overmaps) @@ -692,17 +698,17 @@ std::vector overmapbuffer::get_npc_path( const tripoint &src, const tr int res = 0; const oter_id oter = get_ter_at( cur.pos ); int travel_cost = static_cast( oter->get_travel_cost() ); - if( road_only && ( !is_ot_match( "road", oter, ot_match_type::type ) && - !is_ot_match( "bridge", oter, ot_match_type::type ) && - !is_ot_match( "road_nesw_manhole", oter, ot_match_type::type ) ) ) { + if( ptype.only_road && ( !is_ot_match( "road", oter, ot_match_type::type ) && + !is_ot_match( "bridge", oter, ot_match_type::type ) && + !is_ot_match( "road_nesw_manhole", oter, ot_match_type::type ) ) ) { return pf::rejected; } - if( do_boat && ( !is_river_or_lake( oter ) || - is_ot_match( "bridge", oter, ot_match_type::type ) ) ) { + if( ptype.only_water && ( !is_river_or_lake( oter ) || + is_ot_match( "bridge", oter, ot_match_type::type ) ) ) { return pf::rejected; } if( is_ot_match( "empty_rock", oter, ot_match_type::type ) || - is_ot_match( "open_air", oter, ot_match_type::type ) || ( !do_boat && oter->is_lake() ) ) { + is_ot_match( "open_air", oter, ot_match_type::type ) ) { return pf::rejected; } else if( is_ot_match( "forest", oter, ot_match_type::type ) ) { travel_cost = 10; @@ -713,7 +719,7 @@ std::vector overmapbuffer::get_npc_path( const tripoint &src, const tr is_ot_match( "road_nesw_manhole", oter, ot_match_type::type ) ) { travel_cost = 1; } else if( is_river_or_lake( oter ) ) { - travel_cost = do_boat ? 1 : 20; + travel_cost = ptype.only_water || ptype.amphibious ? 1 : 20; } res += travel_cost; res += manhattan_dist( finish, cur.pos ); diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index 07fc3482ab88e..7f8a84d07b84a 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -33,6 +33,12 @@ class vehicle; class basecamp; class map_extra; +struct path_type { + bool only_road = false; + bool only_water = false; + bool amphibious = false; +}; + struct radio_tower_reference { /** The radio tower itself, points into @ref overmap::radios */ radio_tower *tower; @@ -301,8 +307,8 @@ class overmapbuffer bool reveal( const tripoint ¢er, int radius ); bool reveal( const tripoint ¢er, int radius, const std::function &filter ); - std::vector get_npc_path( const tripoint &src, const tripoint &dest, - bool road_only = false, bool do_boat = false ); + std::vector get_npc_path( const tripoint &src, const tripoint &dest ); + std::vector get_npc_path( const tripoint &src, const tripoint &dest, path_type &ptype ); bool reveal_route( const tripoint &source, const tripoint &dest, int radius = 0, bool road_only = false ); /**