add 'ability_id_active' attribute to filter (#5739)

Add 'ability_id_active' attribute to filter

Until now, only the type of ability could be filtered with activity, and id only for unit who have ability, same if she's inactive.
This commit is contained in:
newfrenchy83 2021-05-03 21:38:05 +02:00 committed by GitHub
parent ad38010a03
commit 00452c0187
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 214 additions and 36 deletions

View file

@ -17,6 +17,7 @@
* The multiplayer "turns over" dialog now uses each team's colors when showing teams' names.
### WML Engine
* Modify implementation of overwrite_specials attribute for replace yes/no parameter by none/one_side/both_sides and select abilities used like weapons and specials who must be overwrited(owned by fighter where special applied or both)
* Add a 'ability_id_active' attribute to [filter]
### Miscellaneous and Bug Fixes
* More optimizations in the UI drawing code, these shouldn't have visible effects (PR #5681).
* Made GUI.pyw compatible with Python 3.9 (issue #5719).

View file

@ -10,6 +10,7 @@
{SIMPLE_KEY has_variation string_list}
{SIMPLE_KEY race string_list}
{SIMPLE_KEY ability_type string_list}
{SIMPLE_KEY ability_id_active string_list}
{SIMPLE_KEY ability_type_active string_list}
{SIMPLE_KEY ability string_list}
{SIMPLE_KEY trait string_list}

View file

@ -0,0 +1,138 @@
# wmllint: no translatables
{GENERIC_UNIT_TEST test_ability_id_active (
[event]
name=start
{VARIABLE triggers 0}
[object]
silent=yes
[filter]
id=alice
[/filter]
[effect]
apply_to=new_ability
[abilities]
[hides]
id=hides_test
[/hides]
[/abilities]
[/effect]
[/object]
[do_command]
[recruit]
type=Peasant
x,y=3,6
[from]
x,y=7,3
[/from]
[/recruit]
[/do_command]
[do_command]
[recruit]
type=Woodsman
x,y=15,8
[from]
x,y=7,3
[/from]
[/recruit]
[/do_command]
{RETURN ({VARIABLE_CONDITIONAL triggers equals 2})}
[/event]
[event]
name=recruit
[filter]
type=Peasant
[/filter]
{ASSERT (
[have_unit]
ability_id_active=hides_test
[/have_unit]
)}
{VARIABLE_OP triggers add 1}
[/event]
[event]
name=recruit
[filter]
type=Woodsman
[/filter]
{ASSERT (
[have_unit]
ability_id_active=hides_test
[/have_unit]
)}
{VARIABLE_OP triggers add 1}
[/event]
) (SIDE1_RECRUIT=Peasant,Woodsman)}
{GENERIC_UNIT_TEST test_ability_id_not_active (
[event]
name=start
{VARIABLE triggers 0}
[object]
silent=yes
[filter]
id=alice
[/filter]
[effect]
apply_to=new_ability
[abilities]
[hides]
id=hides_test
[filter]
[filter_location]
terrain=*^F*
[/filter_location]
[/filter]
[/hides]
[/abilities]
[/effect]
[/object]
[do_command]
[recruit]
type=Peasant
x,y=3,6
[from]
x,y=7,3
[/from]
[/recruit]
[/do_command]
[do_command]
[recruit]
type=Woodsman
x,y=15,8
[from]
x,y=7,3
[/from]
[/recruit]
[/do_command]
{RETURN ({VARIABLE_CONDITIONAL triggers equals 2})}
[/event]
[event]
name=recruit
[filter]
type=Peasant
[/filter]
{ASSERT (
[not]
[have_unit]
ability_id_active=hides_test
[/have_unit]
[/not]
)}
{VARIABLE_OP triggers add 1}
[/event]
[event]
name=recruit
[filter]
type=Woodsman
[/filter]
{ASSERT (
[not]
[have_unit]
ability_id_active=hides_test
[/have_unit]
[/not]
)}
{VARIABLE_OP triggers add 1}
[/event]
) (SIDE1_RECRUIT=Peasant,Woodsman)}

View file

@ -1,9 +1,5 @@
# This unit test defines a WML object based implementation of the "unupgradable" ability
# https://github.com/ProditorMagnus/Ageless-for-1-14/blob/52c1eaf31722bb58046a1b459d4f29daa8d88487/data/general_data/weapon_specials/unupgradable.cfg
# and checks that it works. What is being tested here is that
# [swarm] with swarm_attacks_max=swarm_attacks_min prevents strike changes
# - through [attacks]
# - through [effect] increase_attacks
# This unit test is used for verify the work of abilities used like weapons, but also of special_id_active attribute.
# Here, the teacher and student are the same unit
{GENERIC_UNIT_TEST "swarm_disables_upgrades_with_abilities" (
#define FILTER_BOB

View file

@ -1,9 +1,5 @@
# This unit test defines a WML object based implementation of the "unupgradable" ability
# https://github.com/ProditorMagnus/Ageless-for-1-14/blob/52c1eaf31722bb58046a1b459d4f29daa8d88487/data/general_data/weapon_specials/unupgradable.cfg
# and checks that it works. What is being tested here is that
# [swarm] with swarm_attacks_max=swarm_attacks_min prevents strike changes
# - through [attacks]
# - through [effect] increase_attacks
# This unit test is used for verify the work of abilities used like weapons, but also of special_id_active attribute.
# Here, the teacher and student are different units for verify what abilities was applied to adjacent units but also what special_id_active checking to student unit work.
{GENERIC_UNIT_TEST "swarm_disables_upgrades_with_abilities_adjacent" (
#define FILTER_BOB

View file

@ -1,9 +1,6 @@
# This unit test defines a WML object based implementation of the "unupgradable" ability
# https://github.com/ProditorMagnus/Ageless-for-1-14/blob/52c1eaf31722bb58046a1b459d4f29daa8d88487/data/general_data/weapon_specials/unupgradable.cfg
# and checks that it works. What is being tested here is that
# [swarm] with swarm_attacks_max=swarm_attacks_min prevents strike changes
# - through [attacks]
# - through [effect] increase_attacks
# This unit test is used for verify the work of abilities used like weapons, but also of special_id_active attribute.
# Here, the teacher and student are different units for verify what abilities was applied to adjacent units but also what special_id_active checking to student unit work,
# and what a without a weapon specials with id match special_id_active, then it will be a fail in work of ability filtered.
{GENERIC_UNIT_TEST "swarm_disables_upgrades_with_abilities_adjacent_fail" (
#define FILTER_BOB

View file

@ -1,9 +1,5 @@
# This unit test defines a WML object based implementation of the "unupgradable" ability
# https://github.com/ProditorMagnus/Ageless-for-1-14/blob/52c1eaf31722bb58046a1b459d4f29daa8d88487/data/general_data/weapon_specials/unupgradable.cfg
# and checks that it works. What is being tested here is that
# [swarm] with swarm_attacks_max=swarm_attacks_min prevents strike changes
# - through [attacks]
# - through [effect] increase_attacks
# This unit test is used for verify the work of abilities used like weapons, but also what leadership can be filtered by special_id_active attribute
# like weapons specials and abilities used like weapons.
{GENERIC_UNIT_TEST "swarm_disables_upgrades_with_abilities_adjacent_leadership" (
#define FILTER_BOB

View file

@ -1,9 +1,6 @@
# This unit test defines a WML object based implementation of the "unupgradable" ability
# https://github.com/ProditorMagnus/Ageless-for-1-14/blob/52c1eaf31722bb58046a1b459d4f29daa8d88487/data/general_data/weapon_specials/unupgradable.cfg
# and checks that it works. What is being tested here is that
# [swarm] with swarm_attacks_max=swarm_attacks_min prevents strike changes
# - through [attacks]
# - through [effect] increase_attacks
# This unit test is used for verify the work of abilities used like weapons, but also what leadership can be filtered by special_id_active attribute
# like weapons specials and abilities used like weapons. Here [leadership] id tested is different of name checked by special_id_active attribute
# and must be cause a fail.
{GENERIC_UNIT_TEST "swarm_disables_upgrades_with_abilities_adjacent_leadership_fail" (
#define FILTER_BOB

View file

@ -1,9 +1,5 @@
# This unit test defines a WML object based implementation of the "unupgradable" ability
# https://github.com/ProditorMagnus/Ageless-for-1-14/blob/52c1eaf31722bb58046a1b459d4f29daa8d88487/data/general_data/weapon_specials/unupgradable.cfg
# and checks that it works. What is being tested here is that
# [swarm] with swarm_attacks_max=swarm_attacks_min prevents strike changes
# - through [attacks]
# - through [effect] increase_attacks
# This unit test is used for verify the work of abilities used like weapons, but also of special_id_active attribute.
# Here, the teacher and student are the same unit, but id checked by special_id_active don't exist and must cause a fail.
{GENERIC_UNIT_TEST "swarm_disables_upgrades_with_abilities_fail" (
#define FILTER_BOB

View file

@ -16,6 +16,8 @@
#include "log.hpp"
#include "display.hpp"
#include "display_context.hpp"
#include "config.hpp"
#include "game_data.hpp"
#include "map/map.hpp"
@ -288,6 +290,26 @@ void unit_filter_compound::create_attribute(const config::attribute_value v, C c
}
}
namespace {
struct ability_match
{
std::string tag_name;
const config* cfg;
};
void get_ability_children_id(std::vector<ability_match>& id_result,
const config& parent, const std::string& id) {
for (const config::any_child &sp : parent.all_children_range())
{
if(sp.cfg["id"] == id) {
ability_match special = { sp.key, &sp.cfg };
id_result.push_back(special);
}
}
}
}
void unit_filter_compound::fill(vconfig cfg)
{
const config& literal = cfg.get_config();
@ -386,6 +408,42 @@ void unit_filter_compound::fill(vconfig cfg)
}
);
create_attribute(literal["ability_id_active"],
[](const config::attribute_value& c) { return utils::split(c.str()); },
[](const std::vector<std::string>& abilities, const unit_filter_args& args)
{
assert(display::get_singleton());
const unit_map& units = display::get_singleton()->get_units();
for(const std::string& ability : abilities) {
std::vector<ability_match> ability_id_matches_self;
get_ability_children_id(ability_id_matches_self, args.u.abilities(), ability);
for(const ability_match& entry : ability_id_matches_self) {
if (args.u.get_self_ability_bool(*entry.cfg, entry.tag_name, args.loc)) {
return true;
}
}
const auto adjacent = get_adjacent_tiles(args.loc);
for(unsigned i = 0; i < adjacent.size(); ++i) {
const unit_map::const_iterator it = units.find(adjacent[i]);
if (it == units.end() || it->incapacitated())
continue;
if (&*it == (args.u.shared_from_this()).get())
continue;
std::vector<ability_match> ability_id_matches_adj;
get_ability_children_id(ability_id_matches_adj, it->abilities(), ability);
for(const ability_match& entry : ability_id_matches_adj) {
if (args.u.get_adj_ability_bool(*entry.cfg, entry.tag_name,i, args.loc, *it)) {
return true;
}
}
}
}
return false;
}
);
create_attribute(literal["ability_type_active"],
[](const config::attribute_value& c) { return utils::split(c.str()); },
[](const std::vector<std::string>& abilities, const unit_filter_args& args)

View file

@ -126,6 +126,8 @@
0 event_test_filter_condition
0 event_test_filter_side
0 event_test_filter_unit
0 test_ability_id_active
0 test_ability_id_not_active
0 event_test_filter_attack
0 filter_vision
0 scatter_units