Allow sharing of previous combatant status for AI.
Simplify average_hp() as pointed out by Decker2 (and return double). Correct cumulative calc of poisoned/slowed.
This commit is contained in:
parent
6877bfcc5d
commit
47e4ec7038
2 changed files with 30 additions and 16 deletions
|
@ -470,12 +470,23 @@ void prob_matrix::receive_blow_a(unsigned damage, unsigned slow_damage, double h
|
|||
|
||||
};
|
||||
|
||||
combatant::combatant(const battle_context::unit_stats &u)
|
||||
combatant::combatant(const battle_context::unit_stats &u, combatant *prev)
|
||||
: hp_dist(u.drains ? u.max_hp+1: u.hp+1),
|
||||
untouched(1.0), poisoned(u.is_poisoned ? 1.0 : 0.0), slowed(u.is_slowed ? 1.0 : 0.0),
|
||||
u_(u),
|
||||
hit_chances_(u.num_blows, u.chance_to_hit / 100.0)
|
||||
{
|
||||
// We inherit current state from previous combatant.
|
||||
if (prev) {
|
||||
summary[0] = prev->summary[0];
|
||||
summary[1] = prev->summary[1];
|
||||
poisoned = prev->poisoned;
|
||||
untouched = prev->untouched;
|
||||
slowed = prev->slowed;
|
||||
} else {
|
||||
untouched = 1.0;
|
||||
poisoned = u.is_poisoned ? 1.0 : 0.0;
|
||||
slowed = u.is_slowed ? 1.0 : 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// For swarm, whether we get an attack depends on HP distribution from
|
||||
|
@ -593,30 +604,33 @@ void combatant::fight(combatant &opp)
|
|||
opp.hp_dist[i] = opp.summary[0][i] + opp.summary[1][i];
|
||||
}
|
||||
|
||||
if (opp.u_.poisons && !u_.is_poisoned)
|
||||
poisoned += untouched - hp_dist[u_.hp];
|
||||
if (u_.poisons && !opp.u_.is_poisoned)
|
||||
opp.poisoned += opp.untouched - opp.hp_dist[opp.u_.hp];
|
||||
// Chance that we / they were touched this time.
|
||||
double touched = untouched - hp_dist[u_.hp];
|
||||
double opp_touched = opp.untouched - opp.hp_dist[opp.u_.hp];
|
||||
if (opp.u_.poisons)
|
||||
poisoned += (1 - poisoned) * touched;
|
||||
if (u_.poisons)
|
||||
opp.poisoned += (1 - opp.poisoned) * opp_touched;
|
||||
|
||||
if (opp.u_.slows && !u_.is_slowed)
|
||||
slowed += untouched - hp_dist[u_.hp];
|
||||
if (u_.slows && !opp.u_.is_slowed)
|
||||
opp.slowed += opp.untouched - opp.hp_dist[opp.u_.hp];
|
||||
if (opp.u_.slows)
|
||||
slowed += (1 - slowed) * touched;
|
||||
if (u_.slows)
|
||||
opp.slowed += (1 - opp.slowed) * opp_touched;
|
||||
|
||||
// FIXME: This is approximate: we could drain, then get hit.
|
||||
untouched = hp_dist[u_.hp];
|
||||
opp.untouched = opp.hp_dist[opp.u_.hp];
|
||||
}
|
||||
|
||||
unsigned int combatant::average_hp() const
|
||||
double combatant::average_hp() const
|
||||
{
|
||||
double total = 0, sum = 0;
|
||||
double total = 0;
|
||||
|
||||
// Since sum of probabilities is 1.0, we can just tally weights.
|
||||
for (unsigned int i = 0; i < hp_dist.size(); i++) {
|
||||
sum += hp_dist[i];
|
||||
total += hp_dist[i] * i;
|
||||
}
|
||||
return (unsigned int)((total / sum) + 0.5);
|
||||
return total;
|
||||
}
|
||||
|
||||
#if defined(BENCHMARK) || defined(CHECK)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
struct combatant
|
||||
{
|
||||
// Construct a combatant.
|
||||
combatant(const battle_context::unit_stats &u);
|
||||
combatant(const battle_context::unit_stats &u, combatant *prev = NULL);
|
||||
|
||||
// Simulate a fight! Can be called multiple times for cumulative calculations.
|
||||
void fight(combatant &opponent);
|
||||
|
@ -30,7 +30,7 @@ struct combatant
|
|||
double slowed;
|
||||
|
||||
// What's the average hp (weighted average of hp_dist).
|
||||
unsigned int average_hp() const;
|
||||
double average_hp() const;
|
||||
|
||||
private:
|
||||
// We must adjust for swarm after every combat.
|
||||
|
|
Loading…
Add table
Reference in a new issue