1 #include <functional> 2 #include <memory> 3 #include <vector> 4 5 #include "behavior.h" 6 #include "character.h" 7 #include "character_oracle.h" 8 #include "item.h" 9 #include "itype.h" 10 #include "make_static.h" 11 #include "ret_val.h" 12 #include "type_id.h" 13 #include "value_ptr.h" 14 #include "weather.h" 15 16 namespace behavior 17 { 18 19 // To avoid a local minima when the character has access to warmth in a shelter but gets cold 20 // when they go outside, this method needs to only alert when travel time to known shelter 21 // approaches time to freeze. needs_warmth_badly(const std::string &) const22status_t character_oracle_t::needs_warmth_badly( const std::string & ) const 23 { 24 // Use player::temp_conv to predict whether the Character is "in trouble". 25 for( const bodypart_id &bp : subject->get_all_body_parts() ) { 26 if( subject->get_part_temp_conv( bp ) <= BODYTEMP_VERY_COLD ) { 27 return status_t::running; 28 } 29 } 30 return status_t::success; 31 } 32 needs_water_badly(const std::string &) const33status_t character_oracle_t::needs_water_badly( const std::string & ) const 34 { 35 // Check thirst threshold. 36 if( subject->get_thirst() > 520 ) { 37 return status_t::running; 38 } 39 return status_t::success; 40 } 41 needs_food_badly(const std::string &) const42status_t character_oracle_t::needs_food_badly( const std::string & ) const 43 { 44 // Check hunger threshold. 45 if( subject->get_hunger() >= 300 && subject->get_starvation() > 2500 ) { 46 return status_t::running; 47 } 48 return status_t::success; 49 } 50 can_wear_warmer_clothes(const std::string &) const51status_t character_oracle_t::can_wear_warmer_clothes( const std::string & ) const 52 { 53 // Check inventory for wearable warmer clothes, greedily. 54 // Don't consider swapping clothes yet, just evaluate adding clothes. 55 bool found_clothes = subject->has_item_with( [this]( const item & candidate ) { 56 return candidate.get_warmth() > 0 && subject->can_wear( candidate ).success() && 57 !subject->is_worn( candidate ); 58 } ); 59 return found_clothes ? status_t::running : status_t::failure; 60 } 61 can_make_fire(const std::string &) const62status_t character_oracle_t::can_make_fire( const std::string & ) const 63 { 64 // Check inventory for firemaking tools and fuel 65 bool tool = false; 66 bool fuel = false; 67 bool found_fire_stuff = subject->has_item_with( [&tool, &fuel]( const item & candidate ) { 68 if( candidate.has_flag( STATIC( flag_id( "FIRESTARTER" ) ) ) ) { 69 tool = true; 70 if( fuel ) { 71 return true; 72 } 73 } else if( candidate.flammable() ) { 74 fuel = true; 75 if( tool ) { 76 return true; 77 } 78 } 79 return false; 80 } ); 81 return found_fire_stuff ? status_t::running : status_t::success; 82 } 83 can_take_shelter(const std::string &) const84status_t character_oracle_t::can_take_shelter( const std::string & ) const 85 { 86 // There be no shelter here. 87 // The frontline is everywhere. 88 return status_t::failure; 89 } 90 has_water(const std::string &) const91status_t character_oracle_t::has_water( const std::string & ) const 92 { 93 // Check if we know about water somewhere 94 bool found_water = subject->has_item_with( []( const item & cand ) { 95 return cand.is_food() && cand.get_comestible()->quench > 0; 96 } ); 97 return found_water ? status_t::running : status_t::failure; 98 } 99 has_food(const std::string &) const100status_t character_oracle_t::has_food( const std::string & ) const 101 { 102 // Check if we know about food somewhere 103 bool found_food = subject->has_item_with( []( const item & cand ) { 104 return cand.is_food() && cand.get_comestible()->has_calories(); 105 } ); 106 return found_food ? status_t::running : status_t::failure; 107 } 108 109 } // namespace behavior 110