Simplify healing as per multiple discussions:

No limit of hitpoints per cure/heal, heal at start of healer turn.

Healing still doesn't stack (you can only be healed by one thing), but
standing next to allies healer can get you double-healing.

If healers are now too powerful, simplest would be to limit number of
patients each healer can treat.

If allied healers are too powerful, we could extend limit across
entire turn, so unit cannot be treated by more than one healer per
turn, even allies.
This commit is contained in:
Rusty Russell 2006-03-27 09:36:42 +00:00
parent 8fdcfa7358
commit 01751ea84e
14 changed files with 183 additions and 352 deletions

37
MANUAL
View file

@ -226,35 +226,20 @@ HEALING
Injured units in villages will recover 8 hitpoints every turn. Injured Injured units in villages will recover 8 hitpoints every turn. Injured
units that are adjacent to units with the 'heal' or 'cure' abilities units that are adjacent to units with the 'heal' or 'cure' abilities
will also heal. A unit that does not move or fight during a turn is will also heal. A unit that does not move or fight during a turn is
'resting' and will recover 2 hitpoints. Hitpoints recovered through 'resting' and will recover an additional 2 hitpoints.
'resting' are added on top of hitpoints recovered through healing or
regenerating.
A unit with the 'heals' ability may heal up to 8 hitpoints total per A unit with the 'heals' ability will heal adjacent allied units by up
turn. A unit with the 'cures' ability may heal up to 18 hitpoints total to 4 hitpoints each, at the beginning of the healer's turn. Poisoned
per turn. units will have their poison damage stopped by the healer, instead.
Units next to unit(s) with the 'heals' ability will recover a maximum of A unit with the 'cures' ability will heal adjacent allied units by up
4 hitpoints per turn; units next to unit(s) with the 'cures' ability to 8 hitpoints each, at the beginning of the curer's turn. Poisoned
will recover a maximum of 8 hitpoints per turn. The more units around a units will have their poison cured by healer, instead.
unit that can heal, the less each one will be healed.
An example of 'heals' with multiple adjacent units: No unit can be healed or cured by more than one thing at a time: the
effects are not cumulative. For example, a unit standing in a village
Two units next to a 'healer' will receive 4 hitpoints each. gains no additional benefit from a curer standing next to it. A unit
standing next to two healers and a curer will not use the two healers.
3 units next to a 'healer' will NOT receive 4 hitpoints each:
two will receive 3 hitpoints and one will receive 2 hitpoints.
A unit may be healed a maximum of 8 hitpoints per turn, with a possible
2 hitpoints extra if resting. Trolls, which have the regenerate
ability, will only recover 8 hitpoints when residing in a village, not
16. Nor will a unit inside a village get extra healing from adjacent
healers.
'Heals' prevents poison from causing damage while 'cures' removes
poison. When poison is cured or prevented the unit does not gain or lose
hitpoints on that turn due to healing/poisoning.
For more information see the in-game help. For more information see the in-game help.

View file

@ -25,9 +25,8 @@ ability_ambush= _ "ambush"
cures_description= _ "Cures: cures_description= _ "Cures:
This unit combines herbal remedies with magic to heal units more quickly than is normally possible on the battlefield. This unit combines herbal remedies with magic to heal units more quickly than is normally possible on the battlefield.
This unit will care for all adjacent friendly units that are injured at the beginning of each turn. This unit will care for all adjacent friendly units that are injured at the beginning of its turn.
A unit cared for by a curer may heal up to 8 HP per turn. Each non-poisoned unit cared for by a curer will heal by up to 8 HP per turn.
A curer may heal a total of 18 HP per turn, for all units it cares for.
A curer can cure a unit of poison, although that unit will receive no additional healing on the turn it is cured of the poison." A curer can cure a unit of poison, although that unit will receive no additional healing on the turn it is cured of the poison."
ability_cures= _ "cures" ability_cures= _ "cures"
@ -35,9 +34,9 @@ ability_cures= _ "cures"
heals_description= _ "Heals: heals_description= _ "Heals:
Allows the unit to heal adjacent friendly units at the beginning of each turn. Allows the unit to heal adjacent friendly units at the beginning of each turn.
A unit cared for by a healer may heal up to 4 HP per turn. This unit will care for all adjacent friendly units that are injured at the beginning of its turn.
A healer may heal a total of 8 HP per turn, for all units it cares for. Each non-poisoned unit cared for by a healer will heal up to 4 HP per turn.
A poisoned unit cannot be cured of its poison by a healer, and must seek the care of a village or a unit that can cure." A healer will stop the damage done by poison on the current turn, but cannot cure it: the poisoned unit must seek the care of a village or a unit that can cure."
ability_heals= _ "heals" ability_heals= _ "heals"

