diff --git a/data/json/npcs/TALK_FACTION_CAMP.json b/data/json/npcs/TALK_FACTION_CAMP.json index ca3fca864c806..9513984d1bc5c 100644 --- a/data/json/npcs/TALK_FACTION_CAMP.json +++ b/data/json/npcs/TALK_FACTION_CAMP.json @@ -20,6 +20,12 @@ "switch": true, "default": true }, + { + "text": "We need to abandon this camp.", + "condition": { "npc_at_om_location": "FACTION_CAMP_ANY" }, + "topic": "TALK_DONE", + "effect": "abandon_camp" + }, { "text": "Show me what needs to be done at the camp.", "topic": "TALK_DONE", diff --git a/src/basecamp.h b/src/basecamp.h index d8dd4aefbc431..0c38603c3d591 100644 --- a/src/basecamp.h +++ b/src/basecamp.h @@ -144,6 +144,7 @@ class basecamp //change name of camp void set_name( const std::string &new_name ); void query_new_name(); + void abandon_camp(); void add_expansion( const std::string &terrain, const tripoint &new_pos ); void add_expansion( const std::string &bldg, const tripoint &new_pos, const point &dir ); diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index f991eb5a8de6b..2cd084290b263 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -1266,6 +1266,8 @@ void basecamp::get_available_missions( mission_data &mission_key ) "\n\nRisk: None\n" "Time: Ongoing" ) ); mission_key.add( "Assign Jobs", _( "Assign Jobs" ), entry ); + entry = _( "Notes:\nAbandon this camp" ); + mission_key.add( "Abandon Camp", _( "Abandon Camp" ), entry ); } // Missions assigned to the central tile that could be done by an expansion get_available_missions_by_dir( mission_key, base_camps::base_dir ); @@ -1319,6 +1321,9 @@ bool basecamp::handle_mission( const std::string &miss_id, cata::optional if( miss_id == "Assign Jobs" ) { job_assignment_ui(); } + if( miss_id == "Abandon Camp" ) { + abandon_camp(); + } if( miss_id == "Expand Base" ) { start_mission( "_faction_camp_expansion", 3_hours, true, @@ -1561,6 +1566,27 @@ void basecamp::start_upgrade( const std::string &bldg, const point &dir, } } +void basecamp::abandon_camp() +{ + validate_assignees(); + npc_ptr random_guy; + for( npc_ptr &guy : overmap_buffer.get_companion_mission_npcs( 10 ) ) { + npc_companion_mission c_mission = guy->get_companion_mission(); + if( c_mission.role_id != base_camps::id ) { + continue; + } + random_guy = guy; + const std::string return_msg = _( "responds to the emergency recall…" ); + finish_return( *guy, false, return_msg, "menial", 0, true ); + } + for( npc_ptr &guy : get_npcs_assigned() ) { + talk_function::stop_guard( *guy ); + } + overmap_buffer.remove_camp( *this ); + g->m.remove_submap_camp( random_guy->pos() ); + add_msg( m_info, _( "You abandon %s." ), name ); +} + void basecamp::job_assignment_ui() { int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; diff --git a/src/npctalk.cpp b/src/npctalk.cpp index b0fa2e0c49064..ac411410b7521 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -2571,6 +2571,7 @@ void talk_effect_t::parse_string_effect( const std::string &effect_id, const Jso WRAP( do_farming ), WRAP( assign_guard ), WRAP( assign_camp ), + WRAP( abandon_camp ), WRAP( stop_guard ), WRAP( start_camp ), WRAP( buy_cow ), diff --git a/src/npctalk.h b/src/npctalk.h index 0debe5e30486d..79da5d35ac5e0 100644 --- a/src/npctalk.h +++ b/src/npctalk.h @@ -51,6 +51,7 @@ void goto_location( npc & ); void assign_base( npc & ); void assign_guard( npc & ); void assign_camp( npc & ); +void abandon_camp( npc & ); void stop_guard( npc & ); void end_conversation( npc & ); void insult_combat( npc & ); diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index a4a48b01995d6..be51a6f433477 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -346,6 +346,15 @@ void talk_function::assign_guard( npc &p ) p.set_omt_destination(); } +void talk_function::abandon_camp( npc &p ) +{ + cata::optional bcp = overmap_buffer.find_camp( p.global_omt_location().xy() ); + if( bcp ) { + basecamp *temp_camp = *bcp; + temp_camp->abandon_camp(); + } +} + void talk_function::assign_camp( npc &p ) { cata::optional bcp = overmap_buffer.find_camp( p.global_omt_location().xy() ); diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index bccaff5c8395b..8200154ca4e6c 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -1089,11 +1089,11 @@ std::vector overmapbuffer::get_overmaps_near( const point &p, const i return get_overmaps_near( tripoint( p, 0 ), radius ); } -std::vector> overmapbuffer::get_companion_mission_npcs() +std::vector> overmapbuffer::get_companion_mission_npcs( int range ) { std::vector> available; // TODO: this is an arbitrary radius, replace with something sane. - for( const auto &guy : get_npcs_near_player( 100 ) ) { + for( const auto &guy : get_npcs_near_player( range ) ) { if( guy->has_companion_mission() ) { available.push_back( guy ); } diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index 7f8a84d07b84a..274796fe0b57f 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -233,7 +233,7 @@ class overmapbuffer * Get all (currently loaded!) npcs that have a companion * mission set. */ - std::vector> get_companion_mission_npcs(); + std::vector> get_companion_mission_npcs( int range = 100 ); /** * Uses overmap terrain coordinates, this also means radius is * in overmap terrain.