Difference between revisions of "EventWML"

From The Battle for Wesnoth Wiki
m (The [event] tag: indented all the bullet items that are values for 'name' and moved [allow_undo] blurb up to moveto tag it is relevant to)
(Called out name as mandatory and extensive formatting overhaul.)
Line 1: Line 1:
 
{{WML Tags}}
 
{{WML Tags}}
== The [event] tag ==
+
== The [event] Tag ==
  
 
This tag is a subtag of the [scenario], [unit] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit] type definition, the event will occur in all scenarios in which a unit of that type appears in. When used in an [era], the event will occur in any scenario which is played using that era.
 
This tag is a subtag of the [scenario], [unit] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit] type definition, the event will occur in all scenarios in which a unit of that type appears in. When used in an [era], the event will occur in any scenario which is played using that era.
  
Keys and tags that describe when the event should trigger:
+
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.
* '''name''': this is not like a normal 'name' key. It is a basic description of when the event will trigger. {{DevFeature}} '''name''' can accept a list of commas separated descriptions for which the event must be triggered. Example: '''name= attacker_misses, defender_misses'''. Note that unless you use ''first_time_only=no'', the event will fire only once, not once for each listed type.
 
** '''prestart''': the event is triggered before a scenario 'starts' -- before anything is shown on the screen at all. You can use this event to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start'''.
 
** '''start''': this event triggers after the map is shown but before the scenario begins
 
** '''new turn''': this event triggers whenever the last player ends their turn. See also '''first_time_only=no'''. When the last player ends their turn, before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.
 
** '''side turn''': this event triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.
 
** '''turn refresh''': this event triggers just before a side is taking control after healing, calculating income, and restoring unit movement and status.
 
** '''turn X''': (for X some number) this event triggers at the start of turn ''X''. ''X'' cannot be 1.
 
** '''time over''': this event triggers on turn ''turns''. (''turns'' is specified in [scenario])
 
** '''enemies defeated''': this event triggers when all units with '''canrecruit=yes''' (i.e. all leaders) not allied with side 1 are killed.
 
** '''victory''': in this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also [endlevel], [[DirectActionsWML]])
 
** '''defeat''': in this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])
 
** '''ai turn''': is triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side.
 
  
: Filters can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true.
+
=== The 'name' Key (Mandatory) ===
: These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]
 
  
:* '''moveto''': triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.
+
Usage:
:: ''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.''
+
name=<value>
  
:* '''sighted''': this event triggers when the primary unit becomes visible to the secondary unit in particular after not being visible to the secondary unit's side (so if the secondary unit's side doesn't have shroud or fog, the event never triggers). This happens both when the primary unit moves into view during its turn, and when the secondary unit moves to a location where it can see the primary unit. (This editor hasn't tested whether the event triggers multiple times if the primary unit moves into view of multiple units at once, or if not, which one gets chosen to be the secondary unit here.) (Note: it appears that when a sighted event is triggered because an enemy unit moves into your field of view, the game engine cannot determine which unit (on your side) sees the unit that moved, and so it fires a ''name=sighted'' event without setting ''$second_unit''. This means that, for example, using ''speaker=second_unit'' inside a message tag may fail.)
+
This is '''not''' like a normal 'name' key. ''It is a basic description of when the event will trigger.'' It also has a very large number of predefined values, one of which must be used for the key to be valid.
:* '''attack''': this event triggers when the primary unit attacks the secondary unit.
 
:* '''attacker_hits''': this event triggers when the the primary unit (the attacker) hits the secondary unit (the defender). {{DevFeature}} A variable '''$damage_inflicted''' allow to check the number of hitpoints inflicted by the attacker.
 
:* '''attacker_misses''': same as ''attacker_hits'', but is triggered when the attacker misses.
 
:* '''defender_hits''': this event triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). {{DevFeature}} A variable '''$damage_inflicted''' allow to check the number of hitpoints inflicted by the defender.
 
:* '''defender_misses''': same as ''defender_hits'', but is triggered when the defender misses.
 
:* '''attack_end''': is similar to '''attack''', but is instead triggered after the fight, not before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.
 
:* '''stone''': this event triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability).
 
:* '''last breath''': this event triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered.
 
:* '''die''': this event triggers when the primary unit is killed by the secondary unit.
 
:* '''capture''': this event triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.
 
:* '''recruit''': this event triggers when the primary unit is recruited or recalled. (That is, when a unit is recruited or recalled, it will trigger this event and this event's filter will filter that unit.). {{DevFeature}} The '''recruit''' will no longer triggers on recalls.
 
:* '''prerecruit''': this event triggers when the primary unit is recruited, but before it is displayed. {{DevFeature}} The '''prerecruit''' will no longer triggers on recalls.
 
:* '''advance''': this event triggers just before the primary unit is going to advance to another unit.
 
:* '''post_advance''': this event triggers just after the primary unit has advanced to another unit.
 
:* '''select''': triggers when the primary unit is selected. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''
 
:* '''menu item X''': triggers when a WML menu item with id=X is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''
 
:* {{DevFeature}} '''prerecall''': triggers when a unit is recalled, but before it is displayed. This event is not trigger when a unit is recruit.
 
:* {{DevFeature}} '''recall''': triggers after a unit is recalled. This event is not trigger when a unit is recruit.
 
:* {{DevFeature}} other events with a custom name may be invoked from [fire_event]
 
:* {{DevFeature}} '''consider attack''': triggers before the attack dialog is displayed.
 
:* {{DevFeature}} '''unconsider attack''': triggers when canceling out of the attack dialog.
 
  
The primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the speaker= key. For example:
+
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''
  
  [event]
+
{{DevFeature}} The '''name''' key can accept a list of comma separated values describing when the event will be triggered.*
name=die
+
 
  [message]
+
For example:
  speaker=second_unit
+
 
  message="Hahaha, I finally killed you!"
+
  name=attacker_misses,defender_misses
  [/message]
+
 
+
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''
  [message]
+
 
  speaker=unit
+
==== Valid 'name' Key Values ====
  message="It's not over yet! I'll come back to haunt you!"
+
 
  [/message]
+
All valid values are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here will '''not''' work ''no matter how logical or awesome you think it sounds.''
[/event]
+
 
 +
; prestart
 +
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.
 +
 
 +
; start
 +
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.
 +
 
 +
; new turn
 +
: Triggers whenever the last player ends their turn. See also [[#first_time_only|first_time_only=no]]. When the last player ends their turn, before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.
 +
 
 +
; side turn
 +
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.
 +
 
 +
; ai turn
 +
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side.
 +
 
 +
; turn refresh
 +
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.
 +
 
 +
; turn ''X''
 +
: For ''X'' equals a number greater than 1, this event triggers at the start of turn ''X''. The value of ''X'' cannot be 1 but, if that effect is needed, use '''name=new turn''' and '''first_time_only=yes''' to achieve the equivalent of what '''turn 1''' would do.
 +
 
 +
; time over
 +
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])
 +
 
 +
; enemies defeated
 +
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.
 +
 
 +
; victory
 +
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])
 +
 
 +
; defeat
 +
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])
 +
 
 +
 
 +
Filters can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true.
 +
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]
 +
 
 +
; moveto
 +
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.''
 +
 
 +
; sighted
 +
: Triggers when the primary unit becomes visible to the secondary unit in particular after not being visible to the secondary unit's side (so if the secondary unit's side doesn't have shroud or fog, the event never triggers). This happens both when the primary unit moves into view during its turn, and when the secondary unit moves to a location where it can see the primary unit. (This editor hasn't tested whether the event triggers multiple times if the primary unit moves into view of multiple units at once, or if not, which one gets chosen to be the secondary unit here.) (Note: it appears that when a sighted event is triggered because an enemy unit moves into your field of view, the game engine cannot determine which unit (on your side) sees the unit that moved, and so it fires a ''name=sighted'' event without setting ''$second_unit''. This means that, for example, using ''speaker=second_unit'' inside a message tag may fail.)
 +
 
 +
; attack
 +
: Triggers when the primary unit attacks the secondary unit.
 +
 
 +
; attack_end
 +
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.
 +
 
 +
; attacker_hits
 +
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender).<br />{{DevFeature}} The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.
 +
 
 +
; attacker_misses
 +
: Same as ''attacker_hits'', but is triggered when the attacker misses.
 +
 
 +
; defender_hits
 +
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender).<br />{{DevFeature}} The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.
 +
 
 +
; defender_misses
 +
: Same as ''defender_hits'', but is triggered when the defender misses.
 +
 
 +
; stone
 +
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability).
 +
 
 +
; last breath
 +
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered.
 +
 
 +
; die
 +
: Triggers when the primary unit is killed by the secondary unit.
 +
 
 +
; capture
 +
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.
 +
 
 +
; recruit
 +
: Triggers when the primary unit is recruited or recalled. (That is, when a unit is recruited or recalled, it will trigger this event and this event's filter will filter that unit.). {{DevFeature}} The '''recruit''' will no longer triggers on recalls.
 +
 
 +
; prerecruit
 +
: Triggers when the primary unit is recruited, but before it is displayed. {{DevFeature}} The '''prerecruit''' will no longer triggers on recalls.
 +
 
 +
; advance
 +
: Triggers just before the primary unit is going to advance to another unit.
 +
 
 +
; post_advance
 +
: Triggers just after the primary unit has advanced to another unit.
 +
 
 +
; select
 +
: Triggers when the primary unit is selected. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''
 +
 
 +
; menu item X
 +
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''
 +
 
 +
; {{DevFeature}} prerecall
 +
: Triggers when a unit is recalled, but before it is displayed. This event is not trigger when a unit is recruit.
 +
 
 +
; {{DevFeature}} recall
 +
: Triggers after a unit is recalled. This event is not trigger when a unit is recruit.
 +
 
 +
; {{DevFeature}} consider attack
 +
: Triggers before the attack dialog is displayed.
 +
 
 +
; {{DevFeature}} unconsider attack
 +
: Triggers when canceling out of the attack dialog.
 +
 
 +
; {{DevFeature}} Other events with a custom name may be invoked from [fire_event]
 +
 
 +
=== Optional Keys and Tags ===
  
 
These keys and tags are more complex ways to filter when an event should trigger:
 
These keys and tags are more complex ways to filter when an event should trigger:
* '''first_time_only''': whether the event should be removed from the scenario after it is triggered. Default is '''yes'''.
+
 
* '''[filter]''': the event will only trigger if the primary unit matches this filter.
+
==== first_time_only ====
** [[StandardUnitFilter]]: selection criteria
+
: Whether the event should be removed from the scenario after it is triggered. There are two possible values for this key:
* '''[filter_second]''': is like [filter], but for the secondary unit.
+
: ''first_time_only=yes''
** [[StandardUnitFilter]]: selection criteria
+
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.
* '''[special_filter]''' and '''[special_filter_second]''': can be used to set some additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker_hits'', ''attacker_misses'', ''defender_hits'', ''defender_misses'' and ''attack_end''. ({{DevFeature}} renamed to [filter_attack] and [filter_second_attack])
+
: ''first_time_only=no''
** '''weapon''': the name of the weapon used. ({{DevFeature}} renamed to '''name''')
+
:: The event will every time the criteria are met instead of only the first time.
** {{DevFeature}} '''range''': the range of the weapon used.  
+
 
 +
==== [filter] ====
 +
: The event will only trigger if the primary unit matches this filter.
 +
:* [[StandardUnitFilter]]: selection criteria
 +
 
 +
==== [filter_second] ====
 +
: Like [filter], but for the secondary unit.
 +
:* [[StandardUnitFilter]]: selection criteria
 +
 
 +
==== [special_filter] ====
 +
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker_hits'', ''attacker_misses'', ''defender_hits'', ''defender_misses'' and ''attack_end''. ({{DevFeature}} renamed to [filter_attack])
 +
:* '''weapon''': the name of the weapon used. ({{DevFeature}} renamed to '''name''')
 +
:* {{DevFeature}} '''range''': the range of the weapon used.
 +
 
 +
==== [special_filter_second] ====
 +
: Like [special_filter], but for the secondary unit. ({{DevFeature}} renamed to [filter_second_attack])
 +
:* '''weapon''': the name of the weapon used. ({{DevFeature}} renamed to '''name''')
 +
:* {{DevFeature}} '''range''': the range of the weapon used.
 +
 
 +
==== [event] ====
 +
: A special case 'action', the [event] tag may be used to create a [[#Nested Event|nested event]].
 +
 
 +
==== delayed_variable_substitution ====
 +
: This key is only relevant inside of a [[#Nested Event|nested event]] and controls when variable substitution will occur in those special case actions.
  
 
=== Actions triggered by [event] ===
 
=== Actions triggered by [event] ===
Line 85: Line 180:
 
"standard unit filter" and "standard location filter".
 
"standard unit filter" and "standard location filter".
  
=== Nested events ===
+
=== Nested Events ===
  
There is 1 special type of action: event creation.  By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is created when the nested event is encountered (when executing the contents of the event).  For example, you could create a portal that opens on turn 10.  The outer event executes on turn 10, creating the nested moveto event, which executes when a player steps on a certain spot.  An equivalent way of doing this would be to a single moveto event with an '''[if]''' statement to check for turn number, but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.
+
There is one special type of action: event creation.  By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).
  
Example:
+
([[#Nested Event Example|See Examples]])
 +
 
 +
==== Delayed Variable Substitution ====
 +
 
 +
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.
 +
 
 +
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.
 +
 
 +
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.
 +
 
 +
([[#Delayed Variable Substitution Example|See Examples]])
 +
 
 +
== Miscellaneous Notes and Examples ==
 +
 
 +
=== Primary/Secondary Unit Speaker Example ===
 +
 
 +
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:
 +
 
 +
[event]
 +
    name=die
 +
    [message]
 +
        speaker='''second_unit'''
 +
        message= _ "Hahaha! I finally killed you!"
 +
    [/message]
 +
 +
    [message]
 +
        speaker='''unit'''
 +
        message= _ "It's not over yet! I'll come back to haunt you!"
 +
    [/message]
 +
[/event]
 +
 
 +
=== Nested Event Example ===
 +
 
 +
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.
  
 
  [event]
 
  [event]
Line 105: Line 233:
 
  [/event]
 
  [/event]
  
Variable substitution for a nested event can happen either when the event is spawned, or when it is triggered. This is controlled with the key ''delayed_variable_substitution'' (default yes). Consider the following two examples:
+
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.
  
# This makes the message display the turn on which the moveto happens,
+
=== Delayed Variable Substitution Example ===
  # because the variable substitution for the moveto event will be done
+
 
# when the event triggers.
+
This code will display the turn on which the nested ''moveto'' event happens.
 +
 
 +
  [event]
 +
    name=turn 10
 
   
 
   
 +
    [event]
 +
        name=moveto
 +
        delayed_variable_substitution=yes
 +
 +
        [filter]
 +
            x,y=5,8
 +
        [/filter]
 +
 +
        {DEBUG_MSG "Turn $turn_number"}
 +
    [/event]
 +
[/event]
 +
 +
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.
 +
 
  [event]
 
  [event]
     name=turn 2
+
     name=turn 10
 
   
 
   
 
     [event]
 
     [event]
 
         name=moveto
 
         name=moveto
        delayed_variable_substitution=yes
 
 
   
 
   
         {DEBUG_MSG "Turn $turn_number"}
+
        [filter]
    [/event]
+
            x,y=5,8
 +
        [/filter]
 +
 +
         {DEBUG_MSG "Turn $turn_number"}  
 +
    [/event]
 
  [/event]
 
  [/event]
  
# This makes the message on moveto always display as "Turn 2", because
+
This code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.
# the variable substitution is done when the moveto event is spawned,
 
# not when it eventually triggers.
 
 
   
 
   
 
  [event]
 
  [event]
     name=turn 2
+
     name=turn 10
 
   
 
   
 
     [event]
 
     [event]
Line 133: Line 279:
 
         delayed_variable_substitution=no
 
         delayed_variable_substitution=no
 
   
 
   
         {DEBUG_MSG "Turn $turn_number"}
+
        [filter]
    [/event]
+
            x,y=5,8
 +
        [/filter]
 +
 +
         {DEBUG_MSG "Turn $turn_number"}  
 +
    [/event]
 
  [/event]
 
  [/event]
  
Another way to mark an individual variable to be substituted later (when the event is triggered) is to  write it as "$|var" instead of the normal "$var". By combining this with delayed_variable_substitution=no you can have some variables in the nested event be substituted immediately when the event is spawned and some variables substituted when the event triggers.
+
Finally, this example is identical to the first two, in that it will display the turn on which the nested ''moveto'' event happens despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.
 +
 
 +
[event]
 +
    name=turn 10
 +
 +
    [event]
 +
        name=moveto
 +
        delayed_variable_substitution=no
 +
 +
        [filter]
 +
            x,y=5,8
 +
        [/filter]
 +
 +
        {DEBUG_MSG "Turn $|turn_number"}
 +
    [/event]
 +
[/event]
  
 
== See Also ==
 
== See Also ==

Revision as of 17:23, 27 February 2009

[edit]WML Tags

A:

abilities, about, achievement, achievement_group, add_ai_behavior, advanced_preference, advancefrom, advancement, advances, affect_adjacent, ai, allied_with, allow_end_turn, allow_extra_recruit, allow_recruit, allow_undo, and, animate, animate_unit, animation, aspect, attack (replay, weapon), attack_anim, attacks (special, stats), avoid;

B:

base_unit, background_layer, berserk, binary_path, break, brush;

C:

campaign, cancel_action, candidate_action, capture_village, case, chance_to_hit, change_theme, chat, checkbox, choice, choose, clear_global_variable, clear_menu_item, clear_variable, color_adjust, color_palette, color_range, command (action, replay), continue, credits_group, criteria;

D:

damage, death, deaths, default, defend, defends, defense, delay, deprecated_message, destination, difficulty, disable, disallow_end_turn, disallow_extra_recruit, disallow_recruit, do, do_command, drains, draw_weapon_anim;

E:

editor_group, editor_music, editor_times, effect, else (action, animation), elseif, endlevel, end_turn (action, replay), enemy_of, engine, entry (credits, options), era, event, experimental_filter_ability, experimental_filter_ability_active, experimental_filter_specials, extra_anim;

F:

facet, facing, fake_unit, false, feedback, female, filter (concept, event), filter_adjacent, filter_adjacent_location, filter_attack, filter_attacker, filter_base_value, filter_condition, filter_defender, filter_enemy, filter_location, filter_opponent, filter_own, filter_owner, filter_radius, filter_recall, filter_second, filter_second_attack, filter_self, filter_side, filter_student, filter_vision, filter_weapon, filter_wml, find_path, fire_event, firststrike, floating_text, found_item, for, foreach, frame;

G:

game_config, get_global_variable, goal, gold, gold_carryover;

H:

harm_unit, has_ally, has_attack, has_unit, has_achievement, have_location, have_unit, heal_on_hit, heal_unit, healed_anim, healing_anim, heals, hide_help, hide_unit, hides;

I:

idle_anim, if (action, animation, intro), illuminates, image (intro, terrain), init_side, insert_tag, inspect, item, item_group;

J:

jamming_costs, join;

K:

kill, killed;

L:

label, language, leader, leader_goal, leadership, leading_anim, levelin_anim, levelout_anim, lift_fog, limit, literal, load_resource, locale, lock_view, lua;

M:

male, menu_item, message, micro_ai, missile_frame, modification, modifications, modify_ai, modify_side, modify_turns, modify_unit, modify_unit_type, move, move_unit, move_unit_fake, move_units_fake, movement_anim, movement costs, movetype, multiplayer, multiplayer_side, music;

N:

not, note;

O:

object, objective, objectives, on_undo, open_help, option, options, or;

P:

part, petrifies, petrify, place_shroud, plague, poison, post_movement_anim, pre_movement_anim, primary_attack, primary_unit, print, progress_achievement, put_to_recall_list;

R:

race, random_placement, recall (action, replay), recalls, recruit, recruit_anim, recruiting_anim, recruits, redraw, regenerate, remove_event, remove_item, remove_object, remove_shroud, remove_sound_source, remove_time_area, remove_trait, remove_unit_overlay, repeat, replace_map, replace_schedule, replay, replay_start, reset_fog, resistance (ability, unit), resistance_defaults, resource, return, role, rule;

S:

save, scenario, screen_fade, scroll, scroll_to, scroll_to_unit, secondary_attack, secondary_unit, section, select_unit, sequence, set_achievement, set_extra_recruit, set_global_variable, set_menu_item, set_recruit, set_specials, set_variable, set_variables, sheath_weapon_anim, show_if (message, objective, set_menu_item), show_objectives, side, skirmisher, slider, slow, snapshot, sound, sound_source, source (replay, teleport), special_note, specials, split, stage, standing_anim, statistics, status, store_gold, store_items, store_locations, store_map_dimensions, store_reachable_locations, store_relative_direction, store_side, store_starting_location, store_time_of_day, store_turns, store_unit, store_unit_defense, store_unit_defense_on, store_unit_type, store_unit_type_ids, store_villages, story, swarm, sub_achievement, switch, sync_variable;

T:

target, team, teleport (ability, action), teleport_anim, terrain, terrain_defaults, terrain_graphics, terrain_mask, terrain_type, test, test_condition, test_do_attack_by_id, text_input, textdomain, theme, then, tile, time, time_area, topic, toplevel, trait, transform_unit, traveler, true, tunnel;

U:

unhide_unit, unit, unit_overlay, unit_type, unit_worth, units, unlock_view, unpetrify, unstore_unit, unsynced;

V:

value, variable, variables, variant, variation, victory_anim, village, vision_costs, volume;

W:

while, wml_message, wml_schema;

Z:

zoom;

The [event] Tag

This tag is a subtag of the [scenario], [unit] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit] type definition, the event will occur in all scenarios in which a unit of that type appears in. When used in an [era], the event will occur in any scenario which is played using that era.

This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the name key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.

The 'name' Key (Mandatory)

Usage:

name=<value>

This is not like a normal 'name' key. It is a basic description of when the event will trigger. It also has a very large number of predefined values, one of which must be used for the key to be valid.

Lexicon side note: It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing name=moveto, a person might refer to the event as a 'moveto event' and/or refer to the 'moveto trigger' in the event or even talk about the 'event trigger' when referring to the moveto value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.

Template:DevFeature The name key can accept a list of comma separated values describing when the event will be triggered.*

For example:

name=attacker_misses,defender_misses

* Note that unless you use first_time_only=no, the event will fire only once, not once for each listed type.

Valid 'name' Key Values

All valid values are listed here along with a description of when this value will cause the event to be triggered. Any value not listed here will not work no matter how logical or awesome you think it sounds.

prestart
Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use start instead.
start
Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.
new turn
Triggers whenever the last player ends their turn. See also first_time_only=no. When the last player ends their turn, before any events of this type trigger, the value of the WML variable turn_number is set to the number of the turn that is beginning.
side turn
Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable side_number is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.
ai turn
Triggered just before the AI is invoked for a side. This is called after side turn, and thus the WML variable side_number still holds the number of this side.
turn refresh
Like side turn, triggers just before a side is taking control but after healing, calculating income, and restoring unit movement and status.
turn X
For X equals a number greater than 1, this event triggers at the start of turn X. The value of X cannot be 1 but, if that effect is needed, use name=new turn and first_time_only=yes to achieve the equivalent of what turn 1 would do.
time over
Triggers on turn turns. (turns is specified in [scenario])
enemies defeated
Triggers when all units with canrecruit=yes (that is, all leaders) not allied with side 1 are killed.
victory
In this scenario, any tag of the form [endlevel] result=victory [/endlevel] will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], DirectActionsWML)
defeat
In this scenario, any tag of the form [endlevel] result=defeat [/endlevel] will be automatically preceded by all actions in this tag. (See also [endlevel], DirectActionsWML)


Filters can be applied to the following event triggers (see FilterWML; see also below). The actions specified in the event tag will be executed only if the filter returns true. These event triggers are all actions by units (moveto, attack) or things that happen to units (recruit, advance). When one of these events is triggered, the position of the active unit (referred to as the primary unit) is stored in the variables x1 and y1 and the position of any unit that primary unit does something to is stored in the variables x2 and y2 (this unit is referred to as the secondary unit below). These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the [store_unit] tag. see SingleUnitWML

moveto
Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.
An [allow_undo] tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.
sighted
Triggers when the primary unit becomes visible to the secondary unit in particular after not being visible to the secondary unit's side (so if the secondary unit's side doesn't have shroud or fog, the event never triggers). This happens both when the primary unit moves into view during its turn, and when the secondary unit moves to a location where it can see the primary unit. (This editor hasn't tested whether the event triggers multiple times if the primary unit moves into view of multiple units at once, or if not, which one gets chosen to be the secondary unit here.) (Note: it appears that when a sighted event is triggered because an enemy unit moves into your field of view, the game engine cannot determine which unit (on your side) sees the unit that moved, and so it fires a name=sighted event without setting $second_unit. This means that, for example, using speaker=second_unit inside a message tag may fail.)
attack
Triggers when the primary unit attacks the secondary unit.
attack_end
Similar to attack, but is triggered after the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any die events.
attacker_hits
Triggers when the the primary unit (the attacker) hits the secondary unit (the defender).
Template:DevFeature The value of the WML variable damage_inflicted is set to the number of hitpoints inflicted by the attacker.
attacker_misses
Same as attacker_hits, but is triggered when the attacker misses.
defender_hits
Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender).
Template:DevFeature The value of the WML variable damage_inflicted is set to the number of hitpoints inflicted by the defender.
defender_misses
Same as defender_hits, but is triggered when the defender misses.
stone
Triggers when the primary unit is hit by an attack with the 'stones' ability (See stones, AbilitiesWML) by the secondary unit (the unit with the 'stones' ability).
last breath
Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered.
die
Triggers when the primary unit is killed by the secondary unit.
capture
Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.
recruit
Triggers when the primary unit is recruited or recalled. (That is, when a unit is recruited or recalled, it will trigger this event and this event's filter will filter that unit.). Template:DevFeature The recruit will no longer triggers on recalls.
prerecruit
Triggers when the primary unit is recruited, but before it is displayed. Template:DevFeature The prerecruit will no longer triggers on recalls.
advance
Triggers just before the primary unit is going to advance to another unit.
post_advance
Triggers just after the primary unit has advanced to another unit.
select
Triggers when the primary unit is selected. Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.
menu item X
Triggers when a WML menu item with id=X is selected. Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.
Template:DevFeature prerecall
Triggers when a unit is recalled, but before it is displayed. This event is not trigger when a unit is recruit.
Template:DevFeature recall
Triggers after a unit is recalled. This event is not trigger when a unit is recruit.
Template:DevFeature consider attack
Triggers before the attack dialog is displayed.
Template:DevFeature unconsider attack
Triggers when canceling out of the attack dialog.
Template:DevFeature Other events with a custom name may be invoked from [fire_event]

Optional Keys and Tags

These keys and tags are more complex ways to filter when an event should trigger:

first_time_only

Whether the event should be removed from the scenario after it is triggered. There are two possible values for this key:
first_time_only=yes
Default behavior if key is omitted. The event will trigger the first time it can and never again.
first_time_only=no
The event will every time the criteria are met instead of only the first time.

[filter]

The event will only trigger if the primary unit matches this filter.

[filter_second]

Like [filter], but for the secondary unit.

[special_filter]

Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events attack, attacker_hits, attacker_misses, defender_hits, defender_misses and attack_end. (Template:DevFeature renamed to [filter_attack])

[special_filter_second]

Like [special_filter], but for the secondary unit. (Template:DevFeature renamed to [filter_second_attack])

[event]

A special case 'action', the [event] tag may be used to create a nested event.

delayed_variable_substitution

This key is only relevant inside of a nested event and controls when variable substitution will occur in those special case actions.

Actions triggered by [event]

After the trigger conditions have been met, all action tags within the [event] tag are executed in the order they are written in.

There are 3 main types of actions:

Several actions use standard filters to find out which units to execute the command on. These are denoted by the phrases "standard unit filter" and "standard location filter".

Nested Events

There is one special type of action: event creation. By placing an [event] tag inside another [event] tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).

(See Examples)

Delayed Variable Substitution

Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key delayed_variable_substitution which is used in the nested event.

If this key is set to yes, the variables in the nested event will contain values from the turn in which the nested event was triggered. This is the default behavior if the key is omitted. If set to no, the variables in the nested event are set at the time the parent event is triggered.

This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal $variable syntax, use $|variable to cause a variable to contain values relevant to the turn in which the nested event was triggered even when delayed_variable_substitution is set to no. In this way you can have a mix of variables relevant to the parent and nested event trigger times.

(See Examples)

Miscellaneous Notes and Examples

Primary/Secondary Unit Speaker Example

In events, the primary unit can be referred to as unit and the secondary unit can be referred to as second_unit in [message] tags using the speaker key. For example:

[event]
    name=die
    [message]
        speaker=second_unit
        message= _ "Hahaha! I finally killed you!"
    [/message]

    [message]
        speaker=unit
        message= _ "It's not over yet! I'll come back to haunt you!"
    [/message]
[/event]

Nested Event Example

An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.

[event]
    name=turn 10

    [event]
        name=moveto

        [filter]
            x,y=5,8
        [/filter]

        # moving to 5,8 will trigger this event only on turn 10 and after
    [/event]
[/event]

An equivalent way of doing this would be to create a single moveto event with an [if] statement to check for turn number but using nested [event] tags is a convenient shortcut to accomplish this task without resorting to [if] statements.

Delayed Variable Substitution Example

This code will display the turn on which the nested moveto event happens.

[event]
    name=turn 10

    [event]
        name=moveto
        delayed_variable_substitution=yes

        [filter]
            x,y=5,8
        [/filter]

        {DEBUG_MSG "Turn $turn_number"} 
   [/event]
[/event]

Since this is the default behavior for the delayed_variable_substitution key, the following example is identical.

[event]
    name=turn 10

    [event]
        name=moveto

        [filter]
            x,y=5,8
        [/filter]

        {DEBUG_MSG "Turn $turn_number"} 
   [/event]
[/event]

This code will always display "Turn 10" when the nested moveto event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, not when the nested event is triggered.

[event]
    name=turn 10

    [event]
        name=moveto
        delayed_variable_substitution=no

        [filter]
            x,y=5,8
        [/filter]

        {DEBUG_MSG "Turn $turn_number"} 
   [/event]
[/event]

Finally, this example is identical to the first two, in that it will display the turn on which the nested moveto event happens despite the fact that the delayed_variable_substitution key is set to no. This is because the special $|variable syntax is used.

[event]
    name=turn 10

    [event]
        name=moveto
        delayed_variable_substitution=no

        [filter]
            x,y=5,8
        [/filter]

        {DEBUG_MSG "Turn $|turn_number"} 
   [/event]
[/event]

See Also