View file

@ -44,9 +44,7 @@ default=yes
base_income=2 base_income=2
village_income=1 village_income=1
heal_amount=4 heal_amount=4
healer_heals_per_turn=8
cure_amount=8 cure_amount=8
curer_heals_per_turn=18
rest_heal_amount=2 rest_heal_amount=2
recall_cost=20 recall_cost=20
kill_experience=8 kill_experience=8

View file

@ -216,10 +216,10 @@ text= _ "In combat, your units will inevitably take damage. When a unit <ref>dst
Resting: A unit which neither moves, attacks, nor is attacked will heal 2HP in its next turn." + _" Resting: A unit which neither moves, attacks, nor is attacked will heal 2HP in its next turn." + _"
Villages: A unit which starts a turn in a village will heal 8HP." + _" Villages: A unit which starts a turn in a village will heal 8HP." + _"
<ref>dst=ability_regenerates text=Regeneration</ref>: Certain units (such as trolls) will automatically heal 8HP every turn." + _" <ref>dst=ability_regenerates text=Regeneration</ref>: Certain units (such as trolls) will automatically heal 8HP every turn." + _"
Healing units: Units with the <ref>dst=ability_heals text=Heals</ref> ability will heal up to 8HP of damage per turn, as well as preventing Poison from causing damage. Only those units will be healed that are adjacent to and are fighting on the same side as the healing unit, and only up to 4HP per unit." + _" Healing units: Units with the <ref>dst=ability_heals text=Heals</ref> ability will heal up to 4HP of damage from each allied adjacent unit, per turn, or prevent Poison from causing that unit damage." + _"
Curing units: Units with the <ref>dst=ability_cures text=Cures</ref> ability will heal up to 18HP of damage per turn, as well as curing Poison. Only those units will be healed or cured that are adjacent to and are fighting on the same side as the healing unit, and only up to 8HP per unit." + _" Curing units: Units with the <ref>dst=ability_cures text=Cures</ref> ability will heal up to 8HP of damage from each allied adjacent unit, per turn, or cure Poison in that unit." + _"
Resting can be combined with other forms of healing, but villages, regeneration, healing and curing cannot combine with each other. A healing or curing unit whose attention is split between many wounded will be less effective at healing their individual wounds. Finally, units heal fully between scenarios." Resting can be combined with other forms of healing, but villages, regeneration, healing and curing cannot combine with each other: the best option will be used. Finally, units heal fully between scenarios."
[/topic] [/topic]
[topic] [topic]

View file

