From 33c83115d6d834e12a8cd5548e49112161130c12 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sat, 25 May 2024 14:16:20 -0400 Subject: [PATCH] Display ordered NPC path on map (WIP implementation) --- src/npctalk_funcs.cpp | 7 +++++++ src/overmap_ui.cpp | 39 ++++++++++++++++++++++++++++++++++----- src/overmap_ui.h | 4 ++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index 020e6c63747af..7ceb84aab98c6 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -50,6 +50,7 @@ #include "npctrade.h" #include "output.h" #include "overmap.h" +#include "overmap_ui.h" #include "overmapbuffer.h" #include "pimpl.h" #include "player_activity.h" @@ -400,6 +401,12 @@ void talk_function::goto_location( npc &p ) add_msg( m_info, _( "That is not a valid destination for %s." ), p.disp_name() ); return; } + ui::omap::display_npc_path( p.global_omt_location(), p.omt_path ); + if( !query_yn( _( "Is this path and destination acceptable?" ) ) ) { + p.goal = npc::no_goal_point; + p.omt_path.clear(); + return; + } p.set_mission( NPC_MISSION_TRAVELLING ); p.chatbin.first_topic = p.chatbin.talk_friend_guard; p.guard_pos = std::nullopt; diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index 712647533ec44..4859fb6f1973f 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -537,7 +537,8 @@ static bool get_and_assign_los( int &los, avatar &player_character, const tripoi static void draw_ascii( const catacurses::window &w, const tripoint_abs_omt ¢er, const tripoint_abs_omt &orig, bool blink, bool show_explored, bool /* fast_scroll */, - input_context * /* inp_ctxt */, const draw_data_t &data ) + input_context * /* inp_ctxt */, const draw_data_t &data, + std::vector display_path ) { const int om_map_width = OVERMAP_WINDOW_WIDTH; @@ -688,6 +689,11 @@ static void draw_ascii( npc *npc_to_add = npc_to_get.get(); followers.push_back( npc_to_add ); } + if( !display_path.empty() ) { + for( auto &elem : display_path ) { + npc_path_route.insert( elem ); + } + } // get all traveling NPCs for the debug menu to show pathfinding routes. if( g->debug_pathfinding ) { for( auto &elem : overmap_buffer.get_npcs_near_player( 200 ) ) { @@ -1253,7 +1259,7 @@ tiles_redraw_info redraw_info; static void draw( ui_adaptor &ui, const tripoint_abs_omt ¢er, const tripoint_abs_omt &orig, bool blink, bool show_explored, bool fast_scroll, - input_context *inp_ctxt, const draw_data_t &data ) + input_context *inp_ctxt, const draw_data_t &data, std::vector display_path ) { draw_om_sidebar( ui, g->w_omlegend, center, orig, blink, fast_scroll, inp_ctxt, data ); #if defined( TILES ) @@ -1265,7 +1271,8 @@ static void draw( return; } #endif // TILES - draw_ascii( g->w_overmap, center, orig, blink, show_explored, fast_scroll, inp_ctxt, data ); + draw_ascii( g->w_overmap, center, orig, blink, show_explored, fast_scroll, inp_ctxt, data, + display_path ); } static void create_note( const tripoint_abs_omt &curs ) @@ -1769,7 +1776,7 @@ static bool try_travel_to_destination( avatar &player_character, const tripoint_ } static tripoint_abs_omt display( const tripoint_abs_omt &orig, - const draw_data_t &data = draw_data_t() ) + const draw_data_t &data = draw_data_t(), std::vector display_path = {} ) { const int previous_zoom = g->get_zoom(); g->set_zoom( overmap_zoom_level ); @@ -1857,10 +1864,11 @@ static tripoint_abs_omt display( const tripoint_abs_omt &orig, int fast_scroll_offset = get_option( "FAST_SCROLL_OFFSET" ); std::optional mouse_pos; std::chrono::time_point last_blink = std::chrono::steady_clock::now(); + int i = display_path.size() - 1; ui.on_redraw( [&]( ui_adaptor & ui ) { draw( ui, curs, orig, uistate.overmap_show_overlays, - show_explored, fast_scroll, &ictxt, data ); + show_explored, fast_scroll, &ictxt, data, display_path ); } ); do { @@ -1876,6 +1884,21 @@ static tripoint_abs_omt display( const tripoint_abs_omt &orig, #else action = ictxt.handle_input( get_option( "BLINK_SPEED" ) ); #endif + if( !display_path.empty() ) { + std::chrono::time_point now = std::chrono::steady_clock::now(); + // This is probably awful? Should use a reverse iterator instead, or something? + curs = display_path.at( i ); + if( now > last_blink + std::chrono::milliseconds( 250 ) ) { + if( i > 0 ) { + last_blink = now; + i--; + continue; + } else if( now > last_blink + std::chrono::milliseconds( 2500 ) ) { + action = "QUIT"; + break; + } + } + } if( const std::optional vec = ictxt.get_direction( action ) ) { int scroll_d = fast_scroll ? fast_scroll_offset : 1; curs += vec->xy() * scroll_d; @@ -2049,6 +2072,12 @@ void ui::omap::display() overmap_ui::display( get_player_character().global_omt_location(), overmap_ui::draw_data_t() ); } +void ui::omap::display_npc_path( tripoint_abs_omt starting_pos, + std::vector display_path ) +{ + overmap_ui::display( starting_pos, overmap_ui::draw_data_t(), display_path ); +} + void ui::omap::display_hordes() { overmap_ui::draw_data_t data; diff --git a/src/overmap_ui.h b/src/overmap_ui.h index 84ae82fc61159..bc34aa2a408b5 100644 --- a/src/overmap_ui.h +++ b/src/overmap_ui.h @@ -31,6 +31,10 @@ namespace omap * Display overmap centered at the player's position. */ void display(); +/** + * Display overmap centered at the given NPC's position and visually move across their intended OMT path. + */ +void display_npc_path( tripoint_abs_omt starting_pos, std::vector display_path ); /** * Display overmap like with @ref display() and display hordes. */