diff --git a/src/activity_handlers.h b/src/activity_handlers.h index 3cf788c8876ab..cf33d8244e219 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -41,6 +41,12 @@ std::vector route_adjacent( const Character &you, const tripoin enum class requirement_check_result : int { SKIP_LOCATION = 0, + SKIP_LOCATION_NO_ZONE, // Zone activity but no zone found + SKIP_LOCATION_NO_SKILL, // Insufficient npc skill for task. + SKIP_LOCATION_BLOCKING, // Something is blocking the target location for companion. + SKIP_LOCATION_UNKNOWN_ACTIVITY, // This is probably an error: failed to find matching activity. + SKIP_LOCATION_NO_LOCATION, // No candidate locations found + SKIP_LOCATION_NO_MATCH, // No matches found CAN_DO_LOCATION, RETURN_EARLY //another activity like a fetch activity has been started. }; diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 1cf964b3dff4e..08757636bc17c 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -2733,7 +2733,7 @@ static requirement_check_result generic_multi_activity_check_requirement( // tidy up activity doesn't - it wants things that may not be in a zone already - things that may have been left lying around. if( needs_to_be_in_zone && !zone ) { can_do_it = false; - return requirement_check_result::SKIP_LOCATION; + return requirement_check_result::SKIP_LOCATION_NO_ZONE; } if( can_do_it ) { return requirement_check_result::CAN_DO_LOCATION; @@ -2746,7 +2746,7 @@ static requirement_check_result generic_multi_activity_check_requirement( // we can discount this tile, the work can't be done. if( reason == do_activity_reason::DONT_HAVE_SKILL ) { if( zone ) { - you.add_msg_if_player( m_info, _( "You don't have the skill for the %s task at zone %s." ), + you.add_msg_if_player( m_info, _( "You don't have the skill for the %1$s task at zone %2$s." ), act_id.c_str(), zone->get_name() ); } else { you.add_msg_if_player( m_info, _( "You don't have the skill for the %s task." ), act_id.c_str() ); @@ -2754,14 +2754,29 @@ static requirement_check_result generic_multi_activity_check_requirement( } else if( reason == do_activity_reason::BLOCKING_TILE ) { if( zone ) { you.add_msg_if_player( m_info, - _( "There is something blocking the location for the %s task at zone %s." ), act_id.c_str(), + _( "There is something blocking the location for the %1$s task at zone %2$s." ), act_id.c_str(), zone->get_name() ); } else { you.add_msg_if_player( m_info, _( "There is something blocking the location for the %s task." ), act_id.c_str() ); } } - return requirement_check_result::SKIP_LOCATION; + if( you.is_npc() ) { + if( reason == do_activity_reason::DONT_HAVE_SKILL ) { + return requirement_check_result::SKIP_LOCATION_NO_SKILL; + + } else if( reason == do_activity_reason::NO_ZONE ) { + return requirement_check_result::SKIP_LOCATION_NO_ZONE; + } else if( reason == do_activity_reason::ALREADY_DONE ) { + return requirement_check_result::SKIP_LOCATION; + } else if( reason == do_activity_reason::BLOCKING_TILE ) { + return requirement_check_result::SKIP_LOCATION_BLOCKING; + } else if( reason == do_activity_reason::UNKNOWN_ACTIVITY ) { + return requirement_check_result::SKIP_LOCATION_UNKNOWN_ACTIVITY; + } + } else { + return requirement_check_result::SKIP_LOCATION; + } } else if( reason == do_activity_reason::NO_COMPONENTS || reason == do_activity_reason::NEEDS_CUT_HARVESTING || reason == do_activity_reason::NEEDS_PLANTING || @@ -2952,7 +2967,7 @@ static requirement_check_result generic_multi_activity_check_requirement( you.activity = player_activity(); you.backlog.clear(); check_npc_revert( you ); - return requirement_check_result::SKIP_LOCATION; + return requirement_check_result::SKIP_LOCATION_NO_LOCATION; } act_prev.coords.push_back( here.getabs( @@ -2964,7 +2979,7 @@ static requirement_check_result generic_multi_activity_check_requirement( return requirement_check_result::RETURN_EARLY; } } - return requirement_check_result::SKIP_LOCATION; + return requirement_check_result::SKIP_LOCATION_NO_MATCH; } /** Do activity at this location */ @@ -3152,6 +3167,18 @@ static bool generic_multi_activity_do( return true; } +struct failure_reasons { + bool no_path = false; + bool skip_location_no_zone = false; + bool skip_location_blocking = false; + bool skip_location_no_skill = false; + bool skip_location_unknown_activity = false; + bool skip_location_no_location = false; + bool skip_location_no_match = false; + bool skip_location = false; + bool no_craft_disassembly_location_route_found = false; +}; + bool generic_multi_activity_handler( player_activity &act, Character &you, bool check_only ) { map &here = get_map(); @@ -3184,6 +3211,9 @@ bool generic_multi_activity_handler( player_activity &act, Character &you, bool } return true; } + + failure_reasons reason; + for( const tripoint_abs_ms &src : src_sorted ) { const tripoint_bub_ms &src_loc = here.bub_from_abs( src ); if( !here.inbounds( src_loc ) && !check_only ) { @@ -3198,6 +3228,7 @@ bool generic_multi_activity_handler( player_activity &act, Character &you, bool const std::vector route = route_adjacent( you, src_loc ); if( route.empty() ) { // can't get there, can't do anything, skip it + reason.no_path = true; continue; } you.set_moves( 0 ); @@ -3210,7 +3241,33 @@ bool generic_multi_activity_handler( player_activity &act, Character &you, bool const requirement_check_result req_res = generic_multi_activity_check_requirement( you, activity_to_restore, act_info, src, src_loc, src_set, check_only ); if( req_res == requirement_check_result::SKIP_LOCATION ) { + reason.skip_location = true; + continue; + + } else if( req_res == requirement_check_result::SKIP_LOCATION_NO_ZONE ) { + reason.skip_location_no_zone = true; continue; + + } else if( req_res == requirement_check_result::SKIP_LOCATION_NO_SKILL ) { + reason.skip_location_no_skill = true; + continue; + + } else if( req_res == requirement_check_result::SKIP_LOCATION_BLOCKING ) { + reason.skip_location_blocking = true; + continue; + + } else if( req_res == requirement_check_result::SKIP_LOCATION_UNKNOWN_ACTIVITY ) { + reason.skip_location_unknown_activity = true; + continue; + + } else if( req_res == requirement_check_result::SKIP_LOCATION_NO_LOCATION ) { + reason.skip_location_no_location = true; + continue; + + } else if( req_res == requirement_check_result::SKIP_LOCATION_NO_MATCH ) { + reason.skip_location_no_match = true; + continue; + } else if( req_res == requirement_check_result::RETURN_EARLY ) { return true; } @@ -3232,6 +3289,7 @@ bool generic_multi_activity_handler( player_activity &act, Character &you, bool // check if we found path to source / adjacent tile if( route.empty() ) { check_npc_revert( you ); + reason.no_craft_disassembly_location_route_found = true; continue; } if( !check_only ) { @@ -3290,6 +3348,46 @@ bool generic_multi_activity_handler( player_activity &act, Character &you, bool you.activity_vehicle_part_index = -1; } // scanned every location, tried every path. + if( !check_only && you.is_npc() ) { + if( src_sorted.empty() ) { + add_msg( m_neutral, + _( "%1s failed to perform the %2$s activity because no suitable locations were found." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.no_path ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because no path to a suitable location could be found." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location_no_zone ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because no required zone was found." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location_blocking ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because the target location is blocked or cannot be reached." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location_no_skill ) { + add_msg( m_neutral, _( "%1$s failed to perform the %2$s activity because of insufficient skills." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location_unknown_activity ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because the activity couldn't be found. This is probably an error." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location_no_location ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because no suitable location could be found." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location_no_match ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because no criteria could be matched." ), + you.disp_name(), activity_to_restore.c_str() ); + } else if( reason.skip_location ) { + // Assumed to have been reported already. + } else if( reason.no_craft_disassembly_location_route_found ) { + add_msg( m_neutral, + _( "%1$s failed to perform the %2$s activity because no path to a suitable crafting/disassembly location could be found." ), + you.disp_name(), activity_to_restore.c_str() ); + } + } return false; }