39 #define DBG_NG LOG_STREAM(debug, log_engine)
46 heal_unit(
unit &patient,
const std::vector<unit *> &treaters,
int healing,
55 std::vector<unit *> healers;
61 enum POISON_STATUS { POISON_NORMAL, POISON_SLOW , POISON_CURE };
67 POISON_STATUS poison_status(
const std::string & status)
69 if ( status ==
"cured" )
72 if ( status ==
"slowed" )
84 POISON_STATUS poison_progress(
int side,
const unit & patient,
85 std::vector<unit *> & healers)
90 POISON_STATUS curing = POISON_NORMAL;
93 if ( patient.
side() == side )
102 curing = std::max(curing, poison_status((*regen.ability_cfg)[
"poison"]));
103 if ( curing == POISON_CURE )
114 POISON_STATUS this_cure = poison_status((*heal.ability_cfg)[
"poison"]);
115 if ( this_cure <= curing )
122 assert(cure_it != units.
end());
123 const int cure_side = cure_it->side();
128 if ( teams[cure_side-1].is_enemy(side) )
132 if ( cure_side != side )
133 this_cure = POISON_SLOW;
137 if ( this_cure == POISON_CURE ) {
139 healers.push_back(&*cure_it);
149 if ( curer != units.
end() )
150 healers.push_back(&*curer);
160 inline bool update_healing(
int & healing,
int & harming,
int value)
163 if ( value > healing ) {
169 if ( value < harming ) {
181 int heal_amount(
int side,
const unit & patient, std::vector<unit *> & healers)
189 if ( patient.
side() == side )
192 update_healing(healing, harming,
206 assert(healer != units.
end());
208 return healer->side() != side;
213 if ( update_healing(healing, harming, heal_effect.get_composite_value()) )
217 healers.push_back(&*units.
find(heal.loc));
219 if ( !healers.empty() ) {
220 DBG_NG <<
"Unit has " << healers.size() <<
" healers.";
224 return healing + harming;
231 void do_heal(
unit &patient,
int amount,
bool cure_poison)
236 patient.
heal(amount);
237 else if ( amount < 0 )
247 void animate_heals(std::list<heal_unit> &unit_list)
251 while ( !unit_list.empty() )
254 int min_dist = std::numeric_limits<int>::max();
258 check_it != unit_list.end(); ++check_it )
261 if ( distance < min_dist ) {
270 std::string cure_text =
"";
271 if ( nearest->cure_poison )
273 _(
"female^cured") :
_(
"cured");
277 nearest->amount, cure_text);
278 do_heal(nearest->healed, nearest->amount, nearest->cure_poison);
281 last_loc = nearest->healed.get_location();
282 unit_list.erase(nearest);
292 DBG_NG <<
"beginning of healing calculations";
294 std::list<heal_unit> unit_list;
299 if ( patient.get_state(
"unhealable") || patient.incapacitated() ) {
303 DBG_NG <<
"found healable unit at (" << patient.get_location() <<
")";
305 POISON_STATUS curing = POISON_NORMAL;
307 std::vector<unit *> healers;
311 if ( patient.side() == side ) {
312 if ( patient.resting() || patient.is_healthy() )
318 healing += heal_amount(side, patient, healers);
321 curing = poison_progress(side, patient, healers);
324 if ( curing == POISON_NORMAL && patient.side() == side )
329 int max_heal = std::max(0, patient.max_hitpoints() - patient.hitpoints());
330 int min_heal = std::min(0, 1 - patient.hitpoints());
331 if ( healing < min_heal )
333 else if ( healing > max_heal )
337 if ( curing != POISON_CURE && healing == 0 )
340 if (!healers.empty()) {
341 DBG_NG <<
"Just before healing animations, unit has " << healers.size() <<
" potential healers.";
346 unit_list.emplace_front(patient, healers, healing, curing == POISON_CURE);
351 do_heal(patient, healing, curing == POISON_CURE);
355 animate_heals(unit_list);
357 DBG_NG <<
"end of healing calculations";
virtual const std::vector< team > & teams() const override
virtual const unit_map & units() const override
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
static game_display * get_singleton()
int get_composite_value() const
Container associating units to locations.
unit_iterator find(std::size_t id)
This class represents a single unit of a specific type.
static std::string _(const char *str)
unit_ability_list get_abilities(const std::string &tag_name, const map_location &loc) const
Gets the unit's active abilities of a particular type if it were on a specified location.
void heal(int amount)
Heal the unit.
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
bool take_hit(int damage)
Damage the unit.
int side() const
The side this unit belongs to.
@ STATE_POISONED
The unit is slowed - it moves slower and does less damage.
const map_location & get_location() const
The current map location this unit is at.
void calculate_healing(int side, bool update_display)
Calculates healing for all units for the given side.
static lg::log_domain log_engine("engine")
Various functions that implement healing of units (when a side turn starts).
std::size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
Standard logging facilities (interface).
play_controller * controller
void unit_healing(unit &healed, const std::vector< unit * > &healers, int healing, const std::string &extra_text)
This will use a poisoning anim if healing<0.
void erase_if(Container &container, const Predicate &predicate)
Convenience wrapper for using std::remove_if on a container.
std::string::const_iterator iterator
Encapsulates the map of the game.
Data typedef for unit_ability_list.
Display units performing various actions: moving, attacking, and dying.