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:
parent
8fdcfa7358
commit
01751ea84e
14 changed files with 183 additions and 352 deletions
37
MANUAL
37
MANUAL
|
@ -226,35 +226,20 @@ HEALING
|
|||
Injured units in villages will recover 8 hitpoints every turn. Injured
|
||||
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
|
||||
'resting' and will recover 2 hitpoints. Hitpoints recovered through
|
||||
'resting' are added on top of hitpoints recovered through healing or
|
||||
regenerating.
|
||||
'resting' and will recover an additional 2 hitpoints.
|
||||
|
||||
A unit with the 'heals' ability may heal up to 8 hitpoints total per
|
||||
turn. A unit with the 'cures' ability may heal up to 18 hitpoints total
|
||||
per turn.
|
||||
A unit with the 'heals' ability will heal adjacent allied units by up
|
||||
to 4 hitpoints each, at the beginning of the healer's turn. Poisoned
|
||||
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
|
||||
4 hitpoints per turn; units next to unit(s) with the 'cures' ability
|
||||
will recover a maximum of 8 hitpoints per turn. The more units around a
|
||||
unit that can heal, the less each one will be healed.
|
||||
A unit with the 'cures' ability will heal adjacent allied units by up
|
||||
to 8 hitpoints each, at the beginning of the curer's turn. Poisoned
|
||||
units will have their poison cured by healer, instead.
|
||||
|
||||
An example of 'heals' with multiple adjacent units:
|
||||
|
||||
Two units next to a 'healer' will receive 4 hitpoints each.
|
||||
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
For more information see the in-game help.
|
||||
|
||||
|
|
|
@ -25,9 +25,8 @@ ability_ambush= _ "ambush"
|
|||
cures_description= _ "Cures:
|
||||
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.
|
||||
A unit cared for by a curer may heal up to 8 HP per turn.
|
||||
A curer may heal a total of 18 HP per turn, for all units it cares for.
|
||||
This unit will care for all adjacent friendly units that are injured at the beginning of its turn.
|
||||
Each non-poisoned unit cared for by a curer will heal by up to 8 HP per turn.
|
||||
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"
|
||||
|
@ -35,9 +34,9 @@ ability_cures= _ "cures"
|
|||
heals_description= _ "Heals:
|
||||
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.
|
||||
A healer may heal a total of 8 HP per turn, for all units it cares for.
|
||||
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."
|
||||
This unit will care for all adjacent friendly units that are injured at the beginning of its turn.
|
||||
Each non-poisoned unit cared for by a healer will heal up to 4 HP per turn.
|
||||
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"
|
||||
|
||||
|
|
|
@ -44,9 +44,7 @@ default=yes
|
|||
base_income=2
|
||||
village_income=1
|
||||
heal_amount=4
|
||||
healer_heals_per_turn=8
|
||||
cure_amount=8
|
||||
curer_heals_per_turn=18
|
||||
rest_heal_amount=2
|
||||
recall_cost=20
|
||||
kill_experience=8
|
||||
|
|
|
@ -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." + _"
|
||||
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." + _"
|
||||
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." + _"
|
||||
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." + _"
|
||||
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 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]
|
||||
|
|
420
src/actions.cpp
420
src/actions.cpp
|
@ -1384,317 +1384,189 @@ unit_map::const_iterator find_leader(const unit_map& units, int side)
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
//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)
|
||||
struct patient
|
||||
{
|
||||
const unit_map::const_iterator healer_it = units.find(loc);
|
||||
if(healer_it == units.end() || healer_it->second.type().heals() == false) {
|
||||
return false;
|
||||
patient(unit &un, bool allied)
|
||||
: u(un), healing(0), poison_stopped(false), ally(allied) { }
|
||||
|
||||
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;
|
||||
|
||||
if(healer.incapacitated()) {
|
||||
return false;
|
||||
void patient::harm(int amount)
|
||||
{
|
||||
if (ally)
|
||||
return;
|
||||
wassert(!healing && !poison_stopped);
|
||||
healing = -minimum(u.hitpoints() - 1, amount);
|
||||
}
|
||||
|
||||
if((int)healer.side() == side) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
void patient::rest()
|
||||
{
|
||||
if (ally)
|
||||
return;
|
||||
healing += minimum(u.max_hitpoints() - (u.hitpoints() + healing), game_config::rest_heal_amount);
|
||||
std::cerr << "resting by " << lexical_cast<std::string>(minimum(u.max_hitpoints() - (u.hitpoints() + healing), game_config::rest_heal_amount)) << "\n";
|
||||
}
|
||||
|
||||
// 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];
|
||||
unit_map::iterator healer = units.end();
|
||||
|
||||
get_adjacent_tiles(loc, adjacent);
|
||||
for(int n = 0; n != 6; ++n) {
|
||||
const unit_map::const_iterator u = units.find(adjacent[n]);
|
||||
if(u != units.end() && (u->second.hitpoints() < u->second.max_hitpoints() || u->second.poisoned())) {
|
||||
//ignore stoned units
|
||||
if(!u->second.healable())
|
||||
for (unsigned int n = 0; n != 6U; ++n) {
|
||||
unit_map::iterator i = units.find(adjacent[n]);
|
||||
if (i != units.end()) {
|
||||
if (i->second.incapacitated())
|
||||
continue;
|
||||
|
||||
const int unit_side = u->second.side();
|
||||
|
||||
//the healer won't heal an ally if there is a wounded unit on the same
|
||||
//side next to her
|
||||
if(unit_side == (int)healer.side())
|
||||
return false;
|
||||
|
||||
//choose an arbitrary order for healing
|
||||
if(unit_side > side)
|
||||
return false;
|
||||
if (i->second.side() != side)
|
||||
continue;
|
||||
if (!i->second.type().heals())
|
||||
continue;
|
||||
if (healer == units.end() || i->second.type().heals() > healer->second.type().heals())
|
||||
healer = i;
|
||||
}
|
||||
}
|
||||
return healer;
|
||||
}
|
||||
}
|
||||
|
||||
//there's no-one of higher priority nearby, so the ally will heal
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void calculate_healing(display& disp, const gamestatus& status, const gamemap& map,
|
||||
std::map<gamemap::location,unit>& units, int side,
|
||||
const std::vector<team>& teams, bool update_display)
|
||||
void reset_resting(std::map<gamemap::location,unit>& units, unsigned int side)
|
||||
{
|
||||
std::map<gamemap::location,int> healed_units, max_healing;
|
||||
|
||||
//a map of healed units to their healers
|
||||
std::multimap<gamemap::location,gamemap::location> healers;
|
||||
|
||||
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())
|
||||
continue;
|
||||
|
||||
//the unit heals if it's on this side, and it's on a village or
|
||||
//it has regeneration, and it is wounded
|
||||
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(amount_healed == 0) {
|
||||
int max_heal = 0;
|
||||
gamemap::location adjacent[6];
|
||||
get_adjacent_tiles(i->first,adjacent);
|
||||
for(int j = 0; j != 6; ++j) {
|
||||
if(will_heal(adjacent[j],i->second.side(),teams,units)) {
|
||||
const unit_map::const_iterator healer = units.find(adjacent[j]);
|
||||
max_heal = maximum(max_heal,healer->second.type().heals());
|
||||
|
||||
healers.insert(std::pair<gamemap::location,gamemap::location>(i->first,adjacent[j]));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
const int healing_per_unit = i->second.type().max_unit_healing()/nhealed;
|
||||
|
||||
for(j = 0; j != 6; ++j) {
|
||||
if(!gets_healed[j])
|
||||
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
|
||||
//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));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unit_map::iterator i = units.begin(); i != units.end(); ++i) {
|
||||
if (i->second.side() == side)
|
||||
i->second.set_resting(true);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::map<gamemap::location,int>::iterator h = healed_units.begin();
|
||||
h != healed_units.end(); ++h) {
|
||||
// Simple algorithm: no maximum number of patients per healer.
|
||||
void calculate_healing(display& disp, const gamestatus& status, const gamemap& map,
|
||||
std::map<gamemap::location,unit>& units, unsigned int side,
|
||||
const std::vector<team>& teams, bool update_display)
|
||||
{
|
||||
// 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) {
|
||||
if (teams[i->second.side()-1].is_enemy(side))
|
||||
continue;
|
||||
|
||||
const gamemap::location& loc = h->first;
|
||||
if (!i->second.healable())
|
||||
continue;
|
||||
|
||||
wassert(units.count(loc) == 1);
|
||||
patient p(i->second, i->second.side() != side);
|
||||
unit_map::iterator healer = units.end();
|
||||
|
||||
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;
|
||||
if(show_healing) {
|
||||
disp.scroll_to_tile(loc.x,loc.y,display::ONSCREEN);
|
||||
disp.select_hex(loc);
|
||||
|
||||
|
||||
//iterate over any units that are healing this unit, and make them
|
||||
//enter their healing frame
|
||||
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.u.type().regenerates())
|
||||
p.heal(p.u.type().regenerate_amount(), false);
|
||||
else if (map.gives_healing(i->first))
|
||||
p.heal(game_config::cure_amount, false);
|
||||
else {
|
||||
healer = find_healer(i->first, units, side);
|
||||
if (healer != units.end())
|
||||
p.heal(healer->second.type().heals(), true);
|
||||
}
|
||||
if (p.u.poisoned() && !p.poison_stopped)
|
||||
p.harm(game_config::cure_amount);
|
||||
if (p.u.is_resting())
|
||||
p.rest();
|
||||
|
||||
if (!p.healing && !p.poison_stopped)
|
||||
continue;
|
||||
|
||||
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)
|
||||
if (disp.turbo() || recorder.is_skipping()
|
||||
|| disp.fogged(i->first.x, i->first.y)
|
||||
|| !update_display
|
||||
|| (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;
|
||||
}
|
||||
|
||||
if(h->second < 0) {
|
||||
if(show_healing) {
|
||||
// This is all the pretty stuff.
|
||||
int start_time = 0;
|
||||
disp.scroll_to_tile(i->first.x, i->first.y, display::ONSCREEN);
|
||||
disp.select_hex(i->first);
|
||||
|
||||
if (healer != units.end()) {
|
||||
healer->second.set_healing(disp);
|
||||
start_time = healer->second.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());
|
||||
sound::play_sound("groan.wav");
|
||||
disp.float_label(h->first,lexical_cast<std::string>(h->second*-1),255,0,0);
|
||||
}
|
||||
} else if(h->second > 0) {
|
||||
if(show_healing) {
|
||||
disp.float_label(i->first, lexical_cast<std::string>(-p.healing), 255,0,0);
|
||||
} else {
|
||||
p.u.set_healed(disp, p.healing);
|
||||
start_time = minimum<int>(start_time, p.u.get_animation()->get_first_frame_time());
|
||||
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) {
|
||||
u.set_healed(disp,h->second);
|
||||
start_time = minimum<int>(start_time,u.get_animation()->get_first_frame_time());
|
||||
bool finished;
|
||||
do {
|
||||
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) {
|
||||
u.set_poisoned(disp,-h->second);
|
||||
start_time = minimum<int>(start_time,u.get_animation()->get_first_frame_time());
|
||||
if (p.healing > 0) {
|
||||
p.u.heal(1);
|
||||
--p.healing;
|
||||
} else if (p.healing < 0) {
|
||||
p.u.gets_hit(1);
|
||||
++p.healing;
|
||||
}
|
||||
//std::vector<unit*>::iterator itor;
|
||||
// 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);
|
||||
finished &= (!p.healing);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
if(!disp.turbo()) SDL_Delay(10);
|
||||
SDL_Delay(10);
|
||||
} while (!finished);
|
||||
|
||||
}
|
||||
u.set_standing(disp);
|
||||
for(healer_itor i = healer_itors.first; i != healer_itors.second; ++i) {
|
||||
unit& healer = units.find(i->second)->second;
|
||||
healer.set_standing(disp);
|
||||
}
|
||||
p.u.set_standing(disp);
|
||||
if (healer != units.end())
|
||||
healer->second.set_standing(disp);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//at the beginning of a side's turn.
|
||||
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);
|
||||
|
||||
// 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
|
||||
//name of the unit it is advancing to, will return the advanced version of
|
||||
//this unit. (with traits and items retained).
|
||||
|
|
|
@ -25,9 +25,7 @@ namespace game_config
|
|||
int base_income = 2;
|
||||
int village_income = 1;
|
||||
int heal_amount = 4;
|
||||
int healer_heals_per_turn = 8;
|
||||
int cure_amount = 8;
|
||||
int curer_heals_per_turn = 18;
|
||||
int rest_heal_amount= 2;
|
||||
int recall_cost = 20;
|
||||
int kill_experience = 8;
|
||||
|
@ -100,9 +98,7 @@ namespace game_config
|
|||
base_income = atoi(v["base_income"].c_str());
|
||||
village_income = atoi(v["village_income"].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());
|
||||
curer_heals_per_turn = atoi(v["curer_heals_per_turn"].c_str());
|
||||
rest_heal_amount = atoi(v["rest_heal_amount"].c_str());
|
||||
recall_cost = atoi(v["recall_cost"].c_str());
|
||||
kill_experience = atoi(v["kill_experience"].c_str());
|
||||
|
|
|
@ -27,9 +27,7 @@ namespace game_config
|
|||
extern int base_income;
|
||||
extern int village_income;
|
||||
extern int heal_amount;
|
||||
extern int healer_heals_per_turn;
|
||||
extern int cure_amount;
|
||||
extern int curer_heals_per_turn;
|
||||
extern int rest_heal_amount;
|
||||
extern int recall_cost;
|
||||
extern int kill_experience;
|
||||
|
|
|
@ -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);
|
||||
reset_resting(units, player_number);
|
||||
}
|
||||
|
||||
team_it->set_time_of_day(int(status.turn()),status.get_time_of_day());
|
||||
|
|
|
@ -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());
|
||||
reset_resting(units_, player_number_);
|
||||
}
|
||||
|
||||
current_team.set_time_of_day(int(status_.turn()),status_.get_time_of_day());
|
||||
|
|
|
@ -98,7 +98,6 @@ heals_ability::heals_ability(const config* cfg)
|
|||
: ability(cfg)
|
||||
{
|
||||
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
|
||||
|
@ -106,15 +105,9 @@ const int heals_ability::amount() const
|
|||
return amount_;
|
||||
}
|
||||
|
||||
const int heals_ability::max() const
|
||||
{
|
||||
return max_;
|
||||
}
|
||||
|
||||
void heals_ability::set_heal(int amount, int max)
|
||||
void heals_ability::set_heal(int amount)
|
||||
{
|
||||
amount_=amount;
|
||||
max_=max;
|
||||
}
|
||||
|
||||
/// regenerates_ability ///
|
||||
|
|
|
@ -46,11 +46,9 @@ class heals_ability : public ability
|
|||
public :
|
||||
heals_ability(const config* cfg);
|
||||
const int amount() const;
|
||||
const int max() const;
|
||||
void set_heal(int amount, int max);
|
||||
void set_heal(int amount);
|
||||
private :
|
||||
int amount_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
class regenerates_ability : public ability
|
||||
|
|
|
@ -603,7 +603,7 @@ void ability_filter::add_filters(const config* cfg)
|
|||
unit_type::unit_type(const unit_type& o)
|
||||
: variations_(o.variations_), cfg_(o.cfg_), race_(o.race_),
|
||||
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_),
|
||||
regeneration_(o.regeneration_),
|
||||
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());
|
||||
|
||||
heals_ = 0;
|
||||
max_heals_ = 0;
|
||||
regenerates_ = false;
|
||||
regeneration_ = 0;
|
||||
steadfast_ = false;
|
||||
|
@ -725,15 +724,13 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
if(!deprecated_abilities.empty()) {
|
||||
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()) {
|
||||
heals_ = game_config::healer_heals_per_turn;
|
||||
max_heals_ = game_config::heal_amount;
|
||||
heals_ = game_config::heal_amount;
|
||||
heals_filter_.unfilter();
|
||||
abilities_.push_back("heals");
|
||||
ability_tooltips_.push_back("heals");
|
||||
}
|
||||
if(std::find(deprecated_abilities.begin(),deprecated_abilities.end(),"cures") != deprecated_abilities.end()) {
|
||||
heals_ = game_config::curer_heals_per_turn;
|
||||
max_heals_ = game_config::cure_amount;
|
||||
heals_ = game_config::cure_amount;
|
||||
heals_filter_.unfilter();
|
||||
abilities_.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 {
|
||||
ability_tooltips_.push_back("heals");
|
||||
}
|
||||
heals_ = maximum<int>(heals_, lexical_cast_default<int>((**ab)["amount"],game_config::healer_heals_per_turn));
|
||||
max_heals_ = maximum<int>(max_heals_, lexical_cast_default<int>((**ab)["max"],game_config::heal_amount));
|
||||
heals_ = maximum<int>(heals_, lexical_cast_default<int>((**ab)["amount"],game_config::heal_amount));
|
||||
heals_filter_.add_filters((*ab)->child("filter"));
|
||||
}
|
||||
}
|
||||
|
@ -1285,11 +1281,6 @@ const std::vector<std::string>& unit_type::ability_tooltips() const
|
|||
return ability_tooltips_;
|
||||
}
|
||||
|
||||
int unit_type::max_unit_healing() const
|
||||
{
|
||||
return max_heals_;
|
||||
}
|
||||
|
||||
int unit_type::heals() const
|
||||
{
|
||||
return heals_;
|
||||
|
|
|
@ -216,10 +216,6 @@ public:
|
|||
const std::vector<std::string>& abilities() 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;
|
||||
bool regenerates() const;
|
||||
int regenerate_amount() const;
|
||||
|
@ -280,7 +276,6 @@ private:
|
|||
mutable std::string id_;
|
||||
|
||||
ability_filter heals_filter_;
|
||||
int max_heals_;
|
||||
int heals_;
|
||||
|
||||
ability_filter regenerates_filter_;
|
||||
|
|
Loading…
Add table
Reference in a new issue