From 29608d16ae5894d2b591d60a148d2d9893d1475c Mon Sep 17 00:00:00 2001 From: newfrenchy83 Date: Tue, 17 Dec 2024 11:37:33 +0100 Subject: [PATCH] Fix a possible recursion error involving [has_attack] 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. --- src/units/abilities.cpp | 9 ++++++++- src/units/unit.hpp | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/units/abilities.cpp b/src/units/abilities.cpp index 8daa9abde39e1..c16fcba12251d 100644 --- a/src/units/abilities.cpp +++ b/src/units/abilities.cpp @@ -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); @@ -1532,6 +1532,13 @@ namespace { // Helpers for attack_type::special_active() return false; } + unit::recursion_guard u_filter_lock = u->update_variables_recursion(cfg); + if (filter_child->optional_child("has_attack")) { + 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) { diff --git a/src/units/unit.hpp b/src/units/unit.hpp index 394155d91a062..4880c2e8228c1 100644 --- a/src/units/unit.hpp +++ b/src/units/unit.hpp @@ -1870,7 +1870,6 @@ class unit : public std::enable_shared_from_this 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 @@ -1910,6 +1909,8 @@ class unit : public std::enable_shared_from_this recursion_guard update_variables_recursion(const config& ability) const; +private: + const std::set 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.