add 'unslowable' and 'unpetrifiable' status (#5788)

This commit is contained in:
newfrenchy83 2021-05-27 19:35:49 +02:00 committed by GitHub
parent dc6b5f3832
commit bf6b09007c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 251 additions and 2 deletions

View file

@ -12,6 +12,7 @@
* Added missing Seahorse graphics * Added missing Seahorse graphics
### User interface ### User interface
### WML Engine ### WML Engine
* add 'unslowable' and 'unpetrifiable' status to immune to slow or petrifies
### Miscellaneous and Bug Fixes ### Miscellaneous and Bug Fixes
* The unit description tooltip in the sidebar now includes the text from `[special_note]`s. * The unit description tooltip in the sidebar now includes the text from `[special_note]`s.

View file

@ -0,0 +1,228 @@
# this unit test what 'unslowable' status immune unit against slow status and idem for 'unpetrifiable' status
# with petrified status
{GENERIC_UNIT_TEST "unslowable_status_test" (
[event]
name=start
[modify_unit]
[filter]
[/filter]
max_hitpoints=100
hitpoints=100
attacks_left=1
[/modify_unit]
[object]
silent=yes
[effect]
apply_to=attack
[set_specials]
mode=append
[slow]
[/slow]
[attacks]
value=1
[/attacks]
[damage]
value=1
[/damage]
[chance_to_hit]
value=100
[/chance_to_hit]
[/set_specials]
[/effect]
[filter]
id=bob
[/filter]
[/object]
[object]
silent=yes
[effect]
apply_to=attack
[set_specials]
mode=append
[attacks]
value=1
[/attacks]
[damage]
value=1
[/damage]
[chance_to_hit]
value=100
[/chance_to_hit]
[/set_specials]
[/effect]
[effect]
apply_to=status
add=unslowable
[/effect]
[filter]
id=alice
[/filter]
[/object]
[store_unit]
[filter]
id=alice
[/filter]
variable=a
kill=yes
[/store_unit]
[store_unit]
[filter]
id=bob
[/filter]
variable=b
[/store_unit]
[unstore_unit]
variable=a
find_vacant=yes
x,y=$b.x,$b.y
[/unstore_unit]
[store_unit]
[filter]
id=alice
[/filter]
variable=a
[/store_unit]
[do_command]
[attack]
weapon=0
defender_weapon=0
[source]
x,y=$a.x,$a.y
[/source]
[destination]
x,y=$b.x,$b.y
[/destination]
[/attack]
[/do_command]
[store_unit]
[filter]
id=alice
[/filter]
variable=a
[/store_unit]
[store_unit]
[filter]
id=bob
[/filter]
variable=b
[/store_unit]
{ASSERT ({VARIABLE_CONDITIONAL a.status.slowed boolean_equals no})}
{SUCCEED}
[/event]
)}
{GENERIC_UNIT_TEST "unpetrifiable_status_test" (
[event]
name=start
[modify_unit]
[filter]
[/filter]
max_hitpoints=100
hitpoints=100
attacks_left=1
[/modify_unit]
[object]
silent=yes
[effect]
apply_to=attack
[set_specials]
mode=append
[petrifies]
[/petrifies]
[attacks]
value=1
[/attacks]
[damage]
value=1
[/damage]
[chance_to_hit]
value=100
[/chance_to_hit]
[/set_specials]
[/effect]
[filter]
id=bob
[/filter]
[/object]
[object]
silent=yes
[effect]
apply_to=attack
[set_specials]
mode=append
[attacks]
value=1
[/attacks]
[damage]
value=1
[/damage]
[chance_to_hit]
value=100
[/chance_to_hit]
[/set_specials]
[/effect]
[effect]
apply_to=status
add=unpetrifiable
[/effect]
[filter]
id=alice
[/filter]
[/object]
[store_unit]
[filter]
id=alice
[/filter]
variable=a
kill=yes
[/store_unit]
[store_unit]
[filter]
id=bob
[/filter]
variable=b
[/store_unit]
[unstore_unit]
variable=a
find_vacant=yes
x,y=$b.x,$b.y
[/unstore_unit]
[store_unit]
[filter]
id=alice
[/filter]
variable=a
[/store_unit]
[do_command]
[attack]
weapon=0
defender_weapon=0
[source]
x,y=$a.x,$a.y
[/source]
[destination]
x,y=$b.x,$b.y
[/destination]
[/attack]
[/do_command]
[store_unit]
[filter]
id=alice
[/filter]
variable=a
[/store_unit]
[store_unit]
[filter]
id=bob
[/filter]
variable=b
[/store_unit]
{ASSERT ({VARIABLE_CONDITIONAL a.status.petrified boolean_equals no})}
{SUCCEED}
[/event]
)}

View file

@ -143,9 +143,9 @@ battle_context_unit_stats::battle_context_unit_stats(nonempty_unit_const_ptr up,
opp_ctx.emplace(opp_weapon->specials_context(oppp, up, opp_loc, u_loc, !attacking, weapon)); opp_ctx.emplace(opp_weapon->specials_context(oppp, up, opp_loc, u_loc, !attacking, weapon));
} }
slows = weapon->has_special_or_ability("slow"); slows = weapon->has_special_or_ability("slow") && !opp.get_state("unslowable") ;
drains = !opp.get_state("undrainable") && weapon->has_special_or_ability("drains"); drains = !opp.get_state("undrainable") && weapon->has_special_or_ability("drains");
petrifies = weapon->has_special_or_ability("petrifies"); petrifies = !opp.get_state("unpetrifiable") && weapon->has_special_or_ability("petrifies");
poisons = !opp.get_state("unpoisonable") && weapon->has_special_or_ability("poison") && !opp.get_state(unit::STATE_POISONED); poisons = !opp.get_state("unpoisonable") && weapon->has_special_or_ability("poison") && !opp.get_state(unit::STATE_POISONED);
backstab_pos = is_attacker && backstab_check(u_loc, opp_loc, units, resources::gameboard->teams()); backstab_pos = is_attacker && backstab_check(u_loc, opp_loc, units, resources::gameboard->teams());
rounds = weapon->get_specials_and_abilities("berserk").highest("value", 1).first; rounds = weapon->get_specials_and_abilities("berserk").highest("value", 1).first;

