Change the alignment code in attack to return an optional value and avoid falling back to neutral alignment when unit alignment is not available.

This commit is contained in:
newfrenchy83 2024-10-13 18:20:43 +02:00 committed by Charles Dang
parent a1cadb54e5
commit 174be0f8c4
6 changed files with 11 additions and 20 deletions

View file

@ -187,8 +187,9 @@ battle_context_unit_stats::battle_context_unit_stats(nonempty_unit_const_ptr up,
int damage_multiplier = 100;
// Time of day bonus.
unit_alignments::type alignment = weapon->alignment().value_or(u.alignment());
damage_multiplier += combat_modifier(
resources::gameboard->units(), resources::gameboard->map(), u_loc, weapon->alignment(), u.is_fearless());
resources::gameboard->units(), resources::gameboard->map(), u_loc, alignment, u.is_fearless());
// Leadership bonus.
int leader_bonus = under_leadership(u, u_loc, weapon, opp_weapon);
@ -316,8 +317,9 @@ battle_context_unit_stats::battle_context_unit_stats(const unit_type* u_type,
int base_damage = weapon->modified_damage();
int damage_multiplier = 100;
unit_alignments::type alignment = weapon->alignment().value_or(u_type->alignment());
damage_multiplier
+= generic_combat_modifier(lawful_bonus, weapon->alignment(), u_type->musthave_status("fearless"), 0);
+= generic_combat_modifier(lawful_bonus, alignment, u_type->musthave_status("fearless"), 0);
damage_multiplier *= opp_type->resistance_against(weapon->type(), !attacking);
damage = round_damage(base_damage, damage_multiplier, 10000);

View file

@ -227,8 +227,9 @@ void attack_predictions::set_data(const combatant_data& attacker, const combatan
// Time of day modifier.
const unit& u = *attacker.unit_;
unit_alignments::type alignment = weapon->alignment().value_or(u.alignment());
const int tod_modifier = combat_modifier(resources::gameboard->units(), resources::gameboard->map(),
u.get_location(), weapon->alignment(), u.is_fearless());
u.get_location(), alignment, u.is_fearless());
if(tod_modifier != 0) {
set_label_helper("tod_modifier", utils::signed_percent(tod_modifier));

View file

@ -780,7 +780,7 @@ static int attack_info(const reports::context& rc, const attack_type &at, config
int specials_damage = at.modified_damage();
int damage_multiplier = 100;
const_attack_ptr weapon = at.shared_from_this();
unit_alignments::type attack_alignment = weapon->alignment();
unit_alignments::type attack_alignment = weapon->alignment().value_or(u.alignment());
int tod_bonus = combat_modifier(get_visible_time_of_day_at(rc, hex), attack_alignment, u.is_fearless());
damage_multiplier += tod_bonus;
int leader_bonus = under_leadership(u, hex, weapon);

View file

@ -188,7 +188,6 @@ static int impl_unit_attacks_set(lua_State* L)
if(iter == end) {
atk = u.add_attack(end, cfg);
} else {
auto ctx = atk->specials_context(u.shared_from_this(), map_location::null_location(), true);
iter.base()->reset(new attack_type(cfg));
atk = *iter.base();
}

View file

@ -59,7 +59,7 @@ attack_type::attack_type(const config& cfg) :
range_(cfg["range"]),
min_range_(cfg["min_range"].to_int(1)),
max_range_(cfg["max_range"].to_int(1)),
alignment_str_(),
alignment_str_(cfg["alignment"].str()),
damage_(cfg["damage"].to_int()),
num_attacks_(cfg["number"].to_int()),
attack_weight_(cfg["attack_weight"].to_double(1.0)),
@ -80,17 +80,6 @@ attack_type::attack_type(const config& cfg) :
else
icon_ = "attacks/blank-attack.png";
}
if(cfg.has_attribute("alignment") && (cfg["alignment"] == "neutral" || cfg["alignment"] == "lawful" || cfg["alignment"] == "chaotic" || cfg["alignment"] == "liminal")){
alignment_str_ = cfg["alignment"].str();
} else if(self_){
alignment_str_ =unit_alignments::get_string(self_->alignment());
}
}
unit_alignments::type attack_type::alignment() const
{
// pick attack alignment or fall back to unit alignment
return (unit_alignments::get_enum(alignment_str_).value_or(self_ ? self_->alignment() : unit_alignments::type::neutral));
}
std::string attack_type::accuracy_parry_description() const

View file

@ -89,10 +89,10 @@ public:
/** Returns alignment specified by alignment_str_ variable If empty or not valid returns the unit's alignment or neutral if self_ variable empty.
*/
unit_alignments::type alignment() const;
/** Returns alignment specified by alignment() for filtering.
utils::optional<unit_alignments::type> alignment() const {return unit_alignments::get_enum(alignment_str_);}
/** Returns alignment specified by alignment() for filtering when exist.
*/
std::string alignment_str() const {return unit_alignments::get_string(alignment());}
std::string alignment_str() const {return (alignment() ? unit_alignments::get_string(*alignment()) : "");}
/** Calculates the number of attacks this weapon has, considering specials. */
void modified_attacks(unsigned & min_attacks,