
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]
736 lines
21 KiB
INI
736 lines
21 KiB
INI
#textdomain wesnoth
|
|
# This file contains general utility macros for WML authors.
|
|
#
|
|
# Later macros in this file are built using earlier ones, which
|
|
# is why they live here rather than being broken out into topic-specific files.
|
|
|
|
# ! in comments is used in generating HTML documentation, ignore it otherwise.
|
|
#define QUANTITY NAME EASY_VALUE NORMAL_VALUE HARD_VALUE
|
|
# Macro to define a 'quantity' differently based on difficulty levels.
|
|
#ifdef EASY
|
|
{NAME}={EASY_VALUE}
|
|
#endif
|
|
#ifdef NORMAL
|
|
{NAME}={NORMAL_VALUE}
|
|
#endif
|
|
#ifdef HARD
|
|
{NAME}={HARD_VALUE}
|
|
#endif
|
|
#enddef
|
|
|
|
#define QUANTITY4 NAME EASY_VALUE NORMAL_VALUE HARD_VALUE NIGHTMARE_VALUE
|
|
# Four-difficulty version of QUANTITY
|
|
#ifdef EASY
|
|
{NAME}={EASY_VALUE}
|
|
#endif
|
|
|
|
#ifdef NORMAL
|
|
{NAME}={NORMAL_VALUE}
|
|
#endif
|
|
|
|
#ifdef HARD
|
|
{NAME}={HARD_VALUE}
|
|
#endif
|
|
|
|
#ifdef NIGHTMARE
|
|
{NAME}={NIGHTMARE_VALUE}
|
|
#endif
|
|
#enddef
|
|
|
|
# No tab or space-based indentation for these macros to avoid trouble when these macros are used
|
|
# in the middle of a quoted string literal
|
|
#
|
|
# wmlindent: start ignoring
|
|
# wmlscope: start conditionals
|
|
#ifdef EASY
|
|
#define ON_DIFFICULTY EASY_VALUE NORMAL_VALUE HARD_VALUE
|
|
{EASY_VALUE}#enddef
|
|
#endif
|
|
#ifdef NORMAL
|
|
#define ON_DIFFICULTY EASY_VALUE NORMAL_VALUE HARD_VALUE
|
|
{NORMAL_VALUE}#enddef
|
|
#endif
|
|
#ifdef HARD
|
|
#define ON_DIFFICULTY EASY_VALUE NORMAL_VALUE HARD_VALUE
|
|
{HARD_VALUE}#enddef
|
|
#endif
|
|
# wmlscope: stop conditionals
|
|
# wmlindent: stop ignoring
|
|
# wmlscope: prune ON_DIFFICULTY
|
|
|
|
# No tab or space-based indentation for these macros to avoid trouble when these macros are used
|
|
# in the middle of a quoted string literal
|
|
#
|
|
# wmlindent: start ignoring
|
|
# wmlscope: start conditionals
|
|
#ifdef EASY
|
|
#define ON_DIFFICULTY4 EASY_VALUE NORMAL_VALUE HARD_VALUE NIGHTMARE_VALUE
|
|
{EASY_VALUE}#enddef
|
|
#endif
|
|
#ifdef NORMAL
|
|
#define ON_DIFFICULTY4 EASY_VALUE NORMAL_VALUE HARD_VALUE NIGHTMARE_VALUE
|
|
{NORMAL_VALUE}#enddef
|
|
#endif
|
|
#ifdef HARD
|
|
#define ON_DIFFICULTY4 EASY_VALUE NORMAL_VALUE HARD_VALUE NIGHTMARE_VALUE
|
|
{HARD_VALUE}#enddef
|
|
#endif
|
|
#ifdef NIGHTMARE
|
|
#define ON_DIFFICULTY4 EASY_VALUE NORMAL_VALUE HARD_VALUE NIGHTMARE_VALUE
|
|
{NIGHTMARE_VALUE}#enddef
|
|
#endif
|
|
# wmlscope: stop conditionals
|
|
# wmlindent: stop ignoring
|
|
# wmlscope: prune ON_DIFFICULTY4
|
|
|
|
#define TURNS EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT
|
|
# Macro to define number of turns for different difficulty levels.
|
|
{QUANTITY turns {EASY_AMOUNT} {NORMAL_AMOUNT} {HARD_AMOUNT}}
|
|
#enddef
|
|
|
|
#define TURNS4 EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT NIGHTMARE_AMOUNT
|
|
# Four-difficulty version of TURNS
|
|
{QUANTITY4 turns {EASY_AMOUNT} {NORMAL_AMOUNT} {HARD_AMOUNT} {NIGHTMARE_AMOUNT}}
|
|
#enddef
|
|
|
|
#define GOLD EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT
|
|
# Macro which will let you say {GOLD x y z} to set
|
|
# starting gold depending on easy/medium/hard - x/y/z
|
|
{QUANTITY gold {EASY_AMOUNT} {NORMAL_AMOUNT} {HARD_AMOUNT}}
|
|
#enddef
|
|
|
|
#define GOLD4 EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT NIGHTMARE_AMOUNT
|
|
# Four-difficulty version of GOLD
|
|
{QUANTITY4 gold {EASY_AMOUNT} {NORMAL_AMOUNT} {HARD_AMOUNT} {NIGHTMARE_AMOUNT}}
|
|
#enddef
|
|
|
|
#define INCOME EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT
|
|
# Macro which will let you say {INCOME x y z} to set
|
|
# per-turn income depending on easy/medium/hard - x/y/z
|
|
{QUANTITY income {EASY_AMOUNT} {NORMAL_AMOUNT} {HARD_AMOUNT}}
|
|
#enddef
|
|
|
|
#define INCOME4 EASY_AMOUNT NORMAL_AMOUNT HARD_AMOUNT NIGHTMARE_AMOUNT
|
|
# Four-difficulty version of INCOME
|
|
{QUANTITY4 income {EASY_AMOUNT} {NORMAL_AMOUNT} {HARD_AMOUNT} {NIGHTMARE_AMOUNT}}
|
|
#enddef
|
|
|
|
#define NO_INCOME
|
|
# Used to specify when a side should not have any income
|
|
# every turn.
|
|
income=-2
|
|
#enddef
|
|
|
|
#define ATTACK_DEPTH EASY_VALUE NORMAL_VALUE HARD_VALUE
|
|
# Macro to define AI attack depth for different difficulty levels
|
|
# (set it to 1-6)
|
|
{QUANTITY attack_depth {EASY_VALUE} {NORMAL_VALUE} {HARD_VALUE}}
|
|
#enddef
|
|
|
|
#define ATTACK_DEPTH4 EASY_VALUE NORMAL_VALUE HARD_VALUE NIGHTMARE_VALUE
|
|
# Four-difficulty version of ATTACK_DEPTH
|
|
{QUANTITY4 attack_depth {EASY_VALUE} {NORMAL_VALUE} {HARD_VALUE} {NIGHTMARE_VALUE}}
|
|
#enddef
|
|
|
|
#define NO_SCOUTS
|
|
# Macro to make an AI team not recruit scouts.
|
|
villages_per_scout=0
|
|
#enddef
|
|
|
|
#define RANDOM THING_VALUE
|
|
# Macro to quickly pick a random value (in the $random variable, to avoid
|
|
# cluttering up savegames with such temporary variables).
|
|
[set_variable]
|
|
name=random
|
|
rand={THING_VALUE}
|
|
[/set_variable]
|
|
#enddef
|
|
|
|
#define VARIABLE VAR VALUE
|
|
# Macro to initialize a variable. Strictly a syntatic shortcut.
|
|
[set_variable]
|
|
name={VAR}
|
|
value={VALUE}
|
|
[/set_variable]
|
|
#enddef
|
|
|
|
#define GLOBAL_VARIABLE NAMESPACE LOCAL_VAR_NAME GLOBAL_VAR_NAME SIDE
|
|
#Assigns a persistent variable with the contents of a standard variable.
|
|
[set_global_variable]
|
|
namespace={NAMESPACE}
|
|
from_local={LOCAL_VAR_NAME}
|
|
to_global={GLOBAL_VAR_NAME}
|
|
side={SIDE}
|
|
[/set_global_variable]
|
|
#enddef
|
|
|
|
#define VARIABLE_FROM_GLOBAL NAMESPACE GLOBAL_VAR_NAME LOCAL_VAR_NAME SIDE
|
|
#Retrieves the contents of a persistent variable and stores them in a standard variable.
|
|
[get_global_variable]
|
|
namespace={NAMESPACE}
|
|
from_global={GLOBAL_VAR_NAME}
|
|
to_local={LOCAL_VAR_NAME}
|
|
side={SIDE}
|
|
#immediate=no
|
|
[/get_global_variable]
|
|
#enddef
|
|
|
|
#define VARIABLE_OP VAR OP_NAME VALUE
|
|
# Macro to do mathematical operations on variables.
|
|
[set_variable]
|
|
name={VAR}
|
|
{OP_NAME}={VALUE}
|
|
[/set_variable]
|
|
#enddef
|
|
|
|
#define VARIABLE_CONDITIONAL VAR OP_NAME VALUE
|
|
# Macro to do conditional operations on variables.
|
|
[variable]
|
|
name={VAR}
|
|
{OP_NAME}={VALUE}
|
|
[/variable]
|
|
#enddef
|
|
|
|
#define CLEAR_VARIABLE VAR_NAME
|
|
# Macro to clear a variable previously set.
|
|
[clear_variable]
|
|
name={VAR_NAME}
|
|
[/clear_variable]
|
|
#enddef
|
|
|
|
#define CLEAR_GLOBAL_VARIABLE NAMESPACE MY_VARIABLE_NAME SIDE
|
|
# Clears a persistent variable entirely.
|
|
[clear_global_variable]
|
|
namespace={NAMESPACE}
|
|
global={MY_VARIABLE_NAME}
|
|
side={SIDE}
|
|
immediate=no
|
|
[/clear_global_variable]
|
|
#enddef
|
|
|
|
#define REPEAT NUMBER BODY_WML
|
|
# Macro to execute some WML a defined number of times.
|
|
#
|
|
# Example that causes screen to quake 5 times:
|
|
#! {REPEAT 5 (
|
|
#! {QUAKE "rumble.ogg"}
|
|
#! )}
|
|
{VARIABLE REPEAT_i 0}
|
|
|
|
[while]
|
|
[variable]
|
|
name=REPEAT_i
|
|
less_than={NUMBER}
|
|
[/variable]
|
|
|
|
[do]
|
|
{BODY_WML}
|
|
|
|
{VARIABLE_OP REPEAT_i add 1}
|
|
[/do]
|
|
[/while]
|
|
|
|
{CLEAR_VARIABLE REPEAT_i}
|
|
#enddef
|
|
|
|
#define LOOKUP_INDEX FROM_ARRAY_NAME WHERE_KEY_NAME WHERE_VALUE SAVE_AS_NAME
|
|
# Call this to lookup an array element that has a particular key-value pair
|
|
# then it saves the index of that element, or
|
|
# if the key-value pair is not found it saves the array's length
|
|
{VARIABLE {SAVE_AS_NAME} 0}
|
|
[while]
|
|
[variable]
|
|
name={SAVE_AS_NAME}
|
|
less_than=${FROM_ARRAY_NAME}.length
|
|
[/variable]
|
|
[variable]
|
|
name={FROM_ARRAY_NAME}[${SAVE_AS_NAME}].{WHERE_KEY_NAME}
|
|
not_equals={WHERE_VALUE}
|
|
[/variable]
|
|
[do]
|
|
{VARIABLE_OP {SAVE_AS_NAME} add 1}
|
|
[/do]
|
|
[/while]
|
|
#enddef
|
|
|
|
#define LOOKUP_VALUE FROM_ARRAY_NAME WHERE_KEY_NAME WHERE_VALUE SAVE_KEY_NAME DEFAULT_VALUE SAVE_AS_NAME
|
|
# Call this to look up an array element that has a particular key-value pair
|
|
# then it saves another key from that same element.
|
|
{LOOKUP_INDEX {FROM_ARRAY_NAME} {WHERE_KEY_NAME} {WHERE_VALUE} {SAVE_AS_NAME}}
|
|
[if]
|
|
[variable]
|
|
name={SAVE_AS_NAME}
|
|
numerical_equals=${FROM_ARRAY_NAME}.length
|
|
[/variable]
|
|
[then]
|
|
{VARIABLE {SAVE_AS_NAME} {DEFAULT_VALUE}}
|
|
[/then]
|
|
[else]
|
|
{VARIABLE {SAVE_AS_NAME} ${FROM_ARRAY_NAME}[${SAVE_AS_NAME}].{SAVE_KEY_NAME}}
|
|
[/else]
|
|
[/if]
|
|
#enddef
|
|
|
|
#define MODIFY_UNIT FILTER VAR VALUE
|
|
# Alters a unit variable (such as unit.x, unit.type,
|
|
# unit.side), handling all the storing and unstoring.
|
|
#
|
|
# Example that flips all spearmen to side 2:
|
|
#! {MODIFY_UNIT type=Spearman side 2}
|
|
[store_unit]
|
|
[filter]
|
|
{FILTER}
|
|
[/filter]
|
|
|
|
variable=MODIFY_UNIT_store
|
|
kill=yes
|
|
[/store_unit]
|
|
|
|
[foreach]
|
|
array=MODIFY_UNIT_store
|
|
[do]
|
|
[set_variable]
|
|
name=this_item.{VAR}
|
|
value={VALUE}
|
|
[/set_variable]
|
|
|
|
[unstore_unit]
|
|
variable=this_item
|
|
find_vacant=no
|
|
[/unstore_unit]
|
|
[/do]
|
|
[/foreach]
|
|
|
|
{CLEAR_VARIABLE MODIFY_UNIT_store}
|
|
#enddef
|
|
|
|
#define MOVE_UNIT_BY FILTER OFFSET_X OFFSET_Y
|
|
#TODO COMMENT
|
|
[store_unit]
|
|
[filter]
|
|
{FILTER}
|
|
[/filter]
|
|
|
|
variable=MOVE_UNIT_store
|
|
kill=yes
|
|
[/store_unit]
|
|
|
|
[for]
|
|
array=MOVE_UNIT_store
|
|
variable=MOVE_UNIT_BY_i
|
|
[do]
|
|
{VARIABLE_OP MOVE_UNIT_store[$MOVE_UNIT_BY_i].x add {OFFSET_X}}
|
|
{VARIABLE_OP MOVE_UNIT_store[$MOVE_UNIT_BY_i].y add {OFFSET_Y}}
|
|
[unstore_unit]
|
|
variable=MOVE_UNIT_store[$MOVE_UNIT_BY_i]
|
|
find_vacant=no
|
|
[/unstore_unit]
|
|
[/do]
|
|
[/for]
|
|
{CLEAR_VARIABLE MOVE_UNIT_store}
|
|
#enddef
|
|
|
|
#define MOVE_UNIT FILTER TO_X TO_Y
|
|
# Moves a unit from its current location to the given location, displaying
|
|
# movement normally.
|
|
#
|
|
# Note that setting the destination on an existing unit does not kill either
|
|
# one, but causes the unit to move to the nearest vacant hex instead.
|
|
[move_unit]
|
|
{FILTER}
|
|
to_x={TO_X}
|
|
to_y={TO_Y}
|
|
fire_event=no
|
|
[/move_unit]
|
|
#enddef
|
|
|
|
#define FULL_HEAL FILTER
|
|
[heal_unit]
|
|
[filter]
|
|
{FILTER}
|
|
[/filter]
|
|
|
|
amount=full
|
|
restore_statuses=yes
|
|
[/heal_unit]
|
|
#enddef
|
|
|
|
#define PUT_TO_RECALL_LIST FILTER
|
|
# This places a given unit back to the recall list of the side it is on.
|
|
# Note however, that the unit is not healed to full health, so when
|
|
# recalled (even if not until the next scenario) the unit may have less
|
|
# than his maximum hp left.
|
|
#
|
|
# An example that returns all units stepping on (20,38) back to the recall
|
|
# list:
|
|
#
|
|
#! [event]
|
|
#! name=moveto
|
|
#!
|
|
#! [filter]
|
|
#! x,y=20,38
|
|
#! [/filter]
|
|
#!
|
|
#! {PUT_TO_RECALL_LIST x,y=20,38}
|
|
#! [/event]
|
|
[put_to_recall_list]
|
|
{FILTER}
|
|
[/put_to_recall_list]
|
|
#enddef
|
|
|
|
#define RECRUIT_UNIT_VARIATIONS SIDE TYPE VARIATIONS_VALUE
|
|
# Allows a side to seemingly recruit variations of a given unit, such as the
|
|
# the Walking Corpse.
|
|
#
|
|
# An example which makes side 2 have a 50% chance of getting a normal WC
|
|
# and a 50% chance of getting either a drake or dwarf variation:
|
|
#! {RECRUIT_UNIT_VARIATIONS 2 "Walking Corpse" none,none,drake,dwarf}
|
|
[event]
|
|
name=prerecruit
|
|
first_time_only=no
|
|
|
|
[filter]
|
|
side={SIDE}
|
|
type={TYPE}
|
|
[/filter]
|
|
|
|
{VARIABLE_OP recruited_unit_random_variation rand {VARIATIONS_VALUE}}
|
|
|
|
[if]
|
|
[variable]
|
|
name=recruited_unit_random_variation
|
|
not_equals=none
|
|
[/variable]
|
|
|
|
[then]
|
|
[object]
|
|
duration=forever
|
|
silent=yes
|
|
|
|
[filter]
|
|
x,y=$x1,$y1
|
|
[/filter]
|
|
|
|
[effect]
|
|
apply_to=variation
|
|
name=$recruited_unit_random_variation
|
|
[/effect]
|
|
|
|
[effect]
|
|
apply_to=hitpoints
|
|
heal_full=yes
|
|
[/effect]
|
|
[/object]
|
|
[/then]
|
|
[/if]
|
|
|
|
{CLEAR_VARIABLE recruited_unit_random_variation}
|
|
[/event]
|
|
#enddef
|
|
|
|
#define SCATTER_UNITS NUMBER TYPES PADDING_RADIUS FILTER UNIT_WML
|
|
# Scatters the given kind of units randomly on a given area on the map.
|
|
#
|
|
# An example which scatters some loyal elves on forest hexes in
|
|
# x,y=10-30,20-40, at a minimum of three hexes apart from each other and
|
|
# never on top of or adjacent to any already existing units:
|
|
#! {SCATTER_UNITS 20 "Elvish Fighter,Elvish Archer,Elvish Shaman" 3 (
|
|
#! terrain=Gs^Fp
|
|
#! x=10-30
|
|
#! y=20-40
|
|
#!
|
|
#! [not]
|
|
#! [filter]
|
|
#! [/filter]
|
|
#! [/not]
|
|
#!
|
|
#! [not]
|
|
#! [filter_adjacent_location]
|
|
#! [filter]
|
|
#! [/filter]
|
|
#! [/filter_adjacent_location]
|
|
#! [/not]
|
|
#! ) (
|
|
#! side=2
|
|
#! generate_name=yes
|
|
#! random_traits=yes
|
|
#!
|
|
#! [modifications]
|
|
#! {TRAIT_LOYAL}
|
|
#! [/modifications]
|
|
#! )}
|
|
[set_variables]
|
|
name=unit_type_table
|
|
|
|
[split]
|
|
list={TYPES}
|
|
key=type
|
|
separator=,
|
|
[/split]
|
|
[/set_variables]
|
|
|
|
{VARIABLE unit_type_table_i 0}
|
|
|
|
[random_placement]
|
|
num_items={NUMBER}
|
|
variable=random_placement_location
|
|
allow_less=yes
|
|
min_distance={PADDING_RADIUS}
|
|
[filter_location]
|
|
{FILTER}
|
|
include_borders=no
|
|
[/filter_location]
|
|
[command]
|
|
[unit]
|
|
type=$unit_type_table[$unit_type_table_i].type
|
|
x,y=$random_placement_location.x,$random_placement_location.y
|
|
{UNIT_WML}
|
|
[/unit]
|
|
{VARIABLE unit_type_table_i ("$(($unit_type_table_i + 1) % $unit_type_table.length)")}
|
|
[/command]
|
|
[/random_placement]
|
|
|
|
{CLEAR_VARIABLE unit_type_table,unit_type_table_i,random_placement_location}
|
|
#enddef
|
|
|
|
#define FORCE_CHANCE_TO_HIT FILTER SECOND_FILTER CTH_NUMBER EXTRA_CONDITIONS_WML
|
|
# Invisibly forces certain units to always have a specific chance to hit
|
|
# when fighting against certain other units.
|
|
#
|
|
# Note that the player still only sees the regular damage calculations, so
|
|
# this is useful if you need to give an invisible helping hand to the player
|
|
# or AI. For example, if the player is forced to attack with only a couple
|
|
# of units at the beginning of a scenario, you can use this to ensure that
|
|
# simply having bad luck cannot ruin their attempt so easily. Also you might
|
|
# have enemy leaders which the player is not supposed to fight or be able to
|
|
# defeat due to storyline reasons, but could theoretically still kill with
|
|
# some clever trick, AI mistake or sheer exceptional luck.
|
|
#
|
|
# An example which forces Konrad's attacks to always hit Li'sar, but only
|
|
# after turn 10:
|
|
#! {FORCE_CHANCE_TO_HIT id=Konrad id="Li'sar" 100 (
|
|
#! [variable]
|
|
#! name=turn_number
|
|
#! greater_than=10
|
|
#! [/variable]
|
|
#! )}
|
|
[event]
|
|
name=attack
|
|
first_time_only=no
|
|
|
|
[filter]
|
|
{FILTER}
|
|
[/filter]
|
|
|
|
[filter_second]
|
|
{SECOND_FILTER}
|
|
[/filter_second]
|
|
|
|
[filter_condition]
|
|
[and]
|
|
{EXTRA_CONDITIONS_WML}
|
|
[/and]
|
|
[/filter_condition]
|
|
|
|
[foreach]
|
|
array=unit.attack
|
|
[do]
|
|
[if]
|
|
#This is to mute a warning message about retrieving a member of non-existant wml container.
|
|
[variable]
|
|
name=this_item.specials.length
|
|
greater_than=0
|
|
[/variable]
|
|
|
|
[variable]
|
|
name=this_item.specials.chance_to_hit.length
|
|
greater_than=0
|
|
[/variable]
|
|
|
|
[then]
|
|
[set_variables]
|
|
name=this_item.specials.original_chance_to_hit
|
|
to_variable=this_item.specials.chance_to_hit
|
|
[/set_variables]
|
|
|
|
{CLEAR_VARIABLE this_item.specials.chance_to_hit}
|
|
[/then]
|
|
[/if]
|
|
|
|
[set_variables]
|
|
name=this_item.specials.chance_to_hit
|
|
|
|
[value]
|
|
id=forced_cth
|
|
value={CTH_NUMBER}
|
|
cumulative=no
|
|
[/value]
|
|
[/set_variables]
|
|
[/do]
|
|
[/foreach]
|
|
|
|
[unstore_unit]
|
|
variable=unit
|
|
find_vacant=no
|
|
[/unstore_unit]
|
|
|
|
[event]
|
|
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]
|
|
{CLEAR_VARIABLE this_item.specials.chance_to_hit}
|
|
|
|
[set_variables]
|
|
name=this_item.specials.chance_to_hit
|
|
to_variable=this_item.specials.original_chance_to_hit
|
|
[/set_variables]
|
|
|
|
{CLEAR_VARIABLE this_item.specials.original_chance_to_hit}
|
|
[/do]
|
|
[/foreach]
|
|
|
|
[unstore_unit]
|
|
variable=unit
|
|
find_vacant=no
|
|
[/unstore_unit]
|
|
[/event]
|
|
[/event]
|
|
|
|
# The following event is a simple duplicates of the above ones, with the
|
|
# primary and secondary units reversed so that the effect is applied also on
|
|
# defense.
|
|
[event]
|
|
name=attack
|
|
first_time_only=no
|
|
|
|
[filter]
|
|
{SECOND_FILTER}
|
|
[/filter]
|
|
|
|
[filter_second]
|
|
{FILTER}
|
|
[/filter_second]
|
|
|
|
[filter_condition]
|
|
[and]
|
|
{EXTRA_CONDITIONS_WML}
|
|
[/and]
|
|
[/filter_condition]
|
|
|
|
[foreach]
|
|
array=second_unit.attack
|
|
[do]
|
|
[if]
|
|
[variable]
|
|
name=this_item.specials.length
|
|
greater_than=0
|
|
[/variable]
|
|
|
|
[variable]
|
|
name=this_item.specials.chance_to_hit.length
|
|
greater_than=0
|
|
[/variable]
|
|
|
|
[then]
|
|
[set_variables]
|
|
name=this_item.specials.original_chance_to_hit
|
|
to_variable=this_item.specials.chance_to_hit
|
|
[/set_variables]
|
|
|
|
{CLEAR_VARIABLE this_item.specials.chance_to_hit}
|
|
[/then]
|
|
[/if]
|
|
|
|
[set_variables]
|
|
name=this_item.specials.chance_to_hit
|
|
|
|
[value]
|
|
id=forced_cth
|
|
value={CTH_NUMBER}
|
|
cumulative=no
|
|
[/value]
|
|
[/set_variables]
|
|
[/do]
|
|
[/foreach]
|
|
|
|
[unstore_unit]
|
|
variable=second_unit
|
|
find_vacant=no
|
|
[/unstore_unit]
|
|
|
|
[event]
|
|
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]
|
|
{CLEAR_VARIABLE this_item.specials.chance_to_hit}
|
|
|
|
[set_variables]
|
|
name=this_item.specials.chance_to_hit
|
|
to_variable=this_item.specials.original_chance_to_hit
|
|
[/set_variables]
|
|
|
|
{CLEAR_VARIABLE this_item.specials.original_chance_to_hit}
|
|
[/do]
|
|
[/foreach]
|
|
|
|
[unstore_unit]
|
|
variable=second_unit
|
|
find_vacant=no
|
|
[/unstore_unit]
|
|
[/event]
|
|
[/event]
|
|
#enddef
|
|
|
|
#define LOOT AMOUNT SIDE
|
|
{VARIABLE amount_gold {AMOUNT}}
|
|
|
|
#TODO add message for the other players!
|
|
[message]
|
|
side_for={SIDE}
|
|
speaker=narrator
|
|
message= _ "You retrieve $amount_gold pieces of gold."
|
|
image=wesnoth-icon.png
|
|
sound=gold.ogg
|
|
[/message]
|
|
|
|
{CLEAR_VARIABLE amount_gold}
|
|
|
|
[gold]
|
|
side={SIDE}
|
|
amount={AMOUNT}
|
|
[/gold]
|
|
#enddef
|
|
|
|
#define CREDITS_SEPARATOR
|
|
[entry]
|
|
name = "•"
|
|
[/entry]
|
|
#enddef
|