View file

@ -417,6 +417,10 @@ variant unit_type_callable::get_value(const std::string& key) const
return variant(u_.movement()); return variant(u_.movement());
} else if(key == "unpoisonable") { } else if(key == "unpoisonable") {
return variant(u_.musthave_status("unpoisonable")); return variant(u_.musthave_status("unpoisonable"));
} else if(key == "unslowable") {
return variant(u_.musthave_status("unslowable"));
} else if(key == "unpetrifiable") {
return variant(u_.musthave_status("unpetrifiable"));
} else if(key == "undrainable") { } else if(key == "undrainable") {
return variant(u_.musthave_status("undrainable")); return variant(u_.musthave_status("undrainable"));
} else if(key == "unplagueable") { } else if(key == "unplagueable") {

View file

@ -1497,6 +1497,14 @@ bool attack_type::special_active_impl(const_attack_ptr self_attack, const_attack
other_attack->has_special_or_ability("firststrike")) { other_attack->has_special_or_ability("firststrike")) {
return false; return false;
} }
if (tag_name == "slow" && other &&
(other->get_state("unslowable") || other->get_state(unit::STATE_SLOWED))) {
return false;
}
if (tag_name == "petrifies" && other &&
other->get_state("unpetrifiable")) {
return false;
}
// Translate our context into terms of "attacker" and "defender". // Translate our context into terms of "attacker" and "defender".

View file

@ -949,6 +949,12 @@ void unit::advance_to(const unit_type& u_type, bool use_traits)
if(get_state("unpoisonable")) { if(get_state("unpoisonable")) {
set_state(STATE_POISONED, false); set_state(STATE_POISONED, false);
} }
if(get_state("unslowable")) {
set_state(STATE_SLOWED, false);
}
if(get_state("unpetrifiable")) {
set_state(STATE_PETRIFIED, false);
}
// Now that modifications are done modifying the maximum hit points, // Now that modifications are done modifying the maximum hit points,
// enforce this maximum. // enforce this maximum.

View file

@ -245,6 +245,8 @@
0 swarm_disables_upgrades_with_abilities_adjacent_fail 0 swarm_disables_upgrades_with_abilities_adjacent_fail
0 swarm_disables_upgrades_with_abilities_adjacent_leadership 0 swarm_disables_upgrades_with_abilities_adjacent_leadership
0 swarm_disables_upgrades_with_abilities_adjacent_leadership_fail 0 swarm_disables_upgrades_with_abilities_adjacent_leadership_fail
0 unslowable_status_test
0 unpetrifiable_status_test
0 test_force_chance_to_hit_macro 0 test_force_chance_to_hit_macro
# #
# Deterministic unit facing tests # Deterministic unit facing tests