Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basecamps: add an emergency recall option #34560

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/basecamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,14 @@ class basecamp
/// called with a companion @ref comp who is not the camp manager, finishes updating their
/// skills, consuming food, and returning them to the base.
void finish_return( npc &comp, bool fixed_time, const std::string &return_msg,
const std::string &skill, int difficulty );
const std::string &skill, int difficulty, bool cancel = false );
/// a wrapper function for @ref companion_choose_return and @ref finish_return
npc_ptr mission_return( const std::string &miss_id, time_duration min_duration,
bool fixed_time, const std::string &return_msg,
const std::string &skill, int difficulty );
/// select a companion for any mission to return to base
npc_ptr emergency_recall();

/// Called to close upgrade missions, @ref miss is the name of the mission id
/// and @ref dir is the direction of the location to be upgraded
bool upgrade_return( const point &dir, const std::string &miss );
Expand Down
57 changes: 50 additions & 7 deletions src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ std::map<std::string, miss_data> miss_info = {{
"Recover Ally from Upgrading", to_translation( "Recover Ally from Upgrading" )
}
},
{
"_faction_camp_recall", {
"Emergency Recall", to_translation( "Emergency Recall" ),
to_translation( "Lost in the ether!\n" ),
"Emergency Recall", to_translation( "Emergency Recall" )
}
},
{
"_faction_camp_crafting_", {
"Craft Item", to_translation( "Craft Item" ),
Expand Down Expand Up @@ -1265,6 +1272,22 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio
}
}
}

if( !camp_workers.empty() ) {
const base_camps::miss_data &miss_info = base_camps::miss_info[ "_faction_camp_recall" ];
entry = string_format( _( "Notes:\n"
"Cancel a current mission and force the immediate return of a "
"companion. No work will be done on the mission and all "
"resources used on the mission will be lost.\n\n"
"WARNING: All resources used on the mission will be lost and "
"no work will be done. Only use this mission to recover a "
"companion who cannot otherwise be recovered.\n\n"
"Companions must be on missions for at least 24 hours before "
"emergency recall becomes available." ) );
bool avail = update_time_fixed( entry, camp_workers, 24_hours );
mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(),
cata::nullopt, entry, avail );
}
}

bool basecamp::handle_mission( const std::string &miss_id, const cata::optional<point> miss_dir,
Expand Down Expand Up @@ -1480,6 +1503,10 @@ bool basecamp::handle_mission( const std::string &miss_id, const cata::optional<
}
}

if( miss_id == "Emergency Recall" ) {
emergency_recall();
}

g->draw_ter();
wrefresh( g->w_terrain );
g->draw_panels( true );
Expand Down Expand Up @@ -2156,8 +2183,8 @@ npc_ptr basecamp::companion_choose_return( const std::string &miss_id,
return talk_function::companion_choose_return( omt_pos, base_camps::id, miss_id,
calendar::turn - min_duration );
}
void basecamp::finish_return( npc &comp, bool fixed_time, const std::string &return_msg,
const std::string &skill, int difficulty )
void basecamp::finish_return( npc &comp, const bool fixed_time, const std::string &return_msg,
const std::string &skill, int difficulty, const bool cancel )
{
popup( "%s %s", comp.name, return_msg );
// this is the time the mission was expected to take, or did take for fixed time missions
Expand All @@ -2166,7 +2193,9 @@ void basecamp::finish_return( npc &comp, bool fixed_time, const std::string &ret
if( !fixed_time ) {
mission_time = calendar::turn - comp.companion_mission_time;
}
talk_function::companion_skill_trainer( comp, skill, mission_time, difficulty );
if( !cancel ) {
talk_function::companion_skill_trainer( comp, skill, mission_time, difficulty );
}

// companions subtracted food when they started the mission, but didn't mod their hunger for
// that food. so add it back in.
Expand All @@ -2181,10 +2210,12 @@ void basecamp::finish_return( npc &comp, bool fixed_time, const std::string &ret
comp.companion_mission_time = calendar::before_time_starts;
comp.companion_mission_time_ret = calendar::before_time_starts;
bool by_radio = g->u.global_omt_location() != comp.global_omt_location();
for( size_t i = 0; i < comp.companion_mission_inv.size(); i++ ) {
for( const auto &it : comp.companion_mission_inv.const_stack( i ) ) {
if( !it.count_by_charges() || it.charges > 0 ) {
place_results( it, by_radio );
if( !cancel ) {
for( size_t i = 0; i < comp.companion_mission_inv.size(); i++ ) {
for( const auto &it : comp.companion_mission_inv.const_stack( i ) ) {
if( !it.count_by_charges() || it.charges > 0 ) {
place_results( it, by_radio );
}
}
}
}
Expand Down Expand Up @@ -2215,6 +2246,18 @@ npc_ptr basecamp::mission_return( const std::string &miss_id, time_duration min_
return comp;
}

npc_ptr basecamp::emergency_recall()
{
npc_ptr comp = talk_function::companion_choose_return( omt_pos, base_camps::id, "",
calendar::turn - 24_hours, false );
if( comp != nullptr ) {
const std::string return_msg = _( "responds to the emergency recall..." );
finish_return( *comp, false, return_msg, "menial", 0, true );
}
return comp;

}

bool basecamp::upgrade_return( const point &dir, const std::string &miss )
{
const std::string bldg = next_upgrade( dir, 1 );
Expand Down
5 changes: 3 additions & 2 deletions src/mission_companion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1998,13 +1998,14 @@ npc_ptr talk_function::companion_choose_return( const npc &p, const std::string
npc_ptr talk_function::companion_choose_return( const tripoint &omt_pos,
const std::string &role_id,
const std::string &mission_id,
const time_point &deadline )
const time_point &deadline,
const bool by_mission )
{
std::vector<npc_ptr> available;
for( npc_ptr &guy : overmap_buffer.get_companion_mission_npcs() ) {
npc_companion_mission c_mission = guy->get_companion_mission();
if( c_mission.position != omt_pos ||
c_mission.mission_id != mission_id || c_mission.role_id != role_id ) {
( by_mission && c_mission.mission_id != mission_id ) || c_mission.role_id != role_id ) {
continue;
}
if( g->u.has_trait( trait_id( "DEBUG_HS" ) ) ) {
Expand Down
3 changes: 2 additions & 1 deletion src/mission_companion.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ npc_ptr companion_choose( const std::string &skill_tested = "", int skill_level
npc_ptr companion_choose_return( const npc &p, const std::string &mission_id,
const time_point &deadline );
npc_ptr companion_choose_return( const tripoint &omt_pos, const std::string &role_id,
const std::string &mission_id, const time_point &deadline );
const std::string &mission_id, const time_point &deadline,
bool by_mission = true );

//Return NPC to your party
void companion_return( npc &comp );
Expand Down