37 #define DBG_NG LOG_STREAM(debug, log_engine) 44 heal_unit(
unit &patient,
const std::vector<unit *> &treaters,
int healing,
53 std::vector<unit *> healers;
67 if ( status ==
"cured" )
70 if ( status ==
"slowed" )
83 std::vector<unit *> & healers)
91 if ( patient.
side() == side )
100 curing = std::max(curing, poison_status((*regen.ability_cfg)[
"poison"]));
101 if ( curing == POISON_CURE )
112 POISON_STATUS this_cure = poison_status((*heal.ability_cfg)[
"poison"]);
113 if ( this_cure <= curing )
120 assert(cure_it != units.
end());
121 const int cure_side = cure_it->side();
126 if ( teams[cure_side-1].is_enemy(side) )
130 if ( cure_side != side )
131 this_cure = POISON_SLOW;
135 if ( this_cure == POISON_CURE ) {
137 healers.push_back(&*cure_it);
147 if ( curer != units.
end() )
148 healers.push_back(&*curer);
158 inline bool update_healing(
int & healing,
int & harming,
int value)
161 if ( value > healing ) {
167 if ( value < harming ) {
179 int heal_amount(
int side,
const unit & patient, std::vector<unit *> & healers)
187 if ( patient.
side() == side )
190 update_healing(healing, harming,
203 while ( heal_it != heal_list.end() ) {
205 assert(healer != units.
end());
207 if ( healer->side() != side )
208 heal_it = heal_list.erase(heal_it);
219 healers.push_back(&*units.
find(heal.loc));
221 if ( !healers.empty() ) {
222 DBG_NG <<
"Unit has " << healers.size() <<
" healers.\n";
226 return healing + harming;
233 void do_heal(
unit &patient,
int amount,
bool cure_poison)
238 patient.
heal(amount);
239 else if ( amount < 0 )
249 void animate_heals(std::list<heal_unit> &unit_list)
253 while ( !unit_list.empty() )
256 int min_dist = INT_MAX;
260 check_it != unit_list.end(); ++check_it )
263 if ( distance < min_dist ) {
272 std::string cure_text =
"";
273 if ( nearest->cure_poison )
275 _(
"female^cured") :
_(
"cured");
279 nearest->amount, cure_text);
280 do_heal(nearest->healed, nearest->amount, nearest->cure_poison);
283 last_loc = nearest->healed.get_location();
284 unit_list.erase(nearest);
294 DBG_NG <<
"beginning of healing calculations\n";
296 std::list<heal_unit> unit_list;
301 if ( patient.get_state(
"unhealable") || patient.incapacitated() ) {
305 DBG_NG <<
"found healable unit at (" << patient.get_location() <<
")\n";
309 std::vector<unit *> healers;
313 if ( patient.side() == side ) {
314 if ( patient.resting() || patient.is_healthy() )
320 healing += heal_amount(side, patient, healers);
323 curing = poison_progress(side, patient, healers);
326 if ( curing == POISON_NORMAL && patient.side() == side )
331 int max_heal = std::max(0, patient.max_hitpoints() - patient.hitpoints());
332 int min_heal = std::min(0, 1 - patient.hitpoints());
333 if ( healing < min_heal )
335 else if ( healing > max_heal )
339 if ( curing != POISON_CURE && healing == 0 )
342 if (!healers.empty()) {
343 DBG_NG <<
"Just before healing animations, unit has " << healers.size() <<
" potential healers.\n";
348 unit_list.emplace_front(patient, healers, healing, curing == POISON_CURE);
353 do_heal(patient, healing, curing == POISON_CURE);
357 animate_heals(unit_list);
359 DBG_NG <<
"end of healing calculations\n";
play_controller * controller
static lg::log_domain log_engine("engine")
virtual const std::vector< team > & teams() const override
virtual const unit_map & units() const override
This class represents a single unit of a specific type.
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
The unit is slowed - it moves slower and does less damage.
bool take_hit(int damage)
Damage the unit.
static std::string _(const char *str)
std::vector< unit_ability >::iterator iterator
void heal(int amount)
Heal the unit.
Data typedef for unit_ability_list.
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
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.
Encapsulates the map of the game.
void calculate_healing(int side, bool update_display)
Calculates healing for all units for the given side.
unit_iterator find(std::size_t id)
int get_composite_value() const
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.
Various functions that implement healing of units (when a side turn starts).
const map_location & get_location() const
The current map location this unit is at.
Standard logging facilities (interface).
Container associating units to locations.
int side() const
The side this unit belongs to.
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.
std::string::const_iterator iterator
Display units performing various actions: moving, attacking, and dying.
static game_display * get_singleton()