@ -1384,317 +1384,189 @@ unit_map::const_iterator find_leader(const unit_map& units, int side)
} }
namespace { namespace {
struct patient
//function which returns true iff the unit at 'loc' will heal a unit from side 'side'
//on this turn.
//
//units heal other units if they are (1) on the same side as them; or (2) are on a
//different but allied side, and there are no 'higher priority' sides also adjacent
//to the healer
bool will_heal(const gamemap::location& loc, int side, const std::vector<team>& teams,
const unit_map& units)
{ {
const unit_map::const_iterator healer_it = units.find(loc); patient(unit &un, bool allied)
if(healer_it == units.end() || healer_it->second.type().heals() == false) { : u(un), healing(0), poison_stopped(false), ally(allied) { }
return false;
unit &u;
// How much have we been healed?
int healing;
// Was our poison stopped / cured?
bool poison_stopped;
// Are we an ally? In which case we only get healed.
bool ally;
void heal(int amount, bool allies_too);
void harm(int amount);
void rest();
};
void patient::heal(int amount, bool allies_too)
{
if (ally && !allies_too)
return;
if (u.poisoned()) {
if (amount >= game_config::cure_amount)
u.remove_flag("poisoned");
poison_stopped = true;
} else {
healing = minimum(u.max_hitpoints() - u.hitpoints(), amount);
std::cerr << "healing by " << lexical_cast<std::string>(healing) << " of potential "
<< lexical_cast<std::string>(u.max_hitpoints() - u.hitpoints()) << "\n";
} }
}
const unit& healer = healer_it->second; void patient::harm(int amount)
{
if (ally)
return;
wassert(!healing && !poison_stopped);
healing = -minimum(u.hitpoints() - 1, amount);
}
if(healer.incapacitated()) { void patient::rest()
return false; {
} if (ally)
return;
if((int)healer.side() == side) { healing += minimum(u.max_hitpoints() - (u.hitpoints() + healing), game_config::rest_heal_amount);
return true; std::cerr << "resting by " << lexical_cast<std::string>(minimum(u.max_hitpoints() - (u.hitpoints() + healing), game_config::rest_heal_amount)) << "\n";
} }
if(size_t(side-1) >= teams.size() || size_t(healer.side()-1) >= teams.size()) {
return false;
}
//if the healer is an enemy, it won't heal
if(teams[healer.side()-1].is_enemy(side)) {
return false;
}
// Find the best adjacent healer.
unit_map::iterator find_healer(const gamemap::location &loc, std::map<gamemap::location,unit>& units,
unsigned int side)
{
gamemap::location adjacent[6]; gamemap::location adjacent[6];
get_adjacent_tiles(loc,adjacent); unit_map::iterator healer = units.end();
for(int n = 0; n != 6; ++n) {
const unit_map::const_iterator u = units.find(adjacent[n]); get_adjacent_tiles(loc, adjacent);
if(u != units.end() && (u->second.hitpoints() < u->second.max_hitpoints() || u->second.poisoned())) { for (unsigned int n = 0; n != 6U; ++n) {
//ignore stoned units unit_map::iterator i = units.find(adjacent[n]);
if(!u->second.healable()) if (i != units.end()) {
if (i->second.incapacitated())
continue; continue;
if (i->second.side() != side)
const int unit_side = u->second.side(); continue;
if (!i->second.type().heals())
//the healer won't heal an ally if there is a wounded unit on the same continue;
//side next to her if (healer == units.end() || i->second.type().heals() > healer->second.type().heals())
if(unit_side == (int)healer.side()) healer = i;
return false;
//choose an arbitrary order for healing
if(unit_side > side)
return false;
} }
} }
return healer;
//there's no-one of higher priority nearby, so the ally will heal }
return true;
} }
void reset_resting(std::map<gamemap::location,unit>& units, unsigned int side)
{
for (unit_map::iterator i = units.begin(); i != units.end(); ++i) {
if (i->second.side() == side)
i->second.set_resting(true);
}
} }
// Simple algorithm: no maximum number of patients per healer.
void calculate_healing(display& disp, const gamestatus& status, const gamemap& map, void calculate_healing(display& disp, const gamestatus& status, const gamemap& map,
std::map<gamemap::location,unit>& units, int side, std::map<gamemap::location,unit>& units, unsigned int side,
const std::vector<team>& teams, bool update_display) const std::vector<team>& teams, bool update_display)
{ {
std::map<gamemap::location,int> healed_units, max_healing; // We look for all allied units, then we see if our healer is near them.
for (unit_map::iterator i = units.begin(); i != units.end(); ++i) {
//a map of healed units to their healers if (teams[i->second.side()-1].is_enemy(side))
std::multimap<gamemap::location,gamemap::location> healers; continue;
std::map<gamemap::location,unit>::iterator i;
int amount_healed;
for(i = units.begin(); i != units.end(); ++i) {
amount_healed = 0;
if (!i->second.healable()) if (!i->second.healable())
continue; continue;
//the unit heals if it's on this side, and it's on a village or patient p(i->second, i->second.side() != side);
//it has regeneration, and it is wounded unit_map::iterator healer = units.end();
if((int)i->second.side() == side) {
if(i->second.hitpoints() < i->second.max_hitpoints() || i->second.poisoned()){
if(map.gives_healing(i->first)) {
amount_healed = maximum<int>(amount_healed,game_config::cure_amount);
}
if(i->second.type().regenerates()) {
amount_healed = maximum<int>(amount_healed,i->second.type().regenerate_amount());
}
}
if(amount_healed != 0)
healed_units.insert(std::pair<gamemap::location,int>(
i->first, amount_healed));
}
//otherwise find the maximum healing for the unit if (p.u.type().regenerates())
if(amount_healed == 0) { p.heal(p.u.type().regenerate_amount(), false);
int max_heal = 0; else if (map.gives_healing(i->first))
gamemap::location adjacent[6]; p.heal(game_config::cure_amount, false);
get_adjacent_tiles(i->first,adjacent); else {
for(int j = 0; j != 6; ++j) { healer = find_healer(i->first, units, side);
if(will_heal(adjacent[j],i->second.side(),teams,units)) { if (healer != units.end())
const unit_map::const_iterator healer = units.find(adjacent[j]); p.heal(healer->second.type().heals(), true);
max_heal = maximum(max_heal,healer->second.type().heals()); }
if (p.u.poisoned() && !p.poison_stopped)
p.harm(game_config::cure_amount);
if (p.u.is_resting())
p.rest();
healers.insert(std::pair<gamemap::location,gamemap::location>(i->first,adjacent[j])); if (!p.healing && !p.poison_stopped)
}
}
if(max_heal > 0) {
max_healing.insert(std::pair<gamemap::location,int>(i->first,max_heal));
}
}
}
//now see about units that can heal other units
for(i = units.begin(); i != units.end(); ++i) {
if(will_heal(i->first,side,teams,units)) {
gamemap::location adjacent[6];
bool gets_healed[6];
get_adjacent_tiles(i->first,adjacent);
int nhealed = 0;
int j;
for(j = 0; j != 6; ++j) {
const std::map<gamemap::location,unit>::const_iterator adj =
units.find(adjacent[j]);
if(adj != units.end() &&
adj->second.hitpoints() < adj->second.max_hitpoints() &&
(int)adj->second.side() == side &&
healed_units[adj->first] < max_healing[adj->first] &&
adj->second.healable()) {
++nhealed;
gets_healed[j] = true;
} else {
gets_healed[j] = false;
}
}
if(nhealed == 0)
continue; continue;
const int healing_per_unit = i->second.type().max_unit_healing()/nhealed; if (disp.turbo() || recorder.is_skipping()
|| disp.fogged(i->first.x, i->first.y)
for(j = 0; j != 6; ++j) { || !update_display
if(!gets_healed[j]) || (p.u.invisible(map.underlying_union_terrain(map[i->first.x][i->first.y]),
status.get_time_of_day().lawful_bonus,i->first,units,teams) &&
teams[disp.viewing_team()].is_enemy(side))) {
// Simple path.
if (p.healing > 0)
p.u.heal(p.healing);
else if (p.healing < 0)
p.u.gets_hit(-p.healing);
continue; continue;
wassert(units.find(adjacent[j]) != units.end());
healed_units[adjacent[j]]
= minimum(max_healing[adjacent[j]],
healed_units[adjacent[j]]+healing_per_unit);
}
}
} }
//poisoned units will take the same amount of damage per turn, as // This is all the pretty stuff.
//curing heals until they are reduced to 1 hitpoint. If they are
//cured on a turn, they recover 0 hitpoints that turn, but they
//are no longer poisoned
for(i = units.begin(); i != units.end(); ++i) {
if((int)i->second.side() == side && i->second.poisoned() && i->second.healable()) {
const int damage = minimum<int>(game_config::cure_amount,
i->second.hitpoints()-1);
if(damage > 0) {
healed_units.insert(std::pair<gamemap::location,int>(i->first,-damage));
}
}
}
for(i = units.begin(); i != units.end(); ++i) {
if((int)i->second.side() == side && i->second.healable()) {
if(i->second.hitpoints() < i->second.max_hitpoints() ||
i->second.poisoned()){
if(i->second.is_resting()) {
const std::map<gamemap::location,int>::iterator u =
healed_units.find(i->first);
if(u != healed_units.end()) {
healed_units[i->first] += game_config::rest_heal_amount;
} else {
healed_units.insert(std::pair<gamemap::location,int>(i->first,game_config::rest_heal_amount));
}
}
}
i->second.set_resting(true);
}
}
for(std::map<gamemap::location,int>::iterator h = healed_units.begin();
h != healed_units.end(); ++h) {
const gamemap::location& loc = h->first;
wassert(units.count(loc) == 1);
unit& u = units.find(loc)->second;
const bool show_healing = !disp.turbo() && !recorder.is_skipping() &&
!disp.fogged(loc.x,loc.y) && update_display &&
(!u.invisible(map.underlying_union_terrain(map[h->first.x][h->first.y]),
status.get_time_of_day().lawful_bonus,h->first,units,teams) ||
teams[disp.viewing_team()].is_enemy(side) == false);
typedef std::multimap<gamemap::location,gamemap::location>::const_iterator healer_itor;
const std::pair<healer_itor,healer_itor> healer_itors = healers.equal_range(loc);
// time at which we start all anmations
int start_time = 0; int start_time = 0;
if(show_healing) { disp.scroll_to_tile(i->first.x, i->first.y, display::ONSCREEN);
disp.scroll_to_tile(loc.x,loc.y,display::ONSCREEN); disp.select_hex(i->first);
disp.select_hex(loc);
if (healer != units.end()) {
//iterate over any units that are healing this unit, and make them healer->second.set_healing(disp);
//enter their healing frame start_time = healer->second.get_animation()->get_first_frame_time();
for(healer_itor i = healer_itors.first; i != healer_itors.second; ++i) {
wassert(units.count(i->second));
unit& healer = units.find(i->second)->second;
healer.set_healing(disp);
start_time = minimum<int>(start_time,healer.get_animation()->get_first_frame_time());
} }
} if (p.healing < 0) {
p.u.set_poisoned(disp, -p.healing);
start_time = minimum<int>(start_time, p.u.get_animation()->get_first_frame_time());
LOG_NG << "unit is poisoned? " << (u.has_flag("poisoned") ? "yes" : "no") << ","
<< h->second << "," << max_healing[h->first] << "\n";
if(u.has_flag("poisoned") && h->second > 0) {
//poison is purged only if we are on a village or next to a curer
if(h->second >= game_config::cure_amount ||
max_healing[h->first] >= game_config::cure_amount) {
u.remove_flag("poisoned");
events::pump();
if(show_healing) {
sound::play_sound("heal.wav");
}
}
h->second = 0;
} else {
if(h->second > 0 && h->second > u.max_hitpoints()-u.hitpoints()) {
h->second = u.max_hitpoints()-u.hitpoints();
if(h->second <= 0)
continue;
}
if(h->second < 0) {
if(show_healing) {
sound::play_sound("groan.wav"); sound::play_sound("groan.wav");
disp.float_label(h->first,lexical_cast<std::string>(h->second*-1),255,0,0); disp.float_label(i->first, lexical_cast<std::string>(-p.healing), 255,0,0);
} } else {
} else if(h->second > 0) { p.u.set_healed(disp, p.healing);
if(show_healing) { start_time = minimum<int>(start_time, p.u.get_animation()->get_first_frame_time());
sound::play_sound("heal.wav"); sound::play_sound("heal.wav");
disp.float_label(h->first,lexical_cast<std::string>(h->second),0,255,0); disp.float_label(i->first, lexical_cast<std::string>(p.healing), 0,255,0);
}
}
} }
// restart both anims in a synchronized way
p.u.restart_animation(disp, start_time);
if (healer != units.end())
healer->second.restart_animation(disp, start_time);
if(h->second >= 0) { bool finished;
u.set_healed(disp,h->second); do {
start_time = minimum<int>(start_time,u.get_animation()->get_first_frame_time()); finished = (p.u.get_animation()->animation_finished());
disp.draw_tile(i->first.x, i->first.y);
if (healer != units.end()) {
finished &= healer->second.get_animation()->animation_finished();
disp.draw_tile(healer->first.x, healer->first.y);
} }
if(h->second < 0) { if (p.healing > 0) {
u.set_poisoned(disp,-h->second); p.u.heal(1);
start_time = minimum<int>(start_time,u.get_animation()->get_first_frame_time()); --p.healing;
} else if (p.healing < 0) {
p.u.gets_hit(1);
++p.healing;
} }
//std::vector<unit*>::iterator itor; finished &= (!p.healing);
// restart all anims in a synchronized way
u.restart_animation(disp,start_time);
for(healer_itor i = healer_itors.first; i != healer_itors.second; ++i) {
unit& healer = units.find(i->second)->second;
healer.set_facing(i->first.get_relative_dir(i->second));
healer.restart_animation(disp,start_time);
}
bool finished = false;
while(!finished) {
healer_itor i;
finished = (u.get_animation()->animation_finished());
disp.draw_tile(loc.x,loc.y);
for(i = healer_itors.first; i != healer_itors.second; ++i) {
unit& healer = units.find(i->second)->second;
finished &= healer.get_animation()->animation_finished();
disp.draw_tile(i->second.x,i->second.y);
}
if(h->second > 0) {
u.heal(1);
--h->second;
} else if (h->second <0) {
u.gets_hit(1);
++h->second;
}
finished &= (h->second ==0);
disp.update_display(); disp.update_display();
events::pump(); events::pump();
if(!disp.turbo()) SDL_Delay(10); SDL_Delay(10);
} while (!finished);
} p.u.set_standing(disp);
u.set_standing(disp); if (healer != units.end())
for(healer_itor i = healer_itors.first; i != healer_itors.second; ++i) { healer->second.set_standing(disp);
unit& healer = units.find(i->second)->second;
healer.set_standing(disp);
}
disp.update_display(); disp.update_display();
events::pump(); events::pump();
} }

View file

@ -126,9 +126,13 @@ unit_map::const_iterator find_leader(const unit_map& units, int side);
//calculates healing for all units for the given side. Should be called //calculates healing for all units for the given side. Should be called
//at the beginning of a side's turn. //at the beginning of a side's turn.
void calculate_healing(display& disp, const gamestatus& status, const gamemap& map, void calculate_healing(display& disp, const gamestatus& status, const gamemap& map,
std::map<gamemap::location,unit>& units, int side, std::map<gamemap::location,unit>& units, unsigned int side,
const std::vector<team>& teams, bool update_display); const std::vector<team>& teams, bool update_display);
// Resets resting for all units on this side: should be called after calculate_healing().
// FIXME: Try moving this to unit::new_turn, then move it above calculate_healing().
void reset_resting(std::map<gamemap::location,unit>& units, unsigned int side);
//function which, given the location of a unit that is advancing, and the //function which, given the location of a unit that is advancing, and the
//name of the unit it is advancing to, will return the advanced version of //name of the unit it is advancing to, will return the advanced version of
//this unit. (with traits and items retained). //this unit. (with traits and items retained).

View file

@ -25,9 +25,7 @@ namespace game_config
int base_income = 2; int base_income = 2;
int village_income = 1; int village_income = 1;
int heal_amount = 4; int heal_amount = 4;
int healer_heals_per_turn = 8;
int cure_amount = 8; int cure_amount = 8;
int curer_heals_per_turn = 18;
int rest_heal_amount= 2; int rest_heal_amount= 2;
int recall_cost = 20; int recall_cost = 20;
int kill_experience = 8; int kill_experience = 8;
@ -100,9 +98,7 @@ namespace game_config
base_income = atoi(v["base_income"].c_str()); base_income = atoi(v["base_income"].c_str());
village_income = atoi(v["village_income"].c_str()); village_income = atoi(v["village_income"].c_str());
heal_amount = atoi(v["heal_amount"].c_str()); heal_amount = atoi(v["heal_amount"].c_str());
healer_heals_per_turn = atoi(v["healer_heals_per_turn"].c_str());
cure_amount = atoi(v["cure_amount"].c_str()); cure_amount = atoi(v["cure_amount"].c_str());
curer_heals_per_turn = atoi(v["curer_heals_per_turn"].c_str());
rest_heal_amount = atoi(v["rest_heal_amount"].c_str()); rest_heal_amount = atoi(v["rest_heal_amount"].c_str());
recall_cost = atoi(v["recall_cost"].c_str()); recall_cost = atoi(v["recall_cost"].c_str());
kill_experience = atoi(v["kill_experience"].c_str()); kill_experience = atoi(v["kill_experience"].c_str());

View file

@ -27,9 +27,7 @@ namespace game_config
extern int base_income; extern int base_income;
extern int village_income; extern int village_income;
extern int heal_amount; extern int heal_amount;
extern int healer_heals_per_turn;
extern int cure_amount; extern int cure_amount;
extern int curer_heals_per_turn;
extern int rest_heal_amount; extern int rest_heal_amount;
extern int recall_cost; extern int recall_cost;
extern int kill_experience; extern int kill_experience;

View file

@ -431,6 +431,7 @@ LEVEL_RESULT play_level(const game_data& gameinfo, const config& game_config,
} }
calculate_healing(gui,status,map,units,player_number,teams, !skip_replay); calculate_healing(gui,status,map,units,player_number,teams, !skip_replay);
reset_resting(units, player_number);
} }
team_it->set_time_of_day(int(status.turn()),status.get_time_of_day()); team_it->set_time_of_day(int(status.turn()),status.get_time_of_day());

