Skip to content

Commit

Permalink
Fix a possible recursion error involving [has_attack]
Browse files Browse the repository at this point in the history
I noticed that when using [has_attack], o does not necessarily track the attack used, and that if the unit checked does not use an attack, the recursion count does not work.
  • Loading branch information
newfrenchy83 committed Dec 17, 2024
1 parent f113b2b commit 22bf833
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
10 changes: 9 additions & 1 deletion src/units/abilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,7 @@ namespace { // Helpers for attack_type::special_active()


attack_type::recursion_guard filter_lock;
if (weapon && (filter_child->optional_child("has_attack") || filter_child->optional_child("filter_weapon"))) {
if (weapon && filter_child->optional_child("filter_weapon")) {
filter_lock = weapon->update_variables_recursion(filter);
if(!filter_lock) {
show_recursion_warning(weapon, filter);
Expand All @@ -1532,6 +1532,14 @@ namespace { // Helpers for attack_type::special_active()
return false;
}

unit::recursion_guard u_filter_lock;
if (filter_child->optional_child("has_attack")) {
u_filter_lock = u->update_variables_recursion(filter);
if(!u_filter_lock) {
show_recursion_warning(*u, filter);
return false;
}
}
// Passed.
// If the other unit doesn't exist, try matching without it
if (!u2) {
Expand Down
4 changes: 2 additions & 2 deletions src/units/unit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1870,8 +1870,6 @@ class unit : public std::enable_shared_from_this<unit>
bool ability_matches_filter(const config & cfg, const std::string& tag_name, const config & filter) const;


private:

/**
* Helper similar to std::unique_lock for detecting when calculations such as abilities
* have entered infinite recursion.
Expand Down Expand Up @@ -1910,6 +1908,8 @@ class unit : public std::enable_shared_from_this<unit>

recursion_guard update_variables_recursion(const config& ability) const;

private:

const std::set<std::string> checking_tags_{"disable", "attacks", "damage", "chance_to_hit", "berserk", "swarm", "drains", "heal_on_hit", "plague", "slow", "petrifies", "firststrike", "poison", "damage_type"};
/**
* Check if an ability is active. Includes checks to prevent excessive recursion.
Expand Down

0 comments on commit 22bf833

Please sign in to comment.