Shift some attack and damage calculations to the attack_type class.

This is in anticipation of them being useful (later) in reports.
This commit is contained in:
J. Tyne 2012-10-20 03:23:19 +00:00
parent ba26f76429
commit 243746934a
3 changed files with 49 additions and 27 deletions

View file

@ -142,22 +142,16 @@ battle_context_unit_stats::battle_context_unit_stats(const unit &u,
chance_to_hit = cth_effects.get_composite_value();
// Compute base damage done with the weapon.
int base_damage = weapon->damage();
unit_ability_list dmg_specials = weapon->get_specials("damage");
unit_abilities::effect dmg_effect(dmg_specials, base_damage, backstab_pos);
base_damage = dmg_effect.get_composite_value();
int base_damage = weapon->modified_damage(backstab_pos);
// Get the damage multiplier applied to the base damage of the weapon.
int damage_multiplier = 100;
// Time of day bonus.
damage_multiplier += combat_modifier(u_loc, u.alignment(), u.is_fearless());
// Leadership bonus.
int leader_bonus = 0;
if (under_leadership(units, u_loc, &leader_bonus).valid())
damage_multiplier += leader_bonus;
// Resistance modifier.
damage_multiplier *= opp.damage_from(*weapon, !attacking, opp_loc);
@ -184,26 +178,9 @@ battle_context_unit_stats::battle_context_unit_stats(const unit &u,
drains = drain_constant || drain_percent;
// Compute the number of blows and handle swarm.
unit_ability_list swarm_specials = weapon->get_specials("swarm");
num_blows = weapon->num_attacks();
unit_ability_list attacks_specials = weapon->get_specials("attacks");
unit_abilities::effect attacks_effect(attacks_specials,num_blows,backstab_pos);
const int num_blows_with_specials = attacks_effect.get_composite_value();
if(num_blows_with_specials >= 0) {
num_blows = num_blows_with_specials;
}
else { ERR_NG << "negative number of strikes after applying weapon specials\n"; }
if (!swarm_specials.empty()) {
swarm = true;
swarm_min = swarm_specials.highest("swarm_attacks_min").first;
swarm_max = swarm_specials.highest("swarm_attacks_max", num_blows).first;
num_blows = calc_blows(hp);
} else {
swarm = false;
swarm_min = num_blows;
swarm_max = num_blows;
}
weapon->modified_attacks(backstab_pos, swarm_min, swarm_max);
swarm = swarm_min != swarm_max;
num_blows = calc_blows(hp);
}
}

View file

@ -633,6 +633,45 @@ void attack_type::set_specials_context(const map_location& loc, bool attacking)
}
/**
* Calculates the number of attacks this weapon has, considering specials.
* This returns two numbers because of the swarm special. The actual number of
* attacks depends on the unit's health and should be:
* min_attacks + (max_attacks - min_attacks) * (current hp) / (max hp)
*/
void attack_type::modified_attacks(bool is_backstab, unsigned & min_attacks,
unsigned & max_attacks) const
{
// Apply [attacks].
unit_abilities::effect attacks_effect(get_specials("attacks"),
num_attacks(), is_backstab);
int attacks_value = attacks_effect.get_composite_value();
if ( attacks_value < 0 ) {
attacks_value = num_attacks();
ERR_NG << "negative number of strikes after applying weapon specials\n";
}
// Apply [swarm].
unit_ability_list swarm_specials = get_specials("swarm");
if ( !swarm_specials.empty() ) {
min_attacks = std::max<int>(0, swarm_specials.highest("swarm_attacks_min").first);
max_attacks = std::max<int>(0, swarm_specials.highest("swarm_attacks_max", attacks_value).first);
} else {
min_attacks = max_attacks = attacks_value;
}
}
/**
* Returns the damage per attack of this weapon, considering specials.
*/
int attack_type::modified_damage(bool is_backstab) const
{
unit_abilities::effect dmg_effect(get_specials("damage"), damage(), is_backstab);
return dmg_effect.get_composite_value();
}
namespace { // Helpers for attack_type::special_active()
/**

View file

@ -58,6 +58,12 @@ public:
bool attacking, const attack_type *other_attack) const;
void set_specials_context(const map_location& loc, bool attacking = true) const;
/// Calculates the number of attacks this weapon has, considering specials.
void modified_attacks(bool is_backstab, unsigned & min_attacks,
unsigned & max_attacks) const;
/// Returns the damage per attack of this weapon, considering specials.
int modified_damage(bool is_backstab) const;
// In unit_types.cpp:
bool matches_filter(const config& filter) const;