View file

@ -434,6 +434,7 @@ void replay_controller::play_side(const int team_index){
} }
calculate_healing((*gui_),status_,map_,units_,player_number_,teams_, !recorder.is_skipping()); calculate_healing((*gui_),status_,map_,units_,player_number_,teams_, !recorder.is_skipping());
reset_resting(units_, player_number_);
} }
current_team.set_time_of_day(int(status_.turn()),status_.get_time_of_day()); current_team.set_time_of_day(int(status_.turn()),status_.get_time_of_day());

View file

@ -98,7 +98,6 @@ heals_ability::heals_ability(const config* cfg)
: ability(cfg) : ability(cfg)
{ {
amount_=lexical_cast_default<int>((*cfg)["amount"],game_config::healer_heals_per_turn); amount_=lexical_cast_default<int>((*cfg)["amount"],game_config::healer_heals_per_turn);
max_=lexical_cast_default<int>((*cfg)["max"],game_config::heal_amount);
} }
const int heals_ability::amount() const const int heals_ability::amount() const
@ -106,15 +105,9 @@ const int heals_ability::amount() const
return amount_; return amount_;
} }
const int heals_ability::max() const void heals_ability::set_heal(int amount)
{
return max_;
}
void heals_ability::set_heal(int amount, int max)
{ {
amount_=amount; amount_=amount;
max_=max;
} }
/// regenerates_ability /// /// regenerates_ability ///

