mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-12 18:20:57 +00:00
Fix “filter_adjacent_location” not working in ability (#9079)
This commit is contained in:
parent
fd9d9fa35e
commit
cee370683d
|
@ -5,6 +5,8 @@
|
|||
max=infinite
|
||||
super="units/unit_type/abilities/~generic~,units/unit_type/attack/specials/" + {NAME}
|
||||
{FILTER_TAG "filter_student" unit {FILTER_TAG "filter_weapon" weapon ()}}
|
||||
{FILTER_TAG "filter_adjacent_student" adjacent ()}
|
||||
{FILTER_TAG "filter_adjacent_student_location" adjacent_location ()}
|
||||
[/tag]
|
||||
#enddef
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if one adjacent unit is bob.
|
||||
# Test whether the ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX should be active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_active" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if one of the adjacents units is bob"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent]
|
||||
adjacent=n,ne,se,s,sw,nw
|
||||
count=1-6
|
||||
id=bob
|
||||
[/filter_adjacent]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,48 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if one adjacent unit is bob, and bob is in correct location.
|
||||
# Test whether the ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX should be active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_direction_active" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if one of the adjacents units is bob, and bob is in correct location"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent]
|
||||
adjacent=se,s,sw
|
||||
id=bob
|
||||
[/filter_adjacent]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,50 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if one adjacent unit is bob, and bob is in correct location.
|
||||
# Test whether the ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX shouldn't be active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_direction_inactive" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if one of the adjacents units is bob, and bob is in correct location"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent]
|
||||
adjacent=n,ne,nw
|
||||
id=bob
|
||||
[/filter_adjacent]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[not]
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
[/not]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,51 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if one adjacent unit is Loki.
|
||||
# Test whether the ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX shouldn't be active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_inactive" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if one of the adjacents units is Loki"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent]
|
||||
adjacent=n,ne,se,s,sw,nw
|
||||
count=1-6
|
||||
id=Loki
|
||||
[/filter_adjacent]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[not]
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
[/not]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,49 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent_location]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if exactly three of adjacents terrains are Gg.
|
||||
# Test whether the ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX should be active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_location_count_three_active" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if 3 terrains hexes are Gg"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent_location]
|
||||
adjacent=n,ne,se,s,sw,nw
|
||||
count=3
|
||||
terrain=Gg
|
||||
[/filter_adjacent_location]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,49 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent_location]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if zero of the adjacent terrains are Ww.
|
||||
# Test whether the ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX should be active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_location_count_zero_active" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if 0 terrains hexes are Ww"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent_location]
|
||||
adjacent=n,ne,se,s,sw,nw
|
||||
count=0
|
||||
terrain=Ww
|
||||
[/filter_adjacent_location]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,49 @@
|
|||
#####
|
||||
# API(s) being tested: ability[filter_adjacent_location]adjacent,count=
|
||||
##
|
||||
# Actions:
|
||||
# Give Alice an ability specialX, which is only active if zero of the adjacent terrains are Gg.
|
||||
# Test whether specialX ability is active.
|
||||
##
|
||||
# Expected end state:
|
||||
# specialX isn't active.
|
||||
#####
|
||||
{COMMON_KEEP_A_B_C_D_UNIT_TEST "filter_adjacent_location_count_zero_inactive" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if 0 terrains hexes are Gg"
|
||||
value=100
|
||||
apply_to=self
|
||||
[filter_adjacent_location]
|
||||
adjacent=n,ne,se,s,sw,nw
|
||||
count=0
|
||||
terrain=Gg
|
||||
[/filter_adjacent_location]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/object]
|
||||
|
||||
{ASSERT (
|
||||
[not]
|
||||
[have_unit]
|
||||
ability_id_active=specialX
|
||||
[/have_unit]
|
||||
[/not]
|
||||
)}
|
||||
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,105 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent_student]
|
||||
##
|
||||
# Actions:
|
||||
# place a unit alex adjacent to alice and only alice.
|
||||
# Give alex an ability specialX who affect alice, which is only active in fight if one adjacent unit is bob.
|
||||
# alice attack bob.
|
||||
##
|
||||
# Expected end state:
|
||||
# attack event trigered if specialX active because alice is adjacent to bob.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST "filter_adjacent_student_active" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[unit]
|
||||
id=alex
|
||||
name=_"Alex"
|
||||
x,y=12,4
|
||||
type=Elvish Hero
|
||||
side=1
|
||||
[/unit]
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if one of the adjacents units is bob"
|
||||
value=1
|
||||
apply_to=self
|
||||
affect_self=no
|
||||
affect_allies=yes
|
||||
affect_enemies=yes
|
||||
[affect_adjacent]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/affect_adjacent]
|
||||
[filter_adjacent_student]
|
||||
id=bob
|
||||
[/filter_adjacent_student]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alex
|
||||
[/filter]
|
||||
[/object]
|
||||
{VARIABLE triggers_on_attack 0}
|
||||
[/event]
|
||||
[event]
|
||||
name=side 1 turn 1
|
||||
[do_command]
|
||||
[move]
|
||||
x=7,13
|
||||
y=3,4
|
||||
[/move]
|
||||
[attack]
|
||||
[source]
|
||||
x,y=13,4
|
||||
[/source]
|
||||
[destination]
|
||||
x,y=13,3
|
||||
[/destination]
|
||||
[/attack]
|
||||
[/do_command]
|
||||
[end_turn][/end_turn]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=side 2 turn
|
||||
[do_command]
|
||||
[attack]
|
||||
[source]
|
||||
x,y=13,3
|
||||
[/source]
|
||||
[destination]
|
||||
x,y=13,4
|
||||
[/destination]
|
||||
[/attack]
|
||||
[/do_command]
|
||||
[end_turn][/end_turn]
|
||||
[/event]
|
||||
# Event when Alice attacks
|
||||
[event]
|
||||
name=attack
|
||||
first_time_only=no
|
||||
[filter_attack]
|
||||
special_id_active=specialX
|
||||
[/filter_attack]
|
||||
{ASSERT ({VARIABLE_CONDITIONAL side_number equals 1})}
|
||||
{VARIABLE_OP triggers_on_attack add 1}
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=turn 2
|
||||
{ASSERT ({VARIABLE_CONDITIONAL triggers_on_attack equals 1})}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -0,0 +1,113 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
#####
|
||||
# API(s) being tested: ability[filter_adjacent_student]
|
||||
##
|
||||
# Actions:
|
||||
# place a unit alex adjacent to alice and only alice.
|
||||
# place loki adjacent to alex and only alex
|
||||
# Give alex an ability specialX who affect alice, which is only active in fight if one adjacent unit is loki.
|
||||
# alice attack bob.
|
||||
##
|
||||
# Expected end state:
|
||||
# attack event no trigered if specialX active because alice is no adjacent to loki, [filter_adjacent_student] filter the units adjacent to student, and not owner of ability.
|
||||
#####
|
||||
{GENERIC_UNIT_TEST "filter_adjacent_student_inactive" (
|
||||
[event]
|
||||
name=start
|
||||
|
||||
[unit]
|
||||
id=alex
|
||||
name=_"Alex"
|
||||
x,y=12,4
|
||||
type=Elvish Hero
|
||||
side=1
|
||||
[/unit]
|
||||
[unit]
|
||||
id=loki
|
||||
name=_"Loki"
|
||||
x,y=11,4
|
||||
type=Elvish Hero
|
||||
side=1
|
||||
[/unit]
|
||||
[object]
|
||||
silent=yes
|
||||
[effect]
|
||||
apply_to=new_ability
|
||||
[abilities]
|
||||
[damage]
|
||||
id=specialX
|
||||
name=_ "specialX"
|
||||
description=_ "specialX is active if and only if one of the adjacents units is bob"
|
||||
value=1
|
||||
apply_to=self
|
||||
affect_self=no
|
||||
affect_allies=yes
|
||||
affect_enemies=yes
|
||||
[affect_adjacent]
|
||||
[filter]
|
||||
id=alice
|
||||
[/filter]
|
||||
[/affect_adjacent]
|
||||
[filter_adjacent_student]
|
||||
id=loki
|
||||
[/filter_adjacent_student]
|
||||
[/damage]
|
||||
[/abilities]
|
||||
[/effect]
|
||||
[filter]
|
||||
id=alex
|
||||
[/filter]
|
||||
[/object]
|
||||
{VARIABLE triggers_on_attack 0}
|
||||
[/event]
|
||||
[event]
|
||||
name=side 1 turn 1
|
||||
[do_command]
|
||||
[move]
|
||||
x=7,13
|
||||
y=3,4
|
||||
[/move]
|
||||
[attack]
|
||||
[source]
|
||||
x,y=13,4
|
||||
[/source]
|
||||
[destination]
|
||||
x,y=13,3
|
||||
[/destination]
|
||||
[/attack]
|
||||
[/do_command]
|
||||
[end_turn][/end_turn]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=side 2 turn
|
||||
[do_command]
|
||||
[attack]
|
||||
[source]
|
||||
x,y=13,3
|
||||
[/source]
|
||||
[destination]
|
||||
x,y=13,4
|
||||
[/destination]
|
||||
[/attack]
|
||||
[/do_command]
|
||||
[end_turn][/end_turn]
|
||||
[/event]
|
||||
# Event when Alice attacks
|
||||
[event]
|
||||
name=attack
|
||||
first_time_only=no
|
||||
[filter_attack]
|
||||
special_id_active=specialX
|
||||
[/filter_attack]
|
||||
{ASSERT ({VARIABLE_CONDITIONAL side_number equals 1})}
|
||||
{VARIABLE_OP triggers_on_attack add 1}
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=turn 2
|
||||
{ASSERT ({VARIABLE_CONDITIONAL triggers_on_attack equals 0})}
|
||||
{SUCCEED}
|
||||
[/event]
|
||||
)}
|
|
@ -446,18 +446,16 @@ bool unit::ability_active_impl(const std::string& ability,const config& cfg,cons
|
|||
std::size_t count = 0;
|
||||
unit_filter ufilt{ vconfig(i) };
|
||||
ufilt.set_use_flat_tod(illuminates);
|
||||
std::vector<map_location::direction> dirs = map_location::parse_directions(i["adjacent"]);
|
||||
std::vector<map_location::direction> dirs = i["adjacent"].empty() ? map_location::all_directions() : map_location::parse_directions(i["adjacent"]);
|
||||
for (const map_location::direction index : dirs)
|
||||
{
|
||||
if (index == map_location::direction::indeterminate)
|
||||
continue;
|
||||
unit_map::const_iterator unit = units.find(adjacent[static_cast<int>(index)]);
|
||||
if (unit == units.end())
|
||||
return false;
|
||||
continue;
|
||||
if (!ufilt(*unit, *this))
|
||||
return false;
|
||||
continue;
|
||||
if((*this).id() == (*unit).id())
|
||||
return false;
|
||||
continue;
|
||||
if (i.has_attribute("is_enemy")) {
|
||||
const display_context& dc = resources::filter_con->get_disp_context();
|
||||
if (i["is_enemy"].to_bool() != dc.get_team(unit->side()).is_enemy(side_)) {
|
||||
|
@ -466,10 +464,9 @@ bool unit::ability_active_impl(const std::string& ability,const config& cfg,cons
|
|||
}
|
||||
count++;
|
||||
}
|
||||
if (i["count"].empty() && count != dirs.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!in_ranges<int>(count, utils::parse_ranges_unsigned(i["count"].str()))) {
|
||||
static std::vector<std::pair<int,int>> default_counts = utils::parse_ranges_unsigned("1-6");
|
||||
config::attribute_value i_count =i["count"];
|
||||
if(!in_ranges<int>(count, !i_count.blank() ? utils::parse_ranges_unsigned(i_count) : default_counts)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -480,21 +477,17 @@ bool unit::ability_active_impl(const std::string& ability,const config& cfg,cons
|
|||
terrain_filter adj_filter(vconfig(i), resources::filter_con, false);
|
||||
adj_filter.flatten(illuminates);
|
||||
|
||||
std::vector<map_location::direction> dirs = map_location::parse_directions(i["adjacent"]);
|
||||
std::vector<map_location::direction> dirs = i["adjacent"].empty() ? map_location::all_directions() : map_location::parse_directions(i["adjacent"]);
|
||||
for (const map_location::direction index : dirs)
|
||||
{
|
||||
if (index == map_location::direction::indeterminate) {
|
||||
continue;
|
||||
}
|
||||
if(!adj_filter.match(adjacent[static_cast<int>(index)])) {
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (i["count"].empty() && count != dirs.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!in_ranges<int>(count, utils::parse_ranges_unsigned(i["count"].str()))) {
|
||||
static std::vector<std::pair<int,int>> default_counts = utils::parse_ranges_unsigned("1-6");
|
||||
config::attribute_value i_count =i["count"];
|
||||
if(!in_ranges<int>(count, !i_count.blank() ? utils::parse_ranges_unsigned(i_count) : default_counts)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1554,13 +1547,13 @@ unit_ability_list attack_type::get_weapon_ability(const std::string& ability) co
|
|||
unit_ability_list abil_list(loc);
|
||||
if(self_) {
|
||||
abil_list.append_if((*self_).get_abilities(ability, self_loc_), [&](const unit_ability& i) {
|
||||
return special_active(*i.ability_cfg, AFFECT_SELF, ability, "filter_student");
|
||||
return special_active(*i.ability_cfg, AFFECT_SELF, ability, true);
|
||||
});
|
||||
}
|
||||
|
||||
if(other_) {
|
||||
abil_list.append_if((*other_).get_abilities(ability, other_loc_), [&](const unit_ability& i) {
|
||||
return special_active_impl(other_attack_, shared_from_this(), *i.ability_cfg, AFFECT_OTHER, ability, "filter_student");
|
||||
return special_active_impl(other_attack_, shared_from_this(), *i.ability_cfg, AFFECT_OTHER, ability, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1757,7 +1750,7 @@ bool attack_type::check_self_abilities_impl(const const_attack_ptr& self_attack,
|
|||
}
|
||||
}
|
||||
if((*u).checking_tags().count(tag_name) != 0){
|
||||
if((*u).get_self_ability_bool(special, tag_name, loc) && special_active_impl(self_attack, other_attack, special, whom, tag_name, "filter_student")) {
|
||||
if((*u).get_self_ability_bool(special, tag_name, loc) && special_active_impl(self_attack, other_attack, special, whom, tag_name, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1777,7 +1770,7 @@ bool attack_type::check_adj_abilities_impl(const const_attack_ptr& self_attack,
|
|||
}
|
||||
}
|
||||
if((*u).checking_tags().count(tag_name) != 0){
|
||||
if((*u).get_adj_ability_bool(special, tag_name, dir, loc, from) && special_active_impl(self_attack, other_attack, special, whom, tag_name, "filter_student")) {
|
||||
if((*u).get_adj_ability_bool(special, tag_name, dir, loc, from) && special_active_impl(self_attack, other_attack, special, whom, tag_name, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2197,9 +2190,9 @@ bool attack_type::has_special_or_ability_with_filter(const config & filter) cons
|
|||
}
|
||||
|
||||
bool attack_type::special_active(const config& special, AFFECTS whom, const std::string& tag_name,
|
||||
const std::string& filter_self) const
|
||||
bool in_abilities_tag) const
|
||||
{
|
||||
return special_active_impl(shared_from_this(), other_attack_, special, whom, tag_name, filter_self);
|
||||
return special_active_impl(shared_from_this(), other_attack_, special, whom, tag_name, in_abilities_tag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2210,7 +2203,7 @@ bool attack_type::special_active(const config& special, AFFECTS whom, const std:
|
|||
* @param special a weapon special WML structure
|
||||
* @param whom specifies which combatant we care about
|
||||
* @param tag_name tag name of the special config
|
||||
* @param filter_self the filter to use
|
||||
* @param in_abilities_tag if special coded in [specials] or [abilities] tags
|
||||
*/
|
||||
bool attack_type::special_active_impl(
|
||||
const const_attack_ptr& self_attack,
|
||||
|
@ -2218,7 +2211,7 @@ bool attack_type::special_active_impl(
|
|||
const config& special,
|
||||
AFFECTS whom,
|
||||
const std::string& tag_name,
|
||||
const std::string& filter_self)
|
||||
bool in_abilities_tag)
|
||||
{
|
||||
assert(self_attack || other_attack);
|
||||
bool is_attacker = self_attack ? self_attack->is_attacker_ : !other_attack->is_attacker_;
|
||||
|
@ -2320,6 +2313,7 @@ bool attack_type::special_active_impl(
|
|||
//the function of this special in matches_filter()
|
||||
//In apply_to=both case, tag_name must be checked in all filter because special applied to both self and opponent.
|
||||
bool applied_both = special["apply_to"] == "both";
|
||||
const std::string& filter_self = in_abilities_tag ? "filter_student" : "filter_self";
|
||||
std::string self_check_if_recursion = (applied_both || whom_is_self) ? tag_name : "";
|
||||
if (!special_unit_matches(self, other, self_loc, self_attack, special, is_for_listing, filter_self, self_check_if_recursion))
|
||||
return false;
|
||||
|
@ -2337,21 +2331,25 @@ bool attack_type::special_active_impl(
|
|||
if (!special_unit_matches(def, att, def_loc, def_weapon, special, is_for_listing, "filter_defender", def_check_if_recursion))
|
||||
return false;
|
||||
|
||||
//if filter_self != "filter_self" then it's in [abilities] tags and
|
||||
//[filter_student_adjacent] and [filter_student_adjacent] then designate 'the student' (which may be different from the owner of the ability),
|
||||
//while in the tags[specials] the usual names are kept.
|
||||
const std::string& filter_adjacent = in_abilities_tag ? "filter_adjacent_student" : "filter_adjacent";
|
||||
const std::string& filter_adjacent_location = in_abilities_tag ? "filter_adjacent_student_location" : "filter_adjacent_location";
|
||||
|
||||
const auto adjacent = get_adjacent_tiles(self_loc);
|
||||
|
||||
// Filter the adjacent units.
|
||||
for (const config &i : special.child_range("filter_adjacent"))
|
||||
for (const config &i : special.child_range(filter_adjacent))
|
||||
{
|
||||
std::size_t count = 0;
|
||||
std::vector<map_location::direction> dirs = map_location::parse_directions(i["adjacent"]);
|
||||
std::vector<map_location::direction> dirs = i["adjacent"].empty() ? map_location::all_directions() : map_location::parse_directions(i["adjacent"]);
|
||||
unit_filter filter{ vconfig(i) };
|
||||
for (const map_location::direction index : dirs)
|
||||
{
|
||||
if (index == map_location::direction::indeterminate)
|
||||
continue;
|
||||
unit_map::const_iterator unit = units.find(adjacent[static_cast<int>(index)]);
|
||||
if (unit == units.end() || !filter.matches(*unit, adjacent[static_cast<int>(index)], *self))
|
||||
return false;
|
||||
continue;
|
||||
if (i.has_attribute("is_enemy")) {
|
||||
const display_context& dc = resources::filter_con->get_disp_context();
|
||||
if (i["is_enemy"].to_bool() != dc.get_team(unit->side()).is_enemy(self->side())) {
|
||||
|
@ -2360,33 +2358,29 @@ bool attack_type::special_active_impl(
|
|||
}
|
||||
count++;
|
||||
}
|
||||
if (i["count"].empty() && count != dirs.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!in_ranges<int>(count, utils::parse_ranges_unsigned(i["count"].str()))) {
|
||||
static std::vector<std::pair<int,int>> default_counts = utils::parse_ranges_unsigned("1-6");
|
||||
config::attribute_value i_count =i["count"];
|
||||
if(!in_ranges<int>(count, !i_count.blank() ? utils::parse_ranges_unsigned(i_count) : default_counts)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter the adjacent locations.
|
||||
for (const config &i : special.child_range("filter_adjacent_location"))
|
||||
for (const config &i : special.child_range(filter_adjacent_location))
|
||||
{
|
||||
std::size_t count = 0;
|
||||
std::vector<map_location::direction> dirs = map_location::parse_directions(i["adjacent"]);
|
||||
std::vector<map_location::direction> dirs = i["adjacent"].empty() ? map_location::all_directions() : map_location::parse_directions(i["adjacent"]);
|
||||
terrain_filter adj_filter(vconfig(i), resources::filter_con, false);
|
||||
for (const map_location::direction index : dirs)
|
||||
{
|
||||
if (index == map_location::direction::indeterminate)
|
||||
continue;
|
||||
if(!adj_filter.match(adjacent[static_cast<int>(index)])) {
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (i["count"].empty() && count != dirs.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!in_ranges<int>(count, utils::parse_ranges_unsigned(i["count"].str()))) {
|
||||
static std::vector<std::pair<int,int>> default_counts = utils::parse_ranges_unsigned("1-6");
|
||||
config::attribute_value i_count =i["count"];
|
||||
if(!in_ranges<int>(count, !i_count.blank() ? utils::parse_ranges_unsigned(i_count) : default_counts)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ private:
|
|||
*/
|
||||
bool check_adj_abilities(const config& cfg, const std::string& special, int dir, const unit& from) const;
|
||||
bool special_active(const config& special, AFFECTS whom, const std::string& tag_name,
|
||||
const std::string& filter_self ="filter_self") const;
|
||||
bool in_abilities_tag = false) const;
|
||||
|
||||
/** weapon_specials_impl_self and weapon_specials_impl_adj : check if special name can be added.
|
||||
* @param[in,out] temp_string the string modified and returned
|
||||
|
@ -364,7 +364,7 @@ private:
|
|||
const config& special,
|
||||
AFFECTS whom,
|
||||
const std::string& tag_name,
|
||||
const std::string& filter_self ="filter_self"
|
||||
bool in_abilities_tag = false
|
||||
);
|
||||
|
||||
// Used via specials_context() to control which specials are
|
||||
|
|
|
@ -411,6 +411,15 @@
|
|||
0 taught_resistance_with_three_attack_types
|
||||
0 swarms_filter_student_by_type
|
||||
0 swarms_effects_not_checkable
|
||||
0 filter_adjacent_location_count_three_active
|
||||
0 filter_adjacent_location_count_zero_active
|
||||
0 filter_adjacent_location_count_zero_inactive
|
||||
0 filter_adjacent_active
|
||||
0 filter_adjacent_inactive
|
||||
0 filter_adjacent_student_active
|
||||
0 filter_adjacent_student_inactive
|
||||
0 filter_adjacent_direction_active
|
||||
0 filter_adjacent_direction_inactive
|
||||
0 filter_special_id_active
|
||||
0 filter_ability_special_id_active
|
||||
0 filter_special_id_not_exists
|
||||
|
|
Loading…
Reference in New Issue
Block a user