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 &) const22 status_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 &) const33 status_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 &) const42 status_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 &) const51 status_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 &) const62 status_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 &) const84 status_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 &) const91 status_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 &) const100 status_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