View file

@ -46,11 +46,9 @@ class heals_ability : public ability
public : public :
heals_ability(const config* cfg); heals_ability(const config* cfg);
const int amount() const; const int amount() const;
const int max() const; void set_heal(int amount);
void set_heal(int amount, int max);
private : private :
int amount_; int amount_;
int max_;
}; };
class regenerates_ability : public ability class regenerates_ability : public ability

View file

@ -603,7 +603,7 @@ void ability_filter::add_filters(const config* cfg)
unit_type::unit_type(const unit_type& o) unit_type::unit_type(const unit_type& o)
: variations_(o.variations_), cfg_(o.cfg_), race_(o.race_), : variations_(o.variations_), cfg_(o.cfg_), race_(o.race_),
alpha_(o.alpha_), abilities_(o.abilities_),ability_tooltips_(o.ability_tooltips_), alpha_(o.alpha_), abilities_(o.abilities_),ability_tooltips_(o.ability_tooltips_),
heals_filter_(o.heals_filter_), max_heals_(o.max_heals_), heals_(o.heals_), heals_filter_(o.heals_filter_), heals_(o.heals_),
regenerates_filter_(o.regenerates_filter_),regenerates_(o.regenerates_), regenerates_filter_(o.regenerates_filter_),regenerates_(o.regenerates_),
regeneration_(o.regeneration_), regeneration_(o.regeneration_),
leadership_filter_(o.leadership_filter_), leadership_(o.leadership_), leadership_filter_(o.leadership_filter_), leadership_(o.leadership_),
@ -700,7 +700,6 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
possibleTraits_.insert(possibleTraits_.end(),unit_traits.begin(),unit_traits.end()); possibleTraits_.insert(possibleTraits_.end(),unit_traits.begin(),unit_traits.end());
heals_ = 0; heals_ = 0;
max_heals_ = 0;
regenerates_ = false; regenerates_ = false;
regeneration_ = 0; regeneration_ = 0;
steadfast_ = false; steadfast_ = false;
@ -725,15 +724,13 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
if(!deprecated_abilities.empty()) { if(!deprecated_abilities.empty()) {
LOG_STREAM(err, config) << "unit " << id() << " uses the ability=list tag, which is deprecated\n"; LOG_STREAM(err, config) << "unit " << id() << " uses the ability=list tag, which is deprecated\n";
if(std::find(deprecated_abilities.begin(),deprecated_abilities.end(),"heals") != deprecated_abilities.end()) { if(std::find(deprecated_abilities.begin(),deprecated_abilities.end(),"heals") != deprecated_abilities.end()) {
heals_ = game_config::healer_heals_per_turn; heals_ = game_config::heal_amount;
max_heals_ = game_config::heal_amount;
heals_filter_.unfilter(); heals_filter_.unfilter();
abilities_.push_back("heals"); abilities_.push_back("heals");
ability_tooltips_.push_back("heals"); ability_tooltips_.push_back("heals");
} }
if(std::find(deprecated_abilities.begin(),deprecated_abilities.end(),"cures") != deprecated_abilities.end()) { if(std::find(deprecated_abilities.begin(),deprecated_abilities.end(),"cures") != deprecated_abilities.end()) {
heals_ = game_config::curer_heals_per_turn; heals_ = game_config::cure_amount;
max_heals_ = game_config::cure_amount;
heals_filter_.unfilter(); heals_filter_.unfilter();
abilities_.push_back("cures"); abilities_.push_back("cures");
ability_tooltips_.push_back("cures"); ability_tooltips_.push_back("cures");
@ -804,8 +801,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
} else { } else {
ability_tooltips_.push_back("heals"); ability_tooltips_.push_back("heals");
} }
heals_ = maximum<int>(heals_, lexical_cast_default<int>((**ab)["amount"],game_config::healer_heals_per_turn)); heals_ = maximum<int>(heals_, lexical_cast_default<int>((**ab)["amount"],game_config::heal_amount));
max_heals_ = maximum<int>(max_heals_, lexical_cast_default<int>((**ab)["max"],game_config::heal_amount));
heals_filter_.add_filters((*ab)->child("filter")); heals_filter_.add_filters((*ab)->child("filter"));
} }
} }
@ -1285,11 +1281,6 @@ const std::vector<std::string>& unit_type::ability_tooltips() const
return ability_tooltips_; return ability_tooltips_;
} }
int unit_type::max_unit_healing() const
{
return max_heals_;
}
int unit_type::heals() const int unit_type::heals() const
{ {
return heals_; return heals_;

View file

@ -216,10 +216,6 @@ public:
const std::vector<std::string>& abilities() const; const std::vector<std::string>& abilities() const;
const std::vector<std::string>& ability_tooltips() const; const std::vector<std::string>& ability_tooltips() const;
//max_unit_healing returns the maximum hitpoints a unit next to this
//unit can heal per turn. heals returns the total amount of hitpoints
//this unit can heal out of all adjacent units
int max_unit_healing() const;
int heals() const; int heals() const;
bool regenerates() const; bool regenerates() const;
int regenerate_amount() const; int regenerate_amount() const;
@ -280,7 +276,6 @@ private:
mutable std::string id_; mutable std::string id_;
ability_filter heals_filter_; ability_filter heals_filter_;
int max_heals_;
int heals_; int heals_;
ability_filter regenerates_filter_; ability_filter regenerates_filter_;