Check unit/second_unit existence in FORCE_CHANCE_TO_HIT

Fixes an issue where the auxiliary event handlers for 'attack end' in
this macro might break if the affected unit or units are removed from
the map by a pre-existing 'attack end' event handler.

Unfortunately this still results in log warnings about failing to
auto-store unit/second_unit, but it's better than breaking WML execution
entirely.

    20190313 23:36:48 error engine: failed to auto-store $second_unit at (9,40)

The alternative I contemplated was to force unit/second_unit to be valid
in the event handlers by using empty filters, but then that would result
in the event handler being triggered *later* by another valid unit. This
is especially problematic since the event handler handles special
knowledge about the unit's WML ([specials][original_chance_to_hit]).
That option would not produce any spurious error messages but would
definitely cause new problems, especially when interacting with other
FCTH substitutions in the same scenario.

Ultimately FCTH's design is a bit questionable and relies too much on
state that may be broken by an external agent intentionally or otherwise
and produce unusual results.

Closes #3982.

[ci skip]
This commit is contained in:
Iris Morelle 2019-03-13 23:49:34 -03:00
parent f7bcc0702b
commit bee64fc78b
2 changed files with 25 additions and 0 deletions

View file

@ -52,6 +52,9 @@
* Fix undoing a recall not un-drawing parts of the sprite that go beyond the unit's hex (issue #3325)
* Fix crash when the recruit filter matched nothing. (PR #3969)
* "Show Enemy Moves" now highlights enemy units that can reach the highlighted hex. (PR #3961)
### Miscellaneous and bug fixes
* Fix auxiliary attack end event handlers defined by FORCE_CHANCE_TO_HIT breaking if one or more of the
affected units are removed by another attack end event handler (issue #3982).
## Version 1.14.6
### AI

View file

@ -578,6 +578,17 @@
name=attack end
delayed_variable_substitution=yes
[if]
[variable]
name=unit.length
numerical_equals=0
[/variable]
[then]
# Unit vanished mid-fight
[return][/return]
[/then]
[/if]
[foreach]
array=unit.attack
[do]
@ -665,6 +676,17 @@
name=attack end
delayed_variable_substitution=yes
[if]
[variable]
name=second_unit.length
numerical_equals=0
[/variable]
[then]
# Unit vanished mid-fight
[return][/return]
[/then]
[/if]
[foreach]
array=second_unit.attack
[do]