Difference between revisions of "DirectActionsWML"
m (→[transform_unit]) |
m (→[modify_unit]: - correct description of hitpoints example) |
||
(121 intermediate revisions by 27 users not shown) | |||
Line 11: | Line 11: | ||
When the result is "victory" the following keys can be used: | When the result is "victory" the following keys can be used: | ||
− | * '''bonus''': whether the player should get bonus gold (maximum possible gold that could have been earned by waiting the level out). The default is bonus=yes. {{DevFeature1.13|2}} Alternatively, a number, defining the bonus | + | * '''bonus''': whether the player should get bonus gold (maximum possible gold that could have been earned by waiting the level out). The default is bonus=yes. {{DevFeature1.13|2}} Alternatively, a number, defining the bonus multiple (1.0 meaning full). |
* '''carryover_report''': whether the player should receive a summary of the scenario outcome, the default is carryover_report=yes. | * '''carryover_report''': whether the player should receive a summary of the scenario outcome, the default is carryover_report=yes. | ||
* '''save''': whether a start-of-scenario save should be created for the next scenario, the default is save=yes. Do not confuse this with saving of replays for the current scenario. | * '''save''': whether a start-of-scenario save should be created for the next scenario, the default is save=yes. Do not confuse this with saving of replays for the current scenario. | ||
Line 38: | Line 38: | ||
Creates a unit (either on the map, on a recall list, or into a variable for later use.) For syntax see [[SingleUnitWML]]. | Creates a unit (either on the map, on a recall list, or into a variable for later use.) For syntax see [[SingleUnitWML]]. | ||
* {{Short Note:Predefined Macro|GENERIC_UNIT}} | * {{Short Note:Predefined Macro|GENERIC_UNIT}} | ||
+ | |||
+ | This tag can also recall an existing unit, which happens when: | ||
+ | * the '''id=''' attribute is used | ||
+ | * a unit with that '''id=''' already exists | ||
+ | * (might be unnecessary) the existing unit is on the side's recall list | ||
+ | in this case, the unit is recalled at the '''x,y=''' or '''location_id=''' given, and any other data in the tag is ignored. | ||
+ | |||
+ | Campaign authors: a usual way to recall plot-necessary heroes is to use a macro with the data for creating that hero. This helps during debugging, because you can skip to scenarios and the recall-or-create functionality means that any units which are normally met in a previous scenario are automatically created (otherwise some scenarios may be an instant loss). This can only be used for units that must survive the previous scenarios, as it would recreate units if they died in a previous scenario. | ||
+ | For example, | ||
+ | [https://github.com/wesnoth/wesnoth/blob/1.14.7/data/campaigns/Heir_To_The_Throne/utils/httt_utils.cfg#L685 HttT's NEED_DELFADOR macro]. | ||
=== [recall] === | === [recall] === | ||
− | Recalls a unit taking into account any [ | + | Recalls a unit taking into account any [[SingleUnitWML|filter_recall]] of the leader. The unit is recalled free of charge, and is placed near its leader, e.g., if multiple leaders are present, near the first found which would be able to normally recall it. |
If neither a valid map location is provided nor a leader on the map would be able to recall it, the tag is ignored. | If neither a valid map location is provided nor a leader on the map would be able to recall it, the tag is ignored. | ||
Line 46: | Line 56: | ||
* [[StandardUnitFilter]]: the first matching unit will be recalled. If no units match this tag is ignored. Do not use a [filter] tag. If a comma separated list is given, every unit currently considered for recall is checked against all the types (not each single one of the types against all units). | * [[StandardUnitFilter]]: the first matching unit will be recalled. If no units match this tag is ignored. Do not use a [filter] tag. If a comma separated list is given, every unit currently considered for recall is checked against all the types (not each single one of the types against all units). | ||
* '''x,y''': the unit is placed here instead of next to the leader. | * '''x,y''': the unit is placed here instead of next to the leader. | ||
+ | * '''location_id''': {{DevFeature1.15|0}} the name of a special map location to recall to. Used instead of '''x,y'''. | ||
* '''show''': yes/no, default yes: whether the unit is animated (faded in) or instantly displayed | * '''show''': yes/no, default yes: whether the unit is animated (faded in) or instantly displayed | ||
* '''fire_event''': boolean yes|no (default no); whether any according prerecall or recall events shall be fired. | * '''fire_event''': boolean yes|no (default no); whether any according prerecall or recall events shall be fired. | ||
* '''check_passability''': (boolean yes|no, default yes): If yes, checks for terrain passability when placing the unit (a nearby passable hex is chosen). | * '''check_passability''': (boolean yes|no, default yes): If yes, checks for terrain passability when placing the unit (a nearby passable hex is chosen). | ||
+ | * '''[secondary_unit]''': {{DevFeature1.13|?}} If present and show=yes, a matching unit will be chosen and their recruiting animation played. | ||
=== [teleport] === | === [teleport] === | ||
Line 54: | Line 66: | ||
* '''[filter]''': [[StandardUnitFilter]] the first unit matching this filter will be teleported. | * '''[filter]''': [[StandardUnitFilter]] the first unit matching this filter will be teleported. | ||
* '''x,y''': the hex to teleport to. If that hex is occupied, the closest unoccupied hex will be used instead. | * '''x,y''': the hex to teleport to. If that hex is occupied, the closest unoccupied hex will be used instead. | ||
+ | * '''location_id''': {{DevFeature1.15|0}} the name of a special map location to teleport to. Used instead of '''x,y'''. | ||
* '''clear_shroud''': should shroud be cleared on arrival | * '''clear_shroud''': should shroud be cleared on arrival | ||
* '''animate''': should a teleport animation be played (if the unit doesn't have a teleport animation, it will fade out/fade in) | * '''animate''': should a teleport animation be played (if the unit doesn't have a teleport animation, it will fade out/fade in) | ||
Line 69: | Line 82: | ||
* '''layer''': (overlay|base|both, default=both) only change the specified layer. | * '''layer''': (overlay|base|both, default=both) only change the specified layer. | ||
* '''replace_if_failed''': (default=no) When replacing just one layer failed, try to replace the whole terrain. If '''terrain''' is an overlay only terrain, use the default_base as base layer. If the terrain has no default base, do nothing. | * '''replace_if_failed''': (default=no) When replacing just one layer failed, try to replace the whole terrain. If '''terrain''' is an overlay only terrain, use the default_base as base layer. If the terrain has no default base, do nothing. | ||
+ | * '''location_id''': This key sets a string as a way to mark the hex or hexes for later reference. It is very similar to the leader starting position, and can also be set that way in the map editor. | ||
If you want to remove the overlays from a terrain and leave only the base, use: | If you want to remove the overlays from a terrain and leave only the base, use: | ||
Line 74: | Line 88: | ||
terrain="^" | terrain="^" | ||
− | <b>Note:</b> When a hex changes from a village terrain to a non-village terrain, and a team owned that village it loses that village. When a hex changes from a non-village terrain to a village terrain and there is a unit on that hex it does not automatically capture the village. The reason for not capturing villages | + | <b>Note:</b> When a hex changes from a village terrain to a non-village terrain, and a team owned that village it loses that village. When a hex changes from a non-village terrain to a village terrain and there is a unit on that hex it does not automatically capture the village. The reason for not capturing villages is that there are too many choices to make; should a unit lose its movement points, should capture events be fired. It is easier to do this as wanted by the author in WML. |
=== [gold] === | === [gold] === | ||
Line 83: | Line 97: | ||
=== [unstore_unit] === | === [unstore_unit] === | ||
− | Creates a unit from a game variable, and activates it on the playing field. This must be a specific variable describing a unit, and may not be an array -- | + | Creates a unit from a game variable, and activates it on the playing field or recall list. This must be a specific variable describing a unit, and may not be an array (if it is, only the first unit will be unstored). |
− | * '''variable''': the name of the variable. | + | |
− | * '''find_vacant''': | + | This may be useful in different contexts: |
− | * '''check_passability''' | + | * To update a unit on the map after having edited its WML. This usage is common, but discouraged - if possible, you should use [[#.5Bmodify_unit.5B|[modify_unit]]] or [[#.5Bobject.5B|[object]]] instead. |
− | * '''text''': (translatable) floating text to display above the unit, such as a damage amount | + | * To place a previously-defined unit into the scenario, if it was directly defined in a WML variable, using [unit] with the key '''to_variable'''. This usage is rather uncommon. |
− | * '''male_text''', '''female_text''': {{DevFeature1.13|2}} (translatable) gender-specific versions of the above | + | * To place a unit back into the game that was removed earlier, for example a hero that leaves the party for awhile and then comes back. |
− | * '''red''', '''green''', '''blue''': (default=0,0,0) the color | + | |
− | * '''advance''': (default=yes) if yes the unit is advanced if it has enough XP. When modifying XP make sure to do it from inside a [[EventWML#Multiplayer_safety|synchronized event]] or it may lead to OOS errors especially when several advancement paths exist. Note that advance and post advance events are called, so infinite loops can happen. | + | The variable is not cleared. To unstore units from an array variable, iterate over the array. See [[VariablesWML]] and [[VariablesWML/How to use variables]] for more information about variable usage. See also [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]], [[ConditionalActionsWML|For]], [[ConditionalActionsWML#.5Bwhile.5D|[while]]] and [[InternalActionsWML#.5Bclear_variable.5D|[clear_variable]]]. |
− | * '''fire_event''' | + | |
− | + | The tag takes the following keys: | |
− | + | * '''variable''': This is required to indicate the name of the variable to read the unit from. | |
− | Units can be unstored with negative (or zero) hit points. This can be useful if modifying a unit in its last_breath event (as the unit's death is already the next step), but tends to look wrong in other cases. In particular, it is possible to have units with negative hit points in play. Such units are aberrations, subject to unusual behavior as the game compensates for them. (For example, such units are currently automatically hit& | + | * '''Placement keys''': |
+ | ** '''x''' ,'''y''': By default, the unit will be placed at the location specified in the variable, but if these keys are present, the unit will be placed at that location instead. To place the unit on the recall list of its side, use '''x,y=recall,recall'''. (If you want to change the said, you need to first update ''$unit.side'' in the variable before unstoring.) | ||
+ | ** '''location_id''': {{DevFeature1.15|0}} The name of a special map location to unstore to. Used instead of '''x,y'''. | ||
+ | ** '''find_vacant''' (yes|no, default no): Whether the unit should be placed on the nearest vacant tile to its specified location. If this is set to 'no' (default), then any unit on the same tile as the unit being unstored will be destroyed. | ||
+ | ** '''check_passability''' (yes|no, default yes): Only relevant if '''find_vacant=yes'''. In that case, this determines whether game will try to find a passable tile for the unit. If set to no, the unit may be placed on an impassable tile. Note that if both '''find_vacant''' and '''check_passability''' are set, then the unit's position may be shifted even if there is not a unit on the target space, if that space is not passable for the unit. | ||
+ | * '''Animation keys''' (these determine the visual effect of how the unit is placed or updated): | ||
+ | ** '''text''': (translatable) A floating text to display above the unit, such as a damage amount. | ||
+ | ** '''male_text''', '''female_text''': {{DevFeature1.13|2}} (translatable) gender-specific versions of the above | ||
+ | ** '''red''', '''green''', '''blue''': (default=0,0,0) the color of the text. Values vary from 0-255. You may find it convenient to use the {COLOR_HARM} or {COLOR_HEAL} macro instead. (Use {COLOR_HARM} or {COLOR_HEAL} instead of the whole red,green,blue= line.) | ||
+ | ** '''animate''': (boolean yes|no, default yes) Determines whether to play any animations associated with the unstore. Currently this only affects the advancement animation ("levelout" and "levelin", defaulting to a fade to white and back) if the unit ends up advancing. | ||
+ | * '''Side-effect keys''' (these directly modify the behaviour of the action): | ||
+ | ** '''advance''': (default=yes) if yes the unit is advanced if it has enough XP. When modifying XP, make sure to do it from inside a [[EventWML#Multiplayer_safety|synchronized event]] or it may lead to OOS errors, especially when several advancement paths exist. Note that advance and post advance events are called, so infinite loops can happen. | ||
+ | ** '''fire_event''' (yes|no, default no): Whether any advance/post advance events shall be fired if an advancement takes place. This also affects whether the unit placed event is fired. | ||
+ | |||
+ | Units can be unstored with negative (or zero) hit points. This can be useful if modifying a unit in its last_breath event (as the unit's death is already the next step), but tends to look wrong in other cases. In particular, it is possible to have units with negative hit points in play. Such units are aberrations, subject to unusual behavior as the game compensates for them. (For example, such units are currently automatically hit—and killed—in combat.) The details of the unusual behavior are subject to change between stable releases without warning. | ||
=== [allow_recruit] === | === [allow_recruit] === | ||
− | Allows a side to recruit units it couldn't previously recruit. | + | Allows a side to recruit units it couldn't previously recruit. Any leader on this side will now be able to recruit the new units. |
* '''type''': the types of units that the side can now recruit. | * '''type''': the types of units that the side can now recruit. | ||
* '''side''': (default=1) the number of the side that is being allowed to recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated. | * '''side''': (default=1) the number of the side that is being allowed to recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated. | ||
Line 104: | Line 132: | ||
=== [allow_extra_recruit] === | === [allow_extra_recruit] === | ||
Allows a leader to recruit units it couldn't previously recruit. | Allows a leader to recruit units it couldn't previously recruit. | ||
− | These types | + | These types are in addition to the types the leader can recruit because of '''[side]recruit=''' and '''[allow_recruit]'''. |
− | * '''extra_recruit''': the types of units that the | + | * '''extra_recruit''': the types of units that the leader can now recruit. |
* '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units. | * '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units. | ||
=== [disallow_recruit] === | === [disallow_recruit] === | ||
− | Prevents a side from recruiting units it could previously recruit. | + | Prevents a side from recruiting units it could previously recruit. No leader on this side will be able to recruit the specified units anymore, unless that leader has the same unit in their personal '''extra_recruit''' list. |
* '''type''': the types of units that the side can no longer recruit. {{DevFeature1.13|0}} If omitted, all recruits for matching sides will be disallowed. | * '''type''': the types of units that the side can no longer recruit. {{DevFeature1.13|0}} If omitted, all recruits for matching sides will be disallowed. | ||
* '''side''': (default=1) the number of the side that may no longer recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated. | * '''side''': (default=1) the number of the side that may no longer recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated. | ||
Line 115: | Line 143: | ||
=== [disallow_extra_recruit] === | === [disallow_extra_recruit] === | ||
− | Prevents a leader from recruiting units it could previously recruit. | + | Prevents a leader from recruiting units it could previously recruit. This won't prevent the leader from recruiting that unit if the unit is in the '''[side]recruit=''' list – you must use '''[disallow_recruit]''' in that case. |
− | * '''extra_recruit''': the types of units that the | + | * '''extra_recruit''': the types of units that the leader can no longer recruit. |
* '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units. | * '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units. | ||
=== [set_recruit] === | === [set_recruit] === | ||
− | Sets the units a side can recruit. | + | Sets the units a side can recruit. Any leader on this side will now be able to recruit these units. |
* '''recruit''': the types of units that the side can now recruit. | * '''recruit''': the types of units that the side can now recruit. | ||
− | * '''side''': | + | * '''side''': The number of the side that is having its recruitment set. This can be a comma-separated list. |
* [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF. | * [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF. | ||
=== [set_extra_recruit] === | === [set_extra_recruit] === | ||
Sets the units a leader can recruit. | Sets the units a leader can recruit. | ||
+ | These types are in addition to the types the leader can recruit because of '''[side]recruit=''' and '''[set_recruit]'''. | ||
* '''extra_recruit''': the types of units that the leader can now recruit. | * '''extra_recruit''': the types of units that the leader can now recruit. | ||
* '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units. | * '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units. | ||
Line 138: | Line 167: | ||
* '''team_name''': the team in which the side plays the scenario. | * '''team_name''': the team in which the side plays the scenario. | ||
* '''user_team_name''': a translatable string representing the team's description. This has no effect on alliances. Defaults to ''team_name''. | * '''user_team_name''': a translatable string representing the team's description. This has no effect on alliances. Defaults to ''team_name''. | ||
+ | * '''side_name''': {{DevFeature1.13|?}} a translatable string representing the side leader's description. | ||
* '''gold''': the amount of gold the side owns. | * '''gold''': the amount of gold the side owns. | ||
* '''village_gold''': the income setting per village for the side. | * '''village_gold''': the income setting per village for the side. | ||
− | * '''controller''': the identifier string of the side's controller. Uses the same syntax of the ''controller'' key in the [[SideWML|[side]]] tag. | + | * '''controller''': the identifier string of the side's controller. Uses the same syntax of the ''controller'' key in the [[SideWML|[side]]] tag. warning: in multiplayer, changing the controller of a side might result in OOS during some events like, for example 'side_turn_end'; see [https://github.com/wesnoth/wesnoth/issues/2563 issue #2563]. |
* '''fog''': a boolean string (yes/no) describing the status of Fog for the side. | * '''fog''': a boolean string (yes/no) describing the status of Fog for the side. | ||
* '''shroud''': a boolean string describing the status of Shroud for the side. | * '''shroud''': a boolean string describing the status of Shroud for the side. | ||
* '''hidden''': a boolean string specifying whether side is shown in status table. | * '''hidden''': a boolean string specifying whether side is shown in status table. | ||
* '''color''': a team color range specification, name (e.g. "red", "blue"), or number (e.g. "1", "2") for this side. The default color range names, numbers, and definitions can be found in data/core/team_colors.cfg. | * '''color''': a team color range specification, name (e.g. "red", "blue"), or number (e.g. "1", "2") for this side. The default color range names, numbers, and definitions can be found in data/core/team_colors.cfg. | ||
− | * '''[ai]''': sets/changes AI parameters for the side. Only parameters that are specified in the tag are changed, this does not reset others to their default values. Uses the same syntax as described in [[AiWML]]. Note that [modify_side][ai] works for all simple AI parameters and some, but not all, of the composite ones. If in doubt, use [ | + | * '''[ai]''': sets/changes AI parameters for the side. Only parameters that are specified in the tag are changed, this does not reset others to their default values. Uses the same syntax as described in [[AiWML]]. Note that [modify_side][ai] works for all simple AI parameters and some, but not all, of the composite ones. If in doubt, use [[AiWML#Adding_and_Deleting_Aspects_with_the_.5Bmodify_ai.5D_Tag|[modify_ai]]]] instead, which always works. {{DevFeature1.13|?}} If this contains an '''ai_algorithm''', the AI parameters will be reset to those of the indicated AI before adding any additional parameters included in the tag. In other words, this allows replacing the AI config rather than appending to it. |
* '''switch_ai''': replaces a side ai with a new AI from specified file(ignoring those AI parameters above). Path to file follows the usual WML convention. | * '''switch_ai''': replaces a side ai with a new AI from specified file(ignoring those AI parameters above). Path to file follows the usual WML convention. | ||
* '''reset_maps''': If set to "yes", then the shroud is spread to all hexes, covering the parts of the map that had already been explored by the side, including hexes currently seen. (Seen hexes will be cleared at the end of most events; they can also be manually cleared with {{tag|InterfaceActionsWML|redraw}}.) This is only effective if shroud is on, but this is evaluated after shroud= (and before shroud_data=). | * '''reset_maps''': If set to "yes", then the shroud is spread to all hexes, covering the parts of the map that had already been explored by the side, including hexes currently seen. (Seen hexes will be cleared at the end of most events; they can also be manually cleared with {{tag|InterfaceActionsWML|redraw}}.) This is only effective if shroud is on, but this is evaluated after shroud= (and before shroud_data=). | ||
Line 151: | Line 181: | ||
* '''share_maps''': change the share_maps side attribute. Be sure to use shroud=yes for that side and have it as an ally | * '''share_maps''': change the share_maps side attribute. Be sure to use shroud=yes for that side and have it as an ally | ||
* '''share_view''': change the share_view side attribute. Be sure to use fog=yes for that side and have it as an ally | * '''share_view''': change the share_view side attribute. Be sure to use fog=yes for that side and have it as an ally | ||
+ | * '''share_vision''': change both the above at the same time | ||
* '''shroud_data''': changes to the side's shroud, using the same format as when defining the [side]. | * '''shroud_data''': changes to the side's shroud, using the same format as when defining the [side]. | ||
* '''suppress_end_turn_confirmation''': Boolean value controlling whether or not a player is asked for confirmation when skipping a turn. | * '''suppress_end_turn_confirmation''': Boolean value controlling whether or not a player is asked for confirmation when skipping a turn. | ||
Line 158: | Line 189: | ||
* '''village_support''': The number of unit levels this side is able to support (does not pay upkeep on) per village it controls. | * '''village_support''': The number of unit levels this side is able to support (does not pay upkeep on) per village it controls. | ||
* '''defeat_condition''' {{DevFeature1.13|0}}: When the side is considered defeated (see [[SideWML|[side]]]). | * '''defeat_condition''' {{DevFeature1.13|0}}: When the side is considered defeated (see [[SideWML|[side]]]). | ||
+ | * '''[set_variable]''', '''[clear_variable]''' {{DevFeature1.15|3}} Sets or clears a variable within the side; uses the same syntax as [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] or [[InternalActionsWML#.5Bclear_variable.5D|[clear_variable]]] in ActionWML. | ||
+ | * '''[variables]''' {{DevFeature1.15|3}} The contents of this tag is merged into the side's variables. | ||
=== [modify_turns] === | === [modify_turns] === | ||
Line 169: | Line 202: | ||
=== [disallow_end_turn] === | === [disallow_end_turn] === | ||
− | Disallows human players to end their turn through the user interface. This action doesn't | + | Disallows human players to end their turn through the user interface. This action doesn't require arguments. |
+ | * '''reason''' (translatable): {{DevFeature1.15|0}} Allows to optionally specify a reason. | ||
=== [capture_village] === | === [capture_village] === | ||
Line 181: | Line 215: | ||
Removes all units (including units in a recall list) that match the filter from the game. | Removes all units (including units in a recall list) that match the filter from the game. | ||
* [[StandardUnitFilter]]: Selection criterion; do not use a [filter] tag. | * [[StandardUnitFilter]]: Selection criterion; do not use a [filter] tag. | ||
− | * '''animate''': if 'yes', displays the unit dying (fading away). | + | * '''animate''' (default 'no'): if 'yes', displays the unit dying (fading away). {{DevFeature1.13|8}} If '''[secondary_unit]''' is given, also plays the victory animation of that unit. |
− | * '''fire_event''': if 'yes', triggers any appropriate 'die' events (See [[EventWML]]). Note that events are only fired for killed units that have been on the map (as opposed to recall list). | + | * '''fire_event''' (default 'no'): if 'yes', triggers any appropriate 'die' events (See [[EventWML]]). Note that events are only fired for killed units that have been on the map (as opposed to recall list). |
− | * '''[secondary_unit]''' with a [[StandardUnitFilter]] as argument. Do not use a [filter] tag. Has an effect only if fire_event=yes. The first on-map unit matching the filter becomes second_unit in any fired die and last breath events. If an on-map unit matches and if there are several units killed with a single [kill] tag, second_unit is this same unit for all of them. If no on-map unit matches or [secondary_unit] isn't present, the variable second_unit in each of the die and last breath events is always the same as the variable unit (the dying unit). | + | * '''[secondary_unit]''' with a [[StandardUnitFilter]] as argument. Do not use a [filter] tag. Has an effect only if fire_event=yes ({{DevFeature1.13|8}} or if it has a victory animation and animate=yes). The first on-map unit matching the filter becomes second_unit in any fired die and last breath events. If an on-map unit matches and if there are several units killed with a single [kill] tag, second_unit is this same unit for all of them. If no on-map unit matches or [secondary_unit] isn't present, the variable second_unit in each of the die and last breath events is always the same as the variable unit (the dying unit). |
+ | * '''[primary_attack]''' {{DevFeature1.13|8}} The attacker's weapon to use for matching the animation. Useful for example on the wose, whose death animation depends on the damage type it was killed by. If a secondary unit is specified, this is taken as a [[StandardWeaponFilter]] and used to find a matching weapon on the unit. However, if there is no secondary unit specified, it is instead treated as an [[UnitTypeWML#Attacks|weapon definition]], and the animation will be run as if an imaginary unit possessing that weapon was the attacker. | ||
+ | * '''[secondary_attack]''' {{DevFeature1.13|8}} Similar to the above, but for the defender's weapon. This is taken as a [[StandardWeaponFilter]] and used to find a matching weapon on the dying unit. | ||
=== [move_unit] === | === [move_unit] === | ||
− | + | Moves a unit along a path on the map. The path can be specified exactly, or as a series of waypoints that the unit will pass through. | |
* [[StandardUnitFilter]] as argument; do not use a [filter] tag. All units matching the filter are moved. If the target location is occupied, the nearest free location is chosen. | * [[StandardUnitFilter]] as argument; do not use a [filter] tag. All units matching the filter are moved. If the target location is occupied, the nearest free location is chosen. | ||
* '''to_x''' (unsigned integer): The units are moved to this x coordinate. Can be a comma-separated list, in which case the unit follows this given path during the move. | * '''to_x''' (unsigned integer): The units are moved to this x coordinate. Can be a comma-separated list, in which case the unit follows this given path during the move. | ||
* '''to_y''' (unsigned integer): The units are moved to this y coordinate. Can be a comma-separated list. | * '''to_y''' (unsigned integer): The units are moved to this y coordinate. Can be a comma-separated list. | ||
− | * ''' | + | * '''dir''' (string): {{DevFeature1.15|0}} Performs a relative movement instead of an absolute movement. For example, dir=n,n,nw will move two spaces north and then one space to the northwest. This is used instead of '''to_x''' and '''to_y'''. |
+ | * '''to_location''': {{DevFeature1.15|0}} Moves matching units to locations placed in the map editor with the "New Location" button. Can be a comma-separated list. This is used instead of '''to_x''' and '''to_y'''. | ||
* '''check_passability''' (boolean yes|no, default yes): Whether the terrain the unit is moved to should be checked for suiting the unit. (If it does not, a nearby suitable hex is chosen.) | * '''check_passability''' (boolean yes|no, default yes): Whether the terrain the unit is moved to should be checked for suiting the unit. (If it does not, a nearby suitable hex is chosen.) | ||
* '''force_scroll''': Whether to scroll the map or not even when [[InterfaceActionsWML#.5Block_view.5D|[lock_view]]] is in effect or ''Follow Unit Actions'' is disabled in ''Advanced Preferences''. Defaults to using [[InterfaceActionsWML#.5Bmove_unit_fake.5D|[move_unit_fake]]]'s default value. | * '''force_scroll''': Whether to scroll the map or not even when [[InterfaceActionsWML#.5Block_view.5D|[lock_view]]] is in effect or ''Follow Unit Actions'' is disabled in ''Advanced Preferences''. Defaults to using [[InterfaceActionsWML#.5Bmove_unit_fake.5D|[move_unit_fake]]]'s default value. | ||
+ | * '''clear_shroud''': {{DevFeature1.15|0}} (boolean yes|no, default no) Whether to remove shroud and fog after the unit was moved, but before events are fired. It will not clear all alongside the path, only around the target destination. | ||
+ | * '''fire_event''' (boolean yes|no, default no): Whether any according moveto events shall be fired. The target location ($x1, $y1 in the event) may not be the same location that the unit was tried to be moved to, if the original target location is occupied or impassable. | ||
=== [modify_ai] === | === [modify_ai] === | ||
Line 205: | Line 244: | ||
works similar to the MODIFY_UNIT macro. | works similar to the MODIFY_UNIT macro. | ||
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter are modified. Matches on recall list units too. | * '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter are modified. Matches on recall list units too. | ||
− | * '''[object]''', '''[trait]''', {{DevFeature1.13|5}} '''[advancement]''' - The given modifications will be immediately applied to all units matching the filter. | + | * '''[object]''', '''[trait]''', {{DevFeature1.13|5}} '''[advancement]''' - The given modifications will be immediately applied to all units matching the filter. ([object] is described further [[#.5Bobject.5D|below]]) |
− | ** '''delayed_variable_substitution''' {{DevFeature1.13|5}} (boolean yes|no, default no): If set to "yes", the wml block contained in this [object], [trait], or [advancement] is not variable-substituted at execution time of the event containing this [modify_unit]. You need this | + | ** '''delayed_variable_substitution''' {{DevFeature1.13|5}} (boolean yes|no, default no): If set to "yes", the wml block contained in this [object], [trait], or [advancement] is not variable-substituted at execution time of the event containing this [modify_unit]. You need this for any effect that uses variable substitution or when using [effect][filter] with a $this_unit. {{DevFeature1.13|9}} This is no longer needed when adding ABILITY_TELEPORT, ABILITY_LEADERSHIP or SPECIAL_BACKSTAB. |
− | * '''[effect]''' {{DevFeature1.13|6}} Applies the effect directly to the unit. | + | ** Do not use a '''[modifications]''' tag, as this may skip some of the special-case handling for newly added objects, traits and advancements, and will potentially overwrite existing modifications. |
+ | * '''[effect]''' {{DevFeature1.13|6}} Applies the effect directly to the unit. See [[EffectWML]]. | ||
+ | * '''[set_variable]''', '''[clear_variable]''' {{DevFeature1.15|3}} Sets or clears a variable within the unit (saved inside the unit's [variables] tag); uses the same syntax as [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] or [[InternalActionsWML#.5Bclear_variable.5D|[clear_variable]]] in ActionWML. | ||
* Accepts generally the syntax inside of wml unit variables created by [store_unit] which can be viewed in a savefile or by using the [[CommandMode|inspect command]]. Cannot remove things or add/alter unit animations. Subtags with the same name must be written in the correct order to match them with the tag they are supposed to modify. Note that keys will be processed in arbitrary order, which may cause problems if you use formulas that depend on other formulas. To work around this you may need to use the tag twice with the same filter. | * Accepts generally the syntax inside of wml unit variables created by [store_unit] which can be viewed in a savefile or by using the [[CommandMode|inspect command]]. Cannot remove things or add/alter unit animations. Subtags with the same name must be written in the correct order to match them with the tag they are supposed to modify. Note that keys will be processed in arbitrary order, which may cause problems if you use formulas that depend on other formulas. To work around this you may need to use the tag twice with the same filter. | ||
example usage (see also the test scenario): | example usage (see also the test scenario): | ||
Line 220: | Line 261: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | The unit which is currently modified is accessible via $this_unit, e.g. hitpoints = "$($this_unit.hitpoints / 2)" to set the hitpoints of all units to half of their | + | The unit which is currently modified is accessible via $this_unit, e.g. hitpoints = "$($this_unit.hitpoints / 2)" to set the hitpoints of all units to half of their current value. This this_unit variable is independent from the this_unit variable available in the SUF used to determine which units to modify (first all matching units are gathered, and then all those are modified). |
+ | |||
+ | Modifying a unit ''may'' trigger an advancement event if the experience is set higher than the max_experience. However, this behaviour should not be relied upon to happen under all circumstances; if it's desired, the event should be triggered separately, for example with '''[transform_unit]'''. | ||
+ | |||
+ | '''Note:''' Some some properties of the units are reset sometimes (for example when the unit advances or when [remove_object] is called), so it's usually better to change them with [object] ([object] inside [modify_unit]) than to change those properties directly via [modify_unit]. The following properties are _not_ reset in [remove_object] and are thus safe to use directly in [modify_unit]: | ||
+ | * '''side''' | ||
+ | * '''gender''' | ||
+ | * '''name''' | ||
+ | * '''canrecruit''' | ||
+ | * '''unrenamable''' | ||
+ | * '''extra_recruit''' | ||
+ | * '''[variables]''' | ||
+ | * '''facing''' | ||
+ | * '''x, y''' | ||
+ | * '''goto_x, goto_y''' | ||
+ | * '''hitpoints''' | ||
+ | * '''experience''' | ||
+ | * '''moves''' | ||
+ | * '''[status]''' | ||
+ | * '''attacks_left''' | ||
+ | * '''role''' | ||
=== [transform_unit] === | === [transform_unit] === | ||
− | Transforms every unit on the map matching the filter to the given unit type. Keeps intact hit points, experience and status. If the unit is transformed to a non-living type (undead or mechanical), it will be also unpoisoned. Hit points will be changed if necessary to respect the transformed unit's maximum hit points. | + | Transforms every unit on the map matching the filter to the given unit type. Keeps intact hit points, experience and status. If the unit is transformed to a non-living type (undead or mechanical), it will be also unpoisoned. Hit points will be changed if necessary to respect the transformed unit's maximum hit points. Regardless of anything else, the unit will be rebuilt. Thus, transforming a unit to its current type is a way to force a rebuild, for example after manually removing a modification. |
* [[StandardUnitFilter]]: do not use a [filter] tag. | * [[StandardUnitFilter]]: do not use a [filter] tag. | ||
* '''transform_to''': the unit type in which all the units matching the filter will be transformed. If missing, the units will follow their normal advancement. | * '''transform_to''': the unit type in which all the units matching the filter will be transformed. If missing, the units will follow their normal advancement. | ||
Line 235: | Line 296: | ||
=== [object] === | === [object] === | ||
− | Gives some unit an object which modifies their stats in some way. | + | Gives some unit an object which modifies their stats in some way. This tag can also be used in places that don't support ActionWML, such as [[#.5Bmodify_unit.5D|[modify_unit]]] or [[SingleUnitWML|[unit][modifications]]]. The following is supported in all these places: |
− | |||
− | |||
− | |||
* '''[effect]''': one or more effect elements may be listed. See [[EffectWML]] for a description of [effect]. | * '''[effect]''': one or more effect elements may be listed. See [[EffectWML]] for a description of [effect]. | ||
* '''duration''': | * '''duration''': | ||
− | **if 'scenario', effects only last until the end of | + | **if 'scenario', effects only last until the end of the scenario. |
**if 'forever' or not set, effects never wear off. | **if 'forever' or not set, effects never wear off. | ||
** if 'turn', effects only last until the start of the unit's next turn (when the unit refreshes movement and attacks). (Like other start-of-turn behavior, objects with a duration of "turn" won't expire before turn 2.) | ** if 'turn', effects only last until the start of the unit's next turn (when the unit refreshes movement and attacks). (Like other start-of-turn behavior, objects with a duration of "turn" won't expire before turn 2.) | ||
− | ** {{DevFeature1.13|1}} if 'turn end | + | ** {{DevFeature1.13|1}} if 'turn end', effects only last until the end of the unit's next turn (exactly like the slowed status). |
− | * '''[filter]''' with a [[StandardUnitFilter]] as argument. The first unit found that matches the filter will be given the object. Only on-map units are considered. If no unit matches or no [filter] is supplied, it | + | * Other keys, such as '''id''', may be used to remove the object later, but are not used by the engine. An '''[object]''' tag can contain any arbitrary data that may be helpful to identify the object to remove later using a [[FilterWML#Filtering_on_WML_data|WML filter]]. |
+ | |||
+ | The following is supported only when using '''[object]''' as ActionWML: | ||
+ | * '''id''': (Optional) By default, an object with a defined ID can only be picked up once per scenario, even if it is removed later or first_time_only=no is set for the event. You can remove this restriction by setting take_only_once=no. For filtering objects, it might be simpler to use a custom key such as item_id. The id string can contain only letters, numbers and underscores. The ID is also commonly used to manually remove the object later, for example with [[#.5Bremove_object.5D|[remove_object]]]. | ||
+ | * '''take_only_once''': (default yes) {{DevFeature1.13|6}} If set to "no", the object's ID does not prevent it from being taken more than once. | ||
+ | * '''delayed_variable_substitution''' (boolean yes|no, default no): If set to "yes", the wml block contained in this [object] is not variable-substituted at execution time of the event where this [object] is within. You need this for any effect that uses variable substitution or when using [effect][filter] with a $this_unit. {{DevFeature1.13|9}} This is no longer needed when adding ABILITY_TELEPORT, ABILITY_LEADERSHIP or SPECIAL_BACKSTAB. | ||
+ | * '''[filter]''' with a [[StandardUnitFilter]] as argument. The first unit found that matches the filter will be given the object. Only on-map units are considered. If no unit matches or no [filter] is supplied, it tries to apply the object to the unit at the $x1,$y1 location of the event where this [object] is in. The case of no unit being at that spot is handled in the same way as no unit matching a given filter ([else] commands executed, cannot_use_message displayed). Note that units on the recall list will not be checked. To add an [object] to a unit on the recall list you have to use '''[modify_unit][object]'''. | ||
* '''[then]''': a subtag that lets you execute actions if the filter conditions are met. The most common action that should be inside here is a '''[remove_item]''' tag, but you could probably put any tags that otherwise work in a [then] tag. | * '''[then]''': a subtag that lets you execute actions if the filter conditions are met. The most common action that should be inside here is a '''[remove_item]''' tag, but you could probably put any tags that otherwise work in a [then] tag. | ||
* '''[else]''': a subtag that lets you execute actions if the filter conditions are *not* met. | * '''[else]''': a subtag that lets you execute actions if the filter conditions are *not* met. | ||
Line 251: | Line 315: | ||
* '''image''': the displayed image of the object. | * '''image''': the displayed image of the object. | ||
* '''name''': (translatable) displayed as a caption of the image. | * '''name''': (translatable) displayed as a caption of the image. | ||
− | |||
* '''description''': (translatable) displayed as a message of the image. | * '''description''': (translatable) displayed as a message of the image. | ||
* '''cannot_use_message''': (translatable) displayed instead of '''description''' if no unit passes the filter test. | * '''cannot_use_message''': (translatable) displayed instead of '''description''' if no unit passes the filter test. | ||
− | |||
=== [remove_object] === | === [remove_object] === | ||
− | |||
{{DevFeature1.13|6}} | {{DevFeature1.13|6}} | ||
Removes an object from matching units. | Removes an object from matching units. | ||
− | * [[StandardUnitFilter]]: All units matching the filter have matching objects removed | + | * [[StandardUnitFilter]]: All units on the map (but not the recall list) matching the filter have matching objects removed. Use no [filter] tag. |
* '''object_id''': The id of the object to be removed. | * '''object_id''': The id of the object to be removed. | ||
+ | |||
+ | Note that some unit properties are not restored ideally, e.g. current unit's health reversion might not work as expected (max_hitpoints will though). {{DevFeature1.15|0}} This was fixed. | ||
+ | |||
+ | Note that [remove_object] works the following way: | ||
+ | |||
+ | # Remove the object from the unit | ||
+ | # Rebuild the unit to make the changes effective. | ||
+ | |||
+ | Step 2 implies that changes done for example via [modify_unit] (or via the [store_unit] + [set_variable] + [unstore_unit] technique) will be reset if those changes change a property that is a property of the unit type. See the note under [[#.5Bmodify_unit.5D|[modify_unit]]] to get a list of properties that can safely be changed via [modify_unit]. | ||
+ | |||
+ | === [remove_trait] === | ||
+ | {{DevFeature1.15|2}} | ||
+ | |||
+ | * [[StandardUnitFilter]]: All units on the map (but not the recall list) matching the filter have matching traits removed. Use no [filter] tag. | ||
+ | * '''trait_id''': The id of the trait to be removed. See [[UnitsWML#.5Btrait.5D|[trait]]]. | ||
=== [remove_shroud] === | === [remove_shroud] === | ||
Line 281: | Line 357: | ||
* '''[filter_side]''' with a [[StandardSideFilter]] indicating which sides should be affected. | * '''[filter_side]''' with a [[StandardSideFilter]] indicating which sides should be affected. | ||
* [[StandardLocationFilter]]: the tiles from which fog should be lifted. | * [[StandardLocationFilter]]: the tiles from which fog should be lifted. | ||
− | * '''multiturn''': ''yes/no, default:no''. The default (not multiturn) causes fog to be removed in the same way that normal vision works; the cleared tiles will remain cleared until fog is recalculated (which normally happens when a side ends its turn). When multiturn is set to "yes", the cleared tiles remain clear until {{tag||reset_fog}} cancels the clearing. This allows tiles to remain clear for multiple turns, or to be refogged before the end of the current turn (without also refogging all tiles). Multiturn lifted fog is not shared with allies (even when | + | * '''multiturn''': ''yes/no, default:no''. The default (not multiturn) causes fog to be removed in the same way that normal vision works; the cleared tiles will remain cleared until fog is recalculated (which normally happens when a side ends its turn). When multiturn is set to "yes", the cleared tiles remain clear until {{tag||reset_fog}} cancels the clearing. This allows tiles to remain clear for multiple turns, or to be refogged before the end of the current turn (without also refogging all tiles). Multiturn lifted fog is not shared with allies (even when share_vision=all). |
=== [reset_fog] === | === [reset_fog] === | ||
Line 295: | Line 371: | ||
* Using this tag in a menu item has an additional side effect in 1.11. Starting with version 1.11.1, executing a WML menu item normally counts as doing something as far as the "you have not started your turn yet" dialog is concerned. However, a menu item whose handler includes '''[allow_undo]''' will not count. | * Using this tag in a menu item has an additional side effect in 1.11. Starting with version 1.11.1, executing a WML menu item normally counts as doing something as far as the "you have not started your turn yet" dialog is concerned. However, a menu item whose handler includes '''[allow_undo]''' will not count. | ||
− | The types of actions that can be undone are movement | + | The types of actions that can be undone are movement, recalling, and dismissing a unit from the recall list. If an action is undone, only the position (or existence) of the involved unit will be restored; any altered variables or changes to the game will remain changed after the action is undone. It is up to the scenario designer to avoid abusing this command. |
* Technically, if '''[allow_undo]''' is inside an '''[event]''' with ''first_time_only=yes'' (the default setting), and the user undoes the event, then the state of the game has changed in this way: the event will not fire a second time, even though the user undid the action the first time. | * Technically, if '''[allow_undo]''' is inside an '''[event]''' with ''first_time_only=yes'' (the default setting), and the user undoes the event, then the state of the game has changed in this way: the event will not fire a second time, even though the user undid the action the first time. | ||
+ | * Although recalling can be undone, recruitment can not be undone; this seems to apply even when the recruit's traits are not randomly-generated (tested on 1.12.6 and 1.14.4+dev). | ||
− | Due to a bug in 1.12 (https://gna.org/bugs/?23323) '''[allow_undo]''' should not be used in events that use one of the following things because it might cause OOS: | + | If an '''[event]''' uses both '''[allow_undo]''' and [[InternalActionsWML#.5Bfire_event.5D|'''[fire_event]''']] then the '''[allow_undo]''' must be after the '''[fire_event]'''. |
+ | |||
+ | Due to a bug in 1.12 ([http://web.archive.org/web/20170330000414/http://gna.org/bugs/?23323 https://gna.org/bugs/?23323]) '''[allow_undo]''' should not be used in events that use one of the following things because it might cause OOS: | ||
* [message] with [option]s | * [message] with [option]s | ||
* [get_global_variable] | * [get_global_variable] | ||
Line 310: | Line 389: | ||
message = "message" | message = "message" | ||
[option] | [option] | ||
− | + | label = "option 1" | |
[command] | [command] | ||
[/command] | [/command] | ||
[/option] | [/option] | ||
[option] | [option] | ||
− | + | label = "option 2" | |
[command] | [command] | ||
[/command] | [/command] | ||
Line 329: | Line 408: | ||
{{DevFeature1.13|2}} | {{DevFeature1.13|2}} | ||
Contains commands to execute when the player undoes the action which triggered the parent event. | Contains commands to execute when the player undoes the action which triggered the parent event. | ||
− | *'''delayed_variable_substitution''' {{DevFeature1.13|5}}: ''yes/no, default no (always no before 1.13.5)'' As in [[EventWML]], specifies whether to perform variable substitution when the parent event is run, or when the contents are run. If delayed substitution is used, [[ | + | *'''delayed_variable_substitution''' {{DevFeature1.13|5}}: ''yes/no, default no (always no before 1.13.5)'' As in [[EventWML]], specifies whether to perform variable substitution when the parent event is run, or when the contents are run. If delayed substitution is used, [[VariablesWML#Automatically_Stored_Variables|automatically stored variables]] from the parent event context are available, but may occasionally have unexpected values. (In particular, $unit.x and $unit.y may not have the expected value when undoing a move event, though $x1 and $y1 should be correct.) |
Note: | Note: | ||
− | It is not clear where whether the actionwml in [on_undo] in | + | It is not clear where whether the actionwml in [on_undo] in executed before or after the action is undone. Also, specially for enter/leave_hex events the units position when executing the [on_undo] code is usually different than when executing the original event. The recommended way to work around these issues is to refer to the unit by id instead of position and store all other needed information variables as 'upvalues'. You can also move the actual undo code to an external event. For example |
[event] | [event] | ||
name="undo_blah" | name="undo_blah" | ||
Line 356: | Line 435: | ||
{{DevFeature1.13|2}} | {{DevFeature1.13|2}} | ||
Same as [on_undo], except executes the commands on redo. Note that the parent event is not triggered again on a redo. | Same as [on_undo], except executes the commands on redo. Note that the parent event is not triggered again on a redo. | ||
+ | |||
+ | {{DevFeature1.13|8}} [on_redo] is deprecated and has no effect anymore. | ||
Note that [on_redo] is not guaranteed to be called when redoing an action, the engine might also decide to just fire the original events again. | Note that [on_redo] is not guaranteed to be called when redoing an action, the engine might also decide to just fire the original events again. | ||
+ | |||
+ | === [cancel_action] === | ||
+ | Although Wesnoth 1.12 does not have this tag, it is the default behavior of '''enter_hex'''/'''exit_hex''' [event] in that version. | ||
+ | |||
+ | {{DevFeature1.13|9}} In this version, [cancel_action] is recognised, but has no effect (a bug). | ||
+ | |||
+ | {{DevFeature1.13|11}} | ||
+ | In an '''enter_hex'''/'''exit_hex''' [event], interrupt the movement, leaving the unit where it is. This is intended to be used with an event that gives the player new information, to let the player choose whether to change their plans. For example, if the player has commanded a unit to move from (1,1) to (3,3) and attack a unit on (4,4); then a [cancel_action] inside an '''enter_hex''' [event] on (2,2) would make the unit stop on (2,2). A [cancel_action] inside an enter_hex [event] on (3,3) would let the player choose whether to attack. | ||
+ | |||
+ | {{DevFeature1.15|0}} | ||
+ | In a '''capture'''/'''moveto''' [event], interrupt the attack. | ||
=== [heal_unit] === | === [heal_unit] === | ||
− | Heal a unit. The variable '''$heal_amount''' will be set to the exact number of points healed (i.e can be | + | Heal a unit. The variable '''$heal_amount''' will be set to the exact number of points healed (i.e can be less than the parameter '''amount''' if the unit is fully healed). $heal_amount contains only the number of hitpoints the first unit that was found got healed. When the variable is not needed, use {CLEAR_VARIABLE heal_amount} after this tag. |
+ | |||
+ | {{DevFeature1.17|0}} The '''$heal_amount''' variable is no longer set. Use the '''variable''' key instead. | ||
* '''[filter]''': [[StandardUnitFilter]] All matching on-map units are healed. If no filter is supplied, it is tried to take the unit at $x1, $y1. | * '''[filter]''': [[StandardUnitFilter]] All matching on-map units are healed. If no filter is supplied, it is tried to take the unit at $x1, $y1. | ||
* '''[filter_second]''': [[StandardUnitFilter]] all the units matching the filter ''and'' having the ''heals'' ability will have their animation played (if ''animate'' is set to yes) for each of the units healed. | * '''[filter_second]''': [[StandardUnitFilter]] all the units matching the filter ''and'' having the ''heals'' ability will have their animation played (if ''animate'' is set to yes) for each of the units healed. | ||
− | * '''amount''': (integer, default full) the maximum points the unit(s) will be healed. | + | * '''amount''': (integer, default full) the maximum points the unit(s) will be healed. This can't be used to set the unit's hitpoints below 1 or above the unit's maximum hitpoints. If "full", it fully heals the unit. |
* '''animate''': a boolean which indicate if the healing animations must be played. (default no) | * '''animate''': a boolean which indicate if the healing animations must be played. (default no) | ||
* '''moves''': (integer, default 0) The maximum current movement points the units will be "healed". Can't set below 0 or above max_moves. If "full", sets moves to max_moves. | * '''moves''': (integer, default 0) The maximum current movement points the units will be "healed". Can't set below 0 or above max_moves. If "full", sets moves to max_moves. | ||
* '''restore_attacks''': (boolean, default no) Whether the units' attacks_left should be reset to their max_attacks (usually 1). | * '''restore_attacks''': (boolean, default no) Whether the units' attacks_left should be reset to their max_attacks (usually 1). | ||
− | * '''restore_statuses''': (boolean, default yes) Whether standard statuses should be reset to "no". This affects poisoned, slowed, petrified and unhealable. | + | * '''restore_statuses''': (boolean, default yes) Whether standard statuses should be reset to "no". This affects poisoned, slowed, petrified and unhealable. |
+ | * '''variable''': {{DevFeature1.17|0}} creates an array with the given name; each item of the array has two fields, ''id='' (the ID of the unit being healed) and ''heal_amount='' (the amount of HPs the unit has been healed by). | ||
=== [harm_unit] === | === [harm_unit] === | ||
− | Harms every unit matching the filter, for the specific damage amount. | + | Harms every unit matching the filter, for the specific damage amount. When harming multiple units, the special variable '''$this_unit''' can be used to access the current unit being harmed. This obviously does not work inside the filters though, as they give '''$this_unit''' a different meaning. |
* '''[filter]''': [[StandardUnitFilter]] all matching units will be harmed (required). | * '''[filter]''': [[StandardUnitFilter]] all matching units will be harmed (required). | ||
* '''[filter_second]''': [[StandardUnitFilter]] if present, the first matching unit will attack all the units matching the filter above. | * '''[filter_second]''': [[StandardUnitFilter]] if present, the first matching unit will attack all the units matching the filter above. | ||
Line 381: | Line 476: | ||
* '''[primary_attack], [secondary_attack]''': these set the weapon against which the harmed units will defend, and that the harming unit will use to attack, respectively (notice this is the opposite of '''[filter]''' and '''[filter_second]''' above). This allows for playing specific defense and attack animations. Both tags are expected to contain a [[FilterWML#Filtering_Weapons|Standard Weapon Filter]]. | * '''[primary_attack], [secondary_attack]''': these set the weapon against which the harmed units will defend, and that the harming unit will use to attack, respectively (notice this is the opposite of '''[filter]''' and '''[filter_second]''' above). This allows for playing specific defense and attack animations. Both tags are expected to contain a [[FilterWML#Filtering_Weapons|Standard Weapon Filter]]. | ||
* '''delay''': if animate=yes, sets the delay (in milliseconds, default 500) between each unit harming. | * '''delay''': if animate=yes, sets the delay (in milliseconds, default 500) between each unit harming. | ||
− | * '''variable''': if present, the damage caused to the unit, altered by resistances, will be stored in a WML array with the given name, under the | + | * '''variable''': if present, the damage caused to the unit, altered by resistances, will be stored in a WML array with the given name, under the ''harm_amount='' key. {{DevFeature1.17|0}} Each item of the array also has an ''id='' key, which contains the ID of the unit being harmed. |
* '''poisoned, slowed, petrified, unhealable''': (default no) if yes, every harmed unit that doesn't already have such status will have it set. | * '''poisoned, slowed, petrified, unhealable''': (default no) if yes, every harmed unit that doesn't already have such status will have it set. | ||
− | * '''experience''': | + | * '''experience''': (default yes) If there is a harmer, experience will be attributed similar to regular combat. Can take list of values. When any value is provided, all unspecified experience types default to not giving experience. Supported values: {{DevFeature1.17|25}} until that version only experience=yes and experience=no are supported |
+ | ** no - none of involved units get any experience (this value only works if it is the only value in list) | ||
+ | ** kill - the harming unit receives experience based on level of harmed unit in attack which kills harmed unit | ||
+ | ** attack - the harming unit receives experience based on level of harmed unit in attack which does not kill harmed unit, or in attack which kills harmed unit while kill experience is disabled | ||
+ | ** defend - the unit being harmed receives experience based on level of harming unit in attack which does not kill harmed unit | ||
+ | ** fight - short form of experience=attack,defend | ||
+ | ** yes - short form of experience=kill,attack,defend | ||
* '''resistance_multiplier''': the harmed unit's resistance is multiplied by the supplied value; this means that a value lower than 1 increases it, and a value greater than 1 decreases it. Default value is 1, that means no modification. | * '''resistance_multiplier''': the harmed unit's resistance is multiplied by the supplied value; this means that a value lower than 1 increases it, and a value greater than 1 decreases it. Default value is 1, that means no modification. | ||
Line 389: | Line 490: | ||
How a day should progress in a given area. Everywhere not specified in a [time_area] tag is affected by the [time] tags in the [scenario] tag. | How a day should progress in a given area. Everywhere not specified in a [time_area] tag is affected by the [time] tags in the [scenario] tag. | ||
* [[StandardLocationFilter]]: the locations to affect. ''note: only for [event][time_area]s - at scenario toplevel [time_area] does not support [[StandardLocationFilter]], only location ranges'' | * [[StandardLocationFilter]]: the locations to affect. ''note: only for [event][time_area]s - at scenario toplevel [time_area] does not support [[StandardLocationFilter]], only location ranges'' | ||
− | * [ | + | * '''[time]''': one or more tags describing the new schedule, see [[TimeWML]]. |
− | * '''id''': an unique identifier assigned to a time_area. Optional, unless you want to remove the time_area later. Can be a comma-separated list when removing time_areas, see below. | + | * '''id''': an unique identifier assigned to a time_area. Optional, unless you want to remove the time_area later or reference it from a location filter elsewhere. Can be a comma-separated list when removing time_areas, see below. |
* '''remove''': (boolean) yes/no value. Indicates whether the specified time_area should be removed. Requires an identifier. If no identifier is used, however, all time_areas are removed. | * '''remove''': (boolean) yes/no value. Indicates whether the specified time_area should be removed. Requires an identifier. If no identifier is used, however, all time_areas are removed. | ||
* '''current_time''': The time slot number (starting with zero) active at the creation of the area. | * '''current_time''': The time slot number (starting with zero) active at the creation of the area. | ||
''Example:'' (caves in parts of a map) | ''Example:'' (caves in parts of a map) | ||
− | + | <syntaxhighlight lang=wml> | |
− | + | [time_area] | |
− | + | id = cave_area | |
− | + | x = 1-2,4-5 | |
− | + | y = 1-2,1-2 | |
+ | {UNDERGROUND} | ||
+ | [/time_area] | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Specifying an id allows the area to be referenced from location filters. Example: | ||
+ | <syntaxhighlight lang=wml> | ||
+ | [time_area] | ||
+ | id = glyphs | ||
+ | x = 9,14 | ||
+ | y = 11,3 | ||
+ | [/time_area] | ||
+ | [event] | ||
+ | name = moveto | ||
+ | first_time_only=no | ||
+ | [filter] | ||
+ | side = 1 | ||
+ | [filter_location] | ||
+ | area = glyphs | ||
+ | [/filter_location] | ||
+ | [/filter] | ||
+ | # Do something, for example healing the unit | ||
+ | [/event] | ||
+ | </syntaxhighlight> | ||
=== [remove_time_area] === | === [remove_time_area] === | ||
Line 414: | Line 538: | ||
Replaces the entire map. | Replaces the entire map. | ||
− | * ''' | + | * '''map_data''': Content of a wesnoth map file. (This key used to be just '''map='''.) Example: |
− | + | map_data="{campaigns/Heir_To_The_Throne/maps/01_The_Elves_Besieged.map}" | |
+ | * '''map_file''': {{DevFeature1.13|?}} Path to a Wesnoth map file; can be used instead of '''map'''. The file will be loaded when the tag is executed, rather than being embedded wholesale in the preprocessed WML. Example: | ||
+ | map_file=campaigns/Heir_To_The_Throne/maps/01_The_Elves_Besieged.map | ||
+ | {{DevFeature1.15|3}} If the file is not found directly, it will be searched for in the [[BinaryPathWML|[binary_path]]]. Assuming a standard campaign or add-on layout, the example above can be replaced by: | ||
+ | map_file=01_The_Elves_Besieged.map | ||
* '''expand''': if 'yes', allows the map size to increase. The expansion direction is currently always bottom-right. | * '''expand''': if 'yes', allows the map size to increase. The expansion direction is currently always bottom-right. | ||
* '''shrink''': if 'yes', allows the map size to decrease. If the map size is reduced, any units that would no longer be on the map due to its coordinates no longer existing will be put into the recall list. | * '''shrink''': if 'yes', allows the map size to decrease. If the map size is reduced, any units that would no longer be on the map due to its coordinates no longer existing will be put into the recall list. | ||
Line 423: | Line 551: | ||
Replace the time of day schedule of the entire scenario. | Replace the time of day schedule of the entire scenario. | ||
* [[TimeWML]]: the new schedule. | * [[TimeWML]]: the new schedule. | ||
− | * '''current_time''': The time slot number (starting with zero) active at schedule replacement. | + | * '''current_time''': The time slot number (starting with zero) active at schedule replacement. ('''NB''': due to https://github.com/wesnoth/wesnoth/issues/5757 this attribute is ignored in versions 1.16.*. The fix was delivered in 1.17.* but wasn't backported due to backward-compatibility requirements) |
=== [tunnel] === | === [tunnel] === | ||
Line 432: | Line 560: | ||
* '''[filter]''': (required) [[StandardUnitFilter]] the units which can use the tunnel. Leave empty for "all units". | * '''[filter]''': (required) [[StandardUnitFilter]] the units which can use the tunnel. Leave empty for "all units". | ||
− | * '''[source]''': (required) [[StandardLocationFilter]] the source hex(es). | + | * '''[source]''': (required) [[StandardLocationFilter]] the source hex(es). Use $teleport_unit to filter on unit being teleported. |
− | * '''[target]''': (required) [[StandardLocationFilter]] the target hex(es). | + | * '''[target]''': (required) [[StandardLocationFilter]] the target hex(es). Use $teleport_unit to filter on unit being teleported. |
* '''id''': (optional) identifier for the tunnel, to allow removing. | * '''id''': (optional) identifier for the tunnel, to allow removing. | ||
* '''remove''': (boolean, default: no) If yes, removes all defined tunnels with the same ID (then only id= is necessary). | * '''remove''': (boolean, default: no) If yes, removes all defined tunnels with the same ID (then only id= is necessary). | ||
Line 440: | Line 568: | ||
* '''allow_vision''': (boolean, default: yes) {{DevFeature1.13|6}} If no, vision through a tunnel is not possible. Note that in that case the tunnel cannot be used if the tunnel exit is under shroud (which previously was ''always'' the case). | * '''allow_vision''': (boolean, default: yes) {{DevFeature1.13|6}} If no, vision through a tunnel is not possible. Note that in that case the tunnel cannot be used if the tunnel exit is under shroud (which previously was ''always'' the case). | ||
* '''pass_allied_units''': (boolean, default: yes) {{DevFeature1.13|6}} If no, allied (including own) units on the exit hex block a tunnel. | * '''pass_allied_units''': (boolean, default: yes) {{DevFeature1.13|6}} If no, allied (including own) units on the exit hex block a tunnel. | ||
+ | * '''delayed_variable_substitution''' (boolean, default: yes): If yes, the WML block contained in this [tunnel] is not variable-substituted at execution time of the event where this [tunnel] is within. Instead, variables are substituted when the tunnel is used by a unit. See [[EventWML#Nested_Events]] | ||
(Note: The tunnel tag can also be used inside the [[AbilitiesWML|[teleport]]] ability, without remove= and id=). | (Note: The tunnel tag can also be used inside the [[AbilitiesWML|[teleport]]] ability, without remove= and id=). | ||
Line 455: | Line 584: | ||
* [disband] | * [disband] | ||
* [fire_event] | * [fire_event] | ||
− | * [lua_ai] | + | * [lua_ai] {{DevFeature1.13|12}} This has been removed and is replaced with [custom_command] |
− | The tags corresponding to player actions generally use the same codepath as if a player had ordered it. | + | The tags corresponding to player actions generally use the same codepath as if a player had ordered it. That means for example that only moves that player would be allowed to do are possible, and movement is interrupted when sighting enemy unit. |
One purpose of this tag is to allow scripting of noninteractive scenarios -- without a tag like this, this might require elaborate mechanisms to coerce ais in order to test these code paths. | One purpose of this tag is to allow scripting of noninteractive scenarios -- without a tag like this, this might require elaborate mechanisms to coerce ais in order to test these code paths. | ||
− | This command should | + | This command should be replay safe if it is either invoked in a synced context, ''or'' invoked in code that is never synced, like AI code, a select event, or a menu item with `synced = false`. However, if you use desynchronized logic ''during'' an event that is otherwise synced, invoking [do_command] based on that desynchronized logic will result in out-of-sync errors during the replay; in this case, you must explicitly synchronize which command to do using something like the lua function wesnoth.sync.evaluate_single. |
=== [put_to_recall_list] === | === [put_to_recall_list] === | ||
Line 471: | Line 600: | ||
* '''heal''': (default=no) Whether the unit should be refreshed, similar to the unit moving to the recall list at the end of a scenario. | * '''heal''': (default=no) Whether the unit should be refreshed, similar to the unit moving to the recall list at the end of a scenario. | ||
+ | === [set_achievement] === | ||
+ | |||
+ | {{DevFeature1.17|13}} | ||
+ | |||
+ | Sets the specified achievement as completed and shows a popup stating it's been completed. The popup is not shown if the achievement has already been achieved. | ||
+ | |||
+ | * '''content_for''': The [[AchievementsWML#.5Bachievement_group.5D|[achievement_group]]] that this achievement is part of. | ||
+ | * '''id''': The id of the achievement. | ||
+ | |||
+ | === [set_sub_achievement] === | ||
+ | |||
+ | {{DevFeature1.17|17}} | ||
+ | |||
+ | Sets the specified sub-achievement as completed. | ||
+ | |||
+ | * '''content_for''': The [[AchievementsWML#.5Bachievement_group.5D|[achievement_group]]] that this achievement is part of. | ||
+ | * '''id''': The id of the achievement. | ||
+ | * '''sub_id''': The id of the sub-achievement. | ||
+ | |||
+ | === [progress_achievement] === | ||
+ | |||
+ | {{DevFeature1.17|13}} | ||
+ | |||
+ | Progress an achievement by the specified amount, with an optional limit for how far the achievement can be progressed. | ||
+ | |||
+ | * '''content_for''': The [[AchievementsWML#.5Bachievement_group.5D|[achievement_group]]] that this achievement is part of. | ||
+ | * '''id''': The id of the achievement. | ||
+ | * '''amount''': The amount to increment the achievement. | ||
+ | * '''limit''': (optional) Using this attribute will prevent achievements from progressing past this value. | ||
== Useful Macros == | == Useful Macros == | ||
− | There are some predefined macros that you find useful for direct actions. You can find a complete list along with a detailed explanation of how they work [ | + | There are some predefined macros that you find useful for direct actions. You can find a complete list along with a detailed explanation of how they work [https://www.wesnoth.org/macro-reference.html here]. |
* '''{MOVE_UNIT}''': Moves a unit to another location in the map and the player sees the movement (unlike [teleport]) | * '''{MOVE_UNIT}''': Moves a unit to another location in the map and the player sees the movement (unlike [teleport]) | ||
* '''{FULL_HEAL}''': Brings a unit to full HP | * '''{FULL_HEAL}''': Brings a unit to full HP |
Latest revision as of 20:44, 13 November 2024
Contents
- 1 Direct actions
- 1.1 [endlevel]
- 1.2 [unit]
- 1.3 [recall]
- 1.4 [teleport]
- 1.5 [terrain_mask]
- 1.6 [terrain]
- 1.7 [gold]
- 1.8 [unstore_unit]
- 1.9 [allow_recruit]
- 1.10 [allow_extra_recruit]
- 1.11 [disallow_recruit]
- 1.12 [disallow_extra_recruit]
- 1.13 [set_recruit]
- 1.14 [set_extra_recruit]
- 1.15 [modify_side]
- 1.16 [modify_turns]
- 1.17 [allow_end_turn]
- 1.18 [disallow_end_turn]
- 1.19 [capture_village]
- 1.20 [kill]
- 1.21 [move_unit]
- 1.22 [modify_ai]
- 1.23 [modify_unit]
- 1.24 [transform_unit]
- 1.25 [petrify]
- 1.26 [unpetrify]
- 1.27 [object]
- 1.28 [remove_object]
- 1.29 [remove_trait]
- 1.30 [remove_shroud]
- 1.31 [place_shroud]
- 1.32 [lift_fog]
- 1.33 [reset_fog]
- 1.34 [allow_undo]
- 1.35 [on_undo]
- 1.36 [on_redo]
- 1.37 [cancel_action]
- 1.38 [heal_unit]
- 1.39 [harm_unit]
- 1.40 [time_area]
- 1.41 [remove_time_area]
- 1.42 [end_turn]
- 1.43 [replace_map]
- 1.44 [replace_schedule]
- 1.45 [tunnel]
- 1.46 [do_command]
- 1.47 [put_to_recall_list]
- 1.48 [set_achievement]
- 1.49 [set_sub_achievement]
- 1.50 [progress_achievement]
- 2 Useful Macros
- 3 See Also
Direct actions
Direct actions are actions that have a direct effect on gameplay. They can be used inside of events.
The following tags are actions:
[endlevel]
Ends the scenario.
- result: before the scenario is over, all events with name=result are triggered. If result=victory, the player progresses to the next level (i.e., the next scenario in single player); if result=defeat, the game returns to the main menu.
When the result is "victory" the following keys can be used:
- bonus: whether the player should get bonus gold (maximum possible gold that could have been earned by waiting the level out). The default is bonus=yes. (Version 1.13.2 and later only) Alternatively, a number, defining the bonus multiple (1.0 meaning full).
- carryover_report: whether the player should receive a summary of the scenario outcome, the default is carryover_report=yes.
- save: whether a start-of-scenario save should be created for the next scenario, the default is save=yes. Do not confuse this with saving of replays for the current scenario.
- replay_save: whether a replay save for the current scenario is allowed, the default is replay_save=yes. If yes, the player's settings in preferences will be used to determine if a replay is saved. If no, will override and not save a replay.
- linger_mode: If ...=yes, the screen is greyed out and there's the possibility to save before advancing to the next scenario, the default is linger_mode=yes.
- reveal_map: (Multiplayer only) (Default is 'yes') If 'no', shroud doesn't disappear when game ended.
- next_scenario: (default specified in [scenario] tag) the ID of the next scenario that should be played. All units that side 1 controls at this point become available for recall in next_scenario.
- carryover_percentage: by default 80% of the gold is carried over to the next scenario, with this key the amount can be changed.
- carryover_add: if yes the gold will be added to the starting gold the next scenario, if no the next scenario will start with the amount of the current scenario (after taxes) or the minimum in the next scenario. Default is no.
- music: (default specified in [scenario] or [game_config] tags) a comma-separated list of music tracks from which one will be chosen and played once after any events related to the end of level result are executed; by default, victory_music is used on victory, and defeat_music on defeat.
- end_credits: Whether to display the credits screen at the end of a single-player campaign. Defaults to yes. Note that this has cumulative effects over the campaign - it persists even if the endlevel does not trigger the end of the campaign. See also CampaignWML.
- end_text: (translatable) Text that is shown centered in a black screen at the end of a campaign. Defaults to "The End". Note that this has cumulative effects over the campaign - it persists even if the endlevel does not trigger the end of the campaign. See also CampaignWML.
- end_text_duration: Delay, in milliseconds, before displaying the game credits at the end of a campaign. In other words, for how much time end_text is displayed on screen. Defaults to 3500. Note that this has cumulative effects over the campaign - it persists even if the endlevel does not trigger the end of the campaign. See also CampaignWML.
[next_scenario_settings]: Any tags or attribute children of this optional argument to [endlevel] are merged into the scenario/multiplayer tag of the *next* scenario. This allows you to e.g. reconfigure the [side] tags or settings, just before load.This feature was removed in 1.11.17, it might be redesigned and reintroduced.[next_scenario_append]: Any tags of this optional argument are appended at high level to the next scenario. This is most appropriate for [event] tags, although you may find other uses. Example test scenario for these features: https://gna.org/support/download.php?file_id=20119This feature was removed in 1.11.17, it might be redesigned and reintroduced.- [result] (Version 1.13.0 and later only) Allows specification of a side specific result, this is for competitive multiplayer scenarios/campaigns where it might happen that one player wins but another player loses. The following attributes are accepted and have the same effect as in [endlevel]:
- result
- bonus
- carryover_percentage
- carryover_add
And there is also
- side The number of the side for which these results should apply.
[unit]
Creates a unit (either on the map, on a recall list, or into a variable for later use.) For syntax see SingleUnitWML.
- (Hint: Use the GENERIC_UNIT macro)
This tag can also recall an existing unit, which happens when:
- the id= attribute is used
- a unit with that id= already exists
- (might be unnecessary) the existing unit is on the side's recall list
in this case, the unit is recalled at the x,y= or location_id= given, and any other data in the tag is ignored.
Campaign authors: a usual way to recall plot-necessary heroes is to use a macro with the data for creating that hero. This helps during debugging, because you can skip to scenarios and the recall-or-create functionality means that any units which are normally met in a previous scenario are automatically created (otherwise some scenarios may be an instant loss). This can only be used for units that must survive the previous scenarios, as it would recreate units if they died in a previous scenario. For example, HttT's NEED_DELFADOR macro.
[recall]
Recalls a unit taking into account any filter_recall of the leader. The unit is recalled free of charge, and is placed near its leader, e.g., if multiple leaders are present, near the first found which would be able to normally recall it.
If neither a valid map location is provided nor a leader on the map would be able to recall it, the tag is ignored.
- StandardUnitFilter: the first matching unit will be recalled. If no units match this tag is ignored. Do not use a [filter] tag. If a comma separated list is given, every unit currently considered for recall is checked against all the types (not each single one of the types against all units).
- x,y: the unit is placed here instead of next to the leader.
- location_id: (Version 1.15.0 and later only) the name of a special map location to recall to. Used instead of x,y.
- show: yes/no, default yes: whether the unit is animated (faded in) or instantly displayed
- fire_event: boolean yes|no (default no); whether any according prerecall or recall events shall be fired.
- check_passability: (boolean yes|no, default yes): If yes, checks for terrain passability when placing the unit (a nearby passable hex is chosen).
- [secondary_unit]: (Version 1.13.? and later only) If present and show=yes, a matching unit will be chosen and their recruiting animation played.
[teleport]
Teleports a unit on map. (Hint: Use the TELEPORT_UNIT macro)
- [filter]: StandardUnitFilter the first unit matching this filter will be teleported.
- x,y: the hex to teleport to. If that hex is occupied, the closest unoccupied hex will be used instead.
- location_id: (Version 1.15.0 and later only) the name of a special map location to teleport to. Used instead of x,y.
- clear_shroud: should shroud be cleared on arrival
- animate: should a teleport animation be played (if the unit doesn't have a teleport animation, it will fade out/fade in)
- check_passability: (boolean yes|no, default yes): normally, units will not be teleported into terrain that is impassable for them. Setting this attribute to "no" permits it.
(Note: There is also a ability named teleport, see AbilitiesWML.)
[terrain_mask]
Changes the terrain on the map. See TerrainMaskWML.
[terrain]
Changes the terrain on the map.
- terrain: the character of the terrain to use. See TerrainCodesWML to see what letter a type of terrain uses.
- StandardLocationFilter. This StandardLocationFilter's terrain= key is used for the new terrain, filtering by terrain can be done with a nested StandardLocationFilter: [and]terrain=terrain_string_to_be_filtered_for.
- layer: (overlay|base|both, default=both) only change the specified layer.
- replace_if_failed: (default=no) When replacing just one layer failed, try to replace the whole terrain. If terrain is an overlay only terrain, use the default_base as base layer. If the terrain has no default base, do nothing.
- location_id: This key sets a string as a way to mark the hex or hexes for later reference. It is very similar to the leader starting position, and can also be set that way in the map editor.
If you want to remove the overlays from a terrain and leave only the base, use:
layer=overlay terrain="^"
Note: When a hex changes from a village terrain to a non-village terrain, and a team owned that village it loses that village. When a hex changes from a non-village terrain to a village terrain and there is a unit on that hex it does not automatically capture the village. The reason for not capturing villages is that there are too many choices to make; should a unit lose its movement points, should capture events be fired. It is easier to do this as wanted by the author in WML.
[gold]
Gives sides gold.
- amount: the amount of gold to give.
- side: (default=1) the number of the side to give the gold to. Can be a comma-separated list of sides. note: Default side=1 for empty side= is deprecated.
- StandardSideFilter tags and keys; default for empty side= is all sides, as usual in a SSF.
[unstore_unit]
Creates a unit from a game variable, and activates it on the playing field or recall list. This must be a specific variable describing a unit, and may not be an array (if it is, only the first unit will be unstored).
This may be useful in different contexts:
- To update a unit on the map after having edited its WML. This usage is common, but discouraged - if possible, you should use [modify_unit] or [object] instead.
- To place a previously-defined unit into the scenario, if it was directly defined in a WML variable, using [unit] with the key to_variable. This usage is rather uncommon.
- To place a unit back into the game that was removed earlier, for example a hero that leaves the party for awhile and then comes back.
The variable is not cleared. To unstore units from an array variable, iterate over the array. See VariablesWML and VariablesWML/How to use variables for more information about variable usage. See also [store_unit], For, [while] and [clear_variable].
The tag takes the following keys:
- variable: This is required to indicate the name of the variable to read the unit from.
- Placement keys:
- x ,y: By default, the unit will be placed at the location specified in the variable, but if these keys are present, the unit will be placed at that location instead. To place the unit on the recall list of its side, use x,y=recall,recall. (If you want to change the said, you need to first update $unit.side in the variable before unstoring.)
- location_id: (Version 1.15.0 and later only) The name of a special map location to unstore to. Used instead of x,y.
- find_vacant (yes|no, default no): Whether the unit should be placed on the nearest vacant tile to its specified location. If this is set to 'no' (default), then any unit on the same tile as the unit being unstored will be destroyed.
- check_passability (yes|no, default yes): Only relevant if find_vacant=yes. In that case, this determines whether game will try to find a passable tile for the unit. If set to no, the unit may be placed on an impassable tile. Note that if both find_vacant and check_passability are set, then the unit's position may be shifted even if there is not a unit on the target space, if that space is not passable for the unit.
- Animation keys (these determine the visual effect of how the unit is placed or updated):
- text: (translatable) A floating text to display above the unit, such as a damage amount.
- male_text, female_text: (Version 1.13.2 and later only) (translatable) gender-specific versions of the above
- red, green, blue: (default=0,0,0) the color of the text. Values vary from 0-255. You may find it convenient to use the {COLOR_HARM} or {COLOR_HEAL} macro instead. (Use {COLOR_HARM} or {COLOR_HEAL} instead of the whole red,green,blue= line.)
- animate: (boolean yes|no, default yes) Determines whether to play any animations associated with the unstore. Currently this only affects the advancement animation ("levelout" and "levelin", defaulting to a fade to white and back) if the unit ends up advancing.
- Side-effect keys (these directly modify the behaviour of the action):
- advance: (default=yes) if yes the unit is advanced if it has enough XP. When modifying XP, make sure to do it from inside a synchronized event or it may lead to OOS errors, especially when several advancement paths exist. Note that advance and post advance events are called, so infinite loops can happen.
- fire_event (yes|no, default no): Whether any advance/post advance events shall be fired if an advancement takes place. This also affects whether the unit placed event is fired.
Units can be unstored with negative (or zero) hit points. This can be useful if modifying a unit in its last_breath event (as the unit's death is already the next step), but tends to look wrong in other cases. In particular, it is possible to have units with negative hit points in play. Such units are aberrations, subject to unusual behavior as the game compensates for them. (For example, such units are currently automatically hit—and killed—in combat.) The details of the unusual behavior are subject to change between stable releases without warning.
[allow_recruit]
Allows a side to recruit units it couldn't previously recruit. Any leader on this side will now be able to recruit the new units.
- type: the types of units that the side can now recruit.
- side: (default=1) the number of the side that is being allowed to recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated.
- StandardSideFilter tags and keys; default for empty side= is all sides, as usual in a SSF.
[allow_extra_recruit]
Allows a leader to recruit units it couldn't previously recruit. These types are in addition to the types the leader can recruit because of [side]recruit= and [allow_recruit].
- extra_recruit: the types of units that the leader can now recruit.
- StandardUnitFilter: All units matching this filter are modified. Does not match on recall list units.
[disallow_recruit]
Prevents a side from recruiting units it could previously recruit. No leader on this side will be able to recruit the specified units anymore, unless that leader has the same unit in their personal extra_recruit list.
- type: the types of units that the side can no longer recruit. (Version 1.13.0 and later only) If omitted, all recruits for matching sides will be disallowed.
- side: (default=1) the number of the side that may no longer recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated.
- StandardSideFilter tags and keys; default for empty side= is all sides, as usual in a SSF.
[disallow_extra_recruit]
Prevents a leader from recruiting units it could previously recruit. This won't prevent the leader from recruiting that unit if the unit is in the [side]recruit= list – you must use [disallow_recruit] in that case.
- extra_recruit: the types of units that the leader can no longer recruit.
- StandardUnitFilter: All units matching this filter are modified. Does not match on recall list units.
[set_recruit]
Sets the units a side can recruit. Any leader on this side will now be able to recruit these units.
- recruit: the types of units that the side can now recruit.
- side: The number of the side that is having its recruitment set. This can be a comma-separated list.
- StandardSideFilter tags and keys; default for empty side= is all sides, as usual in a SSF.
[set_extra_recruit]
Sets the units a leader can recruit. These types are in addition to the types the leader can recruit because of [side]recruit= and [set_recruit].
- extra_recruit: the types of units that the leader can now recruit.
- StandardUnitFilter: All units matching this filter are modified. Does not match on recall list units.
[modify_side]
Modifies some details of a given side in the middle of a scenario. The following listed properties are the only properties that [modify_side] can affect!
- side: (default=1) the number of the side that is to be changed. note: Default side=1 for empty side= is deprecated.
- [filter_side] with a StandardSideFilter as argument
- income: the income given at the begining of each turn.
- recruit: a list of unit types, replacing the side's current recruitment list.
- team_name: the team in which the side plays the scenario.
- user_team_name: a translatable string representing the team's description. This has no effect on alliances. Defaults to team_name.
- side_name: (Version 1.13.? and later only) a translatable string representing the side leader's description.
- gold: the amount of gold the side owns.
- village_gold: the income setting per village for the side.
- controller: the identifier string of the side's controller. Uses the same syntax of the controller key in the [side] tag. warning: in multiplayer, changing the controller of a side might result in OOS during some events like, for example 'side_turn_end'; see issue #2563.
- fog: a boolean string (yes/no) describing the status of Fog for the side.
- shroud: a boolean string describing the status of Shroud for the side.
- hidden: a boolean string specifying whether side is shown in status table.
- color: a team color range specification, name (e.g. "red", "blue"), or number (e.g. "1", "2") for this side. The default color range names, numbers, and definitions can be found in data/core/team_colors.cfg.
- [ai]: sets/changes AI parameters for the side. Only parameters that are specified in the tag are changed, this does not reset others to their default values. Uses the same syntax as described in AiWML. Note that [modify_side][ai] works for all simple AI parameters and some, but not all, of the composite ones. If in doubt, use [modify_ai]] instead, which always works. (Version 1.13.? and later only) If this contains an ai_algorithm, the AI parameters will be reset to those of the indicated AI before adding any additional parameters included in the tag. In other words, this allows replacing the AI config rather than appending to it.
- switch_ai: replaces a side ai with a new AI from specified file(ignoring those AI parameters above). Path to file follows the usual WML convention.
- reset_maps: If set to "yes", then the shroud is spread to all hexes, covering the parts of the map that had already been explored by the side, including hexes currently seen. (Seen hexes will be cleared at the end of most events; they can also be manually cleared with [redraw].) This is only effective if shroud is on, but this is evaluated after shroud= (and before shroud_data=).
- reset_view: If set to "yes", then the fog of war is spread to all hexes, covering the parts of the map that had already been seen this turn by the side, including hexes currently seen, excluding hexes affected by multi-turn [lift_fog]. (Seen hexes will be cleared at the end of most events; they can also be manually cleared with [redraw].) This is only effective if fog is on, but this is evaluated after fog=.
- share_maps: change the share_maps side attribute. Be sure to use shroud=yes for that side and have it as an ally
- share_view: change the share_view side attribute. Be sure to use fog=yes for that side and have it as an ally
- share_vision: change both the above at the same time
- shroud_data: changes to the side's shroud, using the same format as when defining the [side].
- suppress_end_turn_confirmation: Boolean value controlling whether or not a player is asked for confirmation when skipping a turn.
- scroll_to_leader: Boolean value controlling whether or not the game view scrolls to the side leader at the start of their turn when present.
- flag: Flag animation for villages owned by this side (see [side]).
- flag_icon: Flag icon used for this side in the status bar (see [side]).
- village_support: The number of unit levels this side is able to support (does not pay upkeep on) per village it controls.
- defeat_condition (Version 1.13.0 and later only): When the side is considered defeated (see [side]).
- [set_variable], [clear_variable] (Version 1.15.3 and later only) Sets or clears a variable within the side; uses the same syntax as [set_variable] or [clear_variable] in ActionWML.
- [variables] (Version 1.15.3 and later only) The contents of this tag is merged into the side's variables.
[modify_turns]
Modifies the turn limit in the middle of a scenario.
- value: the new turn limit.
- add: if used instead of value, specifies the number of turns to add to the current limit (can be negative).
- current: changes the current turn number after applying turn limit modifications, if any. It is not possible to change the turn number to exceed the turn limit (1 <= current turns <= max turns).
[allow_end_turn]
Allows human players to end their turn through the user interface if they were previously affected by the [disallow_end_turn] action. This action doesn't take any arguments.
[disallow_end_turn]
Disallows human players to end their turn through the user interface. This action doesn't require arguments.
- reason (translatable): (Version 1.15.0 and later only) Allows to optionally specify a reason.
[capture_village]
Changes the ownership of a village.
- StandardLocationFilter: all village locations matching the filter are affected.
- side: the side that takes control of the village. This side needs to have a leader (canrecruit=yes). If the side key is not given, the village will become neutral (unless [filter_side] is present, in which case that side fiter decides, see below).
- [filter_side] with StandardSideFilter tags and keys as arguments; if both this tag and inline side= are present it's an error. Otherwise, the first matching side gets ownership (or the village becomes neutral if none match).
- fire_event (boolean yes|no, default: no): Whether any capture events shall be fired.
[kill]
Removes all units (including units in a recall list) that match the filter from the game.
- StandardUnitFilter: Selection criterion; do not use a [filter] tag.
- animate (default 'no'): if 'yes', displays the unit dying (fading away). (Version 1.13.8 and later only) If [secondary_unit] is given, also plays the victory animation of that unit.
- fire_event (default 'no'): if 'yes', triggers any appropriate 'die' events (See EventWML). Note that events are only fired for killed units that have been on the map (as opposed to recall list).
- [secondary_unit] with a StandardUnitFilter as argument. Do not use a [filter] tag. Has an effect only if fire_event=yes ((Version 1.13.8 and later only) or if it has a victory animation and animate=yes). The first on-map unit matching the filter becomes second_unit in any fired die and last breath events. If an on-map unit matches and if there are several units killed with a single [kill] tag, second_unit is this same unit for all of them. If no on-map unit matches or [secondary_unit] isn't present, the variable second_unit in each of the die and last breath events is always the same as the variable unit (the dying unit).
- [primary_attack] (Version 1.13.8 and later only) The attacker's weapon to use for matching the animation. Useful for example on the wose, whose death animation depends on the damage type it was killed by. If a secondary unit is specified, this is taken as a StandardWeaponFilter and used to find a matching weapon on the unit. However, if there is no secondary unit specified, it is instead treated as an weapon definition, and the animation will be run as if an imaginary unit possessing that weapon was the attacker.
- [secondary_attack] (Version 1.13.8 and later only) Similar to the above, but for the defender's weapon. This is taken as a StandardWeaponFilter and used to find a matching weapon on the dying unit.
[move_unit]
Moves a unit along a path on the map. The path can be specified exactly, or as a series of waypoints that the unit will pass through.
- StandardUnitFilter as argument; do not use a [filter] tag. All units matching the filter are moved. If the target location is occupied, the nearest free location is chosen.
- to_x (unsigned integer): The units are moved to this x coordinate. Can be a comma-separated list, in which case the unit follows this given path during the move.
- to_y (unsigned integer): The units are moved to this y coordinate. Can be a comma-separated list.
- dir (string): (Version 1.15.0 and later only) Performs a relative movement instead of an absolute movement. For example, dir=n,n,nw will move two spaces north and then one space to the northwest. This is used instead of to_x and to_y.
- to_location: (Version 1.15.0 and later only) Moves matching units to locations placed in the map editor with the "New Location" button. Can be a comma-separated list. This is used instead of to_x and to_y.
- check_passability (boolean yes|no, default yes): Whether the terrain the unit is moved to should be checked for suiting the unit. (If it does not, a nearby suitable hex is chosen.)
- force_scroll: Whether to scroll the map or not even when [lock_view] is in effect or Follow Unit Actions is disabled in Advanced Preferences. Defaults to using [move_unit_fake]'s default value.
- clear_shroud: (Version 1.15.0 and later only) (boolean yes|no, default no) Whether to remove shroud and fog after the unit was moved, but before events are fired. It will not clear all alongside the path, only around the target destination.
- fire_event (boolean yes|no, default no): Whether any according moveto events shall be fired. The target location ($x1, $y1 in the event) may not be the same location that the unit was tried to be moved to, if the original target location is occupied or impassable.
[modify_ai]
Changes AI objects (aspects, goals, candidate actions or stages) for a specified side. See Modifying AI Components for full description.
- action (string): Takes values 'add', 'change', 'delete' or 'try_delete' to do just that for the AI object.
- path (string): Describes which AI object is to be modified.
- [facet], [goal], [candidate_action] or [stage]: Details about the AI object to be modified.
- StandardSideFilter tags and keys; default for empty side= is all sides, as usual in a SSF.
[modify_unit]
works similar to the MODIFY_UNIT macro.
- [filter] with a StandardUnitFilter as argument. All units matching this filter are modified. Matches on recall list units too.
- [object], [trait], (Version 1.13.5 and later only) [advancement] - The given modifications will be immediately applied to all units matching the filter. ([object] is described further below)
- delayed_variable_substitution (Version 1.13.5 and later only) (boolean yes|no, default no): If set to "yes", the wml block contained in this [object], [trait], or [advancement] is not variable-substituted at execution time of the event containing this [modify_unit]. You need this for any effect that uses variable substitution or when using [effect][filter] with a $this_unit. (Version 1.13.9 and later only) This is no longer needed when adding ABILITY_TELEPORT, ABILITY_LEADERSHIP or SPECIAL_BACKSTAB.
- Do not use a [modifications] tag, as this may skip some of the special-case handling for newly added objects, traits and advancements, and will potentially overwrite existing modifications.
- [effect] (Version 1.13.6 and later only) Applies the effect directly to the unit. See EffectWML.
- [set_variable], [clear_variable] (Version 1.15.3 and later only) Sets or clears a variable within the unit (saved inside the unit's [variables] tag); uses the same syntax as [set_variable] or [clear_variable] in ActionWML.
- Accepts generally the syntax inside of wml unit variables created by [store_unit] which can be viewed in a savefile or by using the inspect command. Cannot remove things or add/alter unit animations. Subtags with the same name must be written in the correct order to match them with the tag they are supposed to modify. Note that keys will be processed in arbitrary order, which may cause problems if you use formulas that depend on other formulas. To work around this you may need to use the tag twice with the same filter.
example usage (see also the test scenario):
[modify_unit]
[filter]
x,y=38,6
[/filter]
hitpoints=10
{TRAIT_HEALTHY}
[/modify_unit]
The unit which is currently modified is accessible via $this_unit, e.g. hitpoints = "$($this_unit.hitpoints / 2)" to set the hitpoints of all units to half of their current value. This this_unit variable is independent from the this_unit variable available in the SUF used to determine which units to modify (first all matching units are gathered, and then all those are modified).
Modifying a unit may trigger an advancement event if the experience is set higher than the max_experience. However, this behaviour should not be relied upon to happen under all circumstances; if it's desired, the event should be triggered separately, for example with [transform_unit].
Note: Some some properties of the units are reset sometimes (for example when the unit advances or when [remove_object] is called), so it's usually better to change them with [object] ([object] inside [modify_unit]) than to change those properties directly via [modify_unit]. The following properties are _not_ reset in [remove_object] and are thus safe to use directly in [modify_unit]:
- side
- gender
- name
- canrecruit
- unrenamable
- extra_recruit
- [variables]
- facing
- x, y
- goto_x, goto_y
- hitpoints
- experience
- moves
- [status]
- attacks_left
- role
[transform_unit]
Transforms every unit on the map matching the filter to the given unit type. Keeps intact hit points, experience and status. If the unit is transformed to a non-living type (undead or mechanical), it will be also unpoisoned. Hit points will be changed if necessary to respect the transformed unit's maximum hit points. Regardless of anything else, the unit will be rebuilt. Thus, transforming a unit to its current type is a way to force a rebuild, for example after manually removing a modification.
- StandardUnitFilter: do not use a [filter] tag.
- transform_to: the unit type in which all the units matching the filter will be transformed. If missing, the units will follow their normal advancement.
[petrify]
- StandardUnitFilter as an argument. Do not use a [filter] tag. All units matching this filter are petrified. Recall list units are included.
[unpetrify]
- StandardUnitFilter as an argument. Do not use a [filter] tag. All units matching this filter are unpetrified. Recall list units are included.
[object]
Gives some unit an object which modifies their stats in some way. This tag can also be used in places that don't support ActionWML, such as [modify_unit] or [unit][modifications]. The following is supported in all these places:
- [effect]: one or more effect elements may be listed. See EffectWML for a description of [effect].
- duration:
- if 'scenario', effects only last until the end of the scenario.
- if 'forever' or not set, effects never wear off.
- if 'turn', effects only last until the start of the unit's next turn (when the unit refreshes movement and attacks). (Like other start-of-turn behavior, objects with a duration of "turn" won't expire before turn 2.)
- (Version 1.13.1 and later only) if 'turn end', effects only last until the end of the unit's next turn (exactly like the slowed status).
- Other keys, such as id, may be used to remove the object later, but are not used by the engine. An [object] tag can contain any arbitrary data that may be helpful to identify the object to remove later using a WML filter.
The following is supported only when using [object] as ActionWML:
- id: (Optional) By default, an object with a defined ID can only be picked up once per scenario, even if it is removed later or first_time_only=no is set for the event. You can remove this restriction by setting take_only_once=no. For filtering objects, it might be simpler to use a custom key such as item_id. The id string can contain only letters, numbers and underscores. The ID is also commonly used to manually remove the object later, for example with [remove_object].
- take_only_once: (default yes) (Version 1.13.6 and later only) If set to "no", the object's ID does not prevent it from being taken more than once.
- delayed_variable_substitution (boolean yes|no, default no): If set to "yes", the wml block contained in this [object] is not variable-substituted at execution time of the event where this [object] is within. You need this for any effect that uses variable substitution or when using [effect][filter] with a $this_unit. (Version 1.13.9 and later only) This is no longer needed when adding ABILITY_TELEPORT, ABILITY_LEADERSHIP or SPECIAL_BACKSTAB.
- [filter] with a StandardUnitFilter as argument. The first unit found that matches the filter will be given the object. Only on-map units are considered. If no unit matches or no [filter] is supplied, it tries to apply the object to the unit at the $x1,$y1 location of the event where this [object] is in. The case of no unit being at that spot is handled in the same way as no unit matching a given filter ([else] commands executed, cannot_use_message displayed). Note that units on the recall list will not be checked. To add an [object] to a unit on the recall list you have to use [modify_unit][object].
- [then]: a subtag that lets you execute actions if the filter conditions are met. The most common action that should be inside here is a [remove_item] tag, but you could probably put any tags that otherwise work in a [then] tag.
- [else]: a subtag that lets you execute actions if the filter conditions are *not* met.
- silent: whether or not messages should be suppressed. Default is "no". (Version 1.13.2 and later only) If no description is provided, this defaults to yes, but can still be overridden.
- image: the displayed image of the object.
- name: (translatable) displayed as a caption of the image.
- description: (translatable) displayed as a message of the image.
- cannot_use_message: (translatable) displayed instead of description if no unit passes the filter test.
[remove_object]
(Version 1.13.6 and later only)
Removes an object from matching units.
- StandardUnitFilter: All units on the map (but not the recall list) matching the filter have matching objects removed. Use no [filter] tag.
- object_id: The id of the object to be removed.
Note that some unit properties are not restored ideally, e.g. current unit's health reversion might not work as expected (max_hitpoints will though). (Version 1.15.0 and later only) This was fixed.
Note that [remove_object] works the following way:
- Remove the object from the unit
- Rebuild the unit to make the changes effective.
Step 2 implies that changes done for example via [modify_unit] (or via the [store_unit] + [set_variable] + [unstore_unit] technique) will be reset if those changes change a property that is a property of the unit type. See the note under [modify_unit] to get a list of properties that can safely be changed via [modify_unit].
[remove_trait]
(Version 1.15.2 and later only)
- StandardUnitFilter: All units on the map (but not the recall list) matching the filter have matching traits removed. Use no [filter] tag.
- trait_id: The id of the trait to be removed. See [trait].
[remove_shroud]
Removes some shroud from the map for a certain side (only relevant for sides that have shroud=yes).
- side: (default=1) the side for which to remove shroud. This can be a comma-separated list of sides. note: Default side=1 for empty side= is deprecated.
- [filter_side] with a StandardSideFilter as argument
- StandardLocationFilter: the range of tiles for which shroud should be removed
[place_shroud]
Places some shroud on the map for a certain side (only relevant for sides that have shroud=yes).
- side: (default=1) the side for which to place shroud. This can be a comma-separated list. note: Default side=1 for empty side= is deprecated.
- [filter_side] with a StandardSideFilter as argument
- StandardLocationFilter: the range of tiles on which shroud should be placed
[lift_fog]
Lifts the fog of war from parts of the map for a certain side (only relevant for sides that have fog=yes), allowing a player to witness what occurs there even if that player has no units within vision range.
- [filter_side] with a StandardSideFilter indicating which sides should be affected.
- StandardLocationFilter: the tiles from which fog should be lifted.
- multiturn: yes/no, default:no. The default (not multiturn) causes fog to be removed in the same way that normal vision works; the cleared tiles will remain cleared until fog is recalculated (which normally happens when a side ends its turn). When multiturn is set to "yes", the cleared tiles remain clear until [reset_fog] cancels the clearing. This allows tiles to remain clear for multiple turns, or to be refogged before the end of the current turn (without also refogging all tiles). Multiturn lifted fog is not shared with allies (even when share_vision=all).
[reset_fog]
The primary use of this tag is to remove multiturn lifted fog (created by [lift_fog]), which causes the fog to reset to what it would have been had WML not interfered. (That is, hexes that a side's units could not see at any point this turn will be re-fogged, while seen hexes remain defogged.)
- [filter_side] with a StandardSideFilter indicating which sides should be affected.
- StandardLocationFilter: the fog reset will be restricted to these tiles.
- reset_view: yes/no, default: no If set to "yes", then in addition to removing multiturn fog, the side's current view is canceled (independent of the SLF). This means that all hexes will become fogged for the side unless multiturn fog exists outside the tiles selected by the SLF. Normally, one would want the currently seen hexes to become clear of fog; this is done automatically at the end of many events, and it can be done manually with [redraw].
Omitting both the SSF and the SLF would cancel all earlier uses of [lift_fog]. Additionally setting reset_view="yes" would cause the side's entire map to be fogged (unless an ally keeps hexes clear by sharing its view).
[allow_undo]
Normally when an event with a handler fires, the player's undo stack is cleared, preventing all actions performed so far from being undone. Including this tag in the event handler prevents the stack from being cleared for this reason, allowing the player to undo actions. (However, the stack might still be cleared for other reasons, such as fog being cleared or combat occurring.) In the common cases, this means [allow_undo] allows the current action to be undone even though an event was handled. There is a less common case, though — specifically when handling a menu item, where there is no current action — and in this case, [allow_undo] means merely that earlier actions can still be undone.
- Using this tag in a menu item has an additional side effect in 1.11. Starting with version 1.11.1, executing a WML menu item normally counts as doing something as far as the "you have not started your turn yet" dialog is concerned. However, a menu item whose handler includes [allow_undo] will not count.
The types of actions that can be undone are movement, recalling, and dismissing a unit from the recall list. If an action is undone, only the position (or existence) of the involved unit will be restored; any altered variables or changes to the game will remain changed after the action is undone. It is up to the scenario designer to avoid abusing this command.
- Technically, if [allow_undo] is inside an [event] with first_time_only=yes (the default setting), and the user undoes the event, then the state of the game has changed in this way: the event will not fire a second time, even though the user undid the action the first time.
- Although recalling can be undone, recruitment can not be undone; this seems to apply even when the recruit's traits are not randomly-generated (tested on 1.12.6 and 1.14.4+dev).
If an [event] uses both [allow_undo] and [fire_event] then the [allow_undo] must be after the [fire_event].
Due to a bug in 1.12 (https://gna.org/bugs/?23323) [allow_undo] should not be used in events that use one of the following things because it might cause OOS:
- [message] with [option]s
- [get_global_variable]
- wesnoth.synchronize_choice
While in 1.13 using [allow_undo] together with those things won't give you a guaranteed OOS, there are some non-obvious situations where it will, for example assume the following event:
[event] name="moveto" [message] message = "message" [option] label = "option 1" [command] [/command] [/option] [option] label = "option 2" [command] [/command] [/option] [/message] [allow_undo] [/allow_undo] [/event]
It will cause OOS when the message is undone: since the event is already executed (erased) on one client only , the clients will disagree about how many choices happen during the next moveto action.
[on_undo]
(Version 1.13.2 and later only) Contains commands to execute when the player undoes the action which triggered the parent event.
- delayed_variable_substitution (Version 1.13.5 and later only): yes/no, default no (always no before 1.13.5) As in EventWML, specifies whether to perform variable substitution when the parent event is run, or when the contents are run. If delayed substitution is used, automatically stored variables from the parent event context are available, but may occasionally have unexpected values. (In particular, $unit.x and $unit.y may not have the expected value when undoing a move event, though $x1 and $y1 should be correct.)
Note: It is not clear where whether the actionwml in [on_undo] in executed before or after the action is undone. Also, specially for enter/leave_hex events the units position when executing the [on_undo] code is usually different than when executing the original event. The recommended way to work around these issues is to refer to the unit by id instead of position and store all other needed information variables as 'upvalues'. You can also move the actual undo code to an external event. For example
[event] name="undo_blah" first_time_only=no [store_unit] id="$moved_unit_id" [/store_unit] ... do undo stuff stuff [/event] ... ... in some other event [on_undo] # store upvalues {VARIABLE moved_unit_id $unit.id} # call actual undo handler [fire_event] name = "undo_blah" [/fire_event] [on_undo]
[on_redo]
(Version 1.13.2 and later only) Same as [on_undo], except executes the commands on redo. Note that the parent event is not triggered again on a redo.
(Version 1.13.8 and later only) [on_redo] is deprecated and has no effect anymore.
Note that [on_redo] is not guaranteed to be called when redoing an action, the engine might also decide to just fire the original events again.
[cancel_action]
Although Wesnoth 1.12 does not have this tag, it is the default behavior of enter_hex/exit_hex [event] in that version.
(Version 1.13.9 and later only) In this version, [cancel_action] is recognised, but has no effect (a bug).
(Version 1.13.11 and later only) In an enter_hex/exit_hex [event], interrupt the movement, leaving the unit where it is. This is intended to be used with an event that gives the player new information, to let the player choose whether to change their plans. For example, if the player has commanded a unit to move from (1,1) to (3,3) and attack a unit on (4,4); then a [cancel_action] inside an enter_hex [event] on (2,2) would make the unit stop on (2,2). A [cancel_action] inside an enter_hex [event] on (3,3) would let the player choose whether to attack.
(Version 1.15.0 and later only) In a capture/moveto [event], interrupt the attack.
[heal_unit]
Heal a unit. The variable $heal_amount will be set to the exact number of points healed (i.e can be less than the parameter amount if the unit is fully healed). $heal_amount contains only the number of hitpoints the first unit that was found got healed. When the variable is not needed, use {CLEAR_VARIABLE heal_amount} after this tag.
(Version 1.17.0 and later only) The $heal_amount variable is no longer set. Use the variable key instead.
- [filter]: StandardUnitFilter All matching on-map units are healed. If no filter is supplied, it is tried to take the unit at $x1, $y1.
- [filter_second]: StandardUnitFilter all the units matching the filter and having the heals ability will have their animation played (if animate is set to yes) for each of the units healed.
- amount: (integer, default full) the maximum points the unit(s) will be healed. This can't be used to set the unit's hitpoints below 1 or above the unit's maximum hitpoints. If "full", it fully heals the unit.
- animate: a boolean which indicate if the healing animations must be played. (default no)
- moves: (integer, default 0) The maximum current movement points the units will be "healed". Can't set below 0 or above max_moves. If "full", sets moves to max_moves.
- restore_attacks: (boolean, default no) Whether the units' attacks_left should be reset to their max_attacks (usually 1).
- restore_statuses: (boolean, default yes) Whether standard statuses should be reset to "no". This affects poisoned, slowed, petrified and unhealable.
- variable: (Version 1.17.0 and later only) creates an array with the given name; each item of the array has two fields, id= (the ID of the unit being healed) and heal_amount= (the amount of HPs the unit has been healed by).
[harm_unit]
Harms every unit matching the filter, for the specific damage amount. When harming multiple units, the special variable $this_unit can be used to access the current unit being harmed. This obviously does not work inside the filters though, as they give $this_unit a different meaning.
- [filter]: StandardUnitFilter all matching units will be harmed (required).
- [filter_second]: StandardUnitFilter if present, the first matching unit will attack all the units matching the filter above.
- amount: the amount of damage that will be done (required).
- alignment: (default neutral) applies an alignment to the damage, this means that if alignment=chaotic, the damage will be increased at night and reduced at day.
- damage_type: if present, amount will be altered by unit resistance to the damage type specified.
- kill: (default yes) if yes, when a harmed unit goes to or below 0 HP, it is killed; if no its HP are set to 1.
- fire_event: (default no) if yes, when a unit is killed by harming, the corresponding events are fired. If yes, also the corresponding advance and post advance events are fired.
- animate: (default no) if yes, scrolls to each unit before harming it and plays its defense (or attack, if it's the harmer) and death animations. Special values supported, other than the usual yes and no, are "attacker", that means only the harmer will be animated, and "defender", that means only the harmed units will be animated. If the supplied value is yes, attacker or defender also advancement animations are played.
- [primary_attack], [secondary_attack]: these set the weapon against which the harmed units will defend, and that the harming unit will use to attack, respectively (notice this is the opposite of [filter] and [filter_second] above). This allows for playing specific defense and attack animations. Both tags are expected to contain a Standard Weapon Filter.
- delay: if animate=yes, sets the delay (in milliseconds, default 500) between each unit harming.
- variable: if present, the damage caused to the unit, altered by resistances, will be stored in a WML array with the given name, under the harm_amount= key. (Version 1.17.0 and later only) Each item of the array also has an id= key, which contains the ID of the unit being harmed.
- poisoned, slowed, petrified, unhealable: (default no) if yes, every harmed unit that doesn't already have such status will have it set.
- experience: (default yes) If there is a harmer, experience will be attributed similar to regular combat. Can take list of values. When any value is provided, all unspecified experience types default to not giving experience. Supported values: (Version 1.17.25 and later only) until that version only experience=yes and experience=no are supported
- no - none of involved units get any experience (this value only works if it is the only value in list)
- kill - the harming unit receives experience based on level of harmed unit in attack which kills harmed unit
- attack - the harming unit receives experience based on level of harmed unit in attack which does not kill harmed unit, or in attack which kills harmed unit while kill experience is disabled
- defend - the unit being harmed receives experience based on level of harming unit in attack which does not kill harmed unit
- fight - short form of experience=attack,defend
- yes - short form of experience=kill,attack,defend
- resistance_multiplier: the harmed unit's resistance is multiplied by the supplied value; this means that a value lower than 1 increases it, and a value greater than 1 decreases it. Default value is 1, that means no modification.
[time_area]
How a day should progress in a given area. Everywhere not specified in a [time_area] tag is affected by the [time] tags in the [scenario] tag.
- StandardLocationFilter: the locations to affect. note: only for [event][time_area]s - at scenario toplevel [time_area] does not support StandardLocationFilter, only location ranges
- [time]: one or more tags describing the new schedule, see TimeWML.
- id: an unique identifier assigned to a time_area. Optional, unless you want to remove the time_area later or reference it from a location filter elsewhere. Can be a comma-separated list when removing time_areas, see below.
- remove: (boolean) yes/no value. Indicates whether the specified time_area should be removed. Requires an identifier. If no identifier is used, however, all time_areas are removed.
- current_time: The time slot number (starting with zero) active at the creation of the area.
Example: (caves in parts of a map)
[time_area]
id = cave_area
x = 1-2,4-5
y = 1-2,1-2
{UNDERGROUND}
[/time_area]
Specifying an id allows the area to be referenced from location filters. Example:
[time_area]
id = glyphs
x = 9,14
y = 11,3
[/time_area]
[event]
name = moveto
first_time_only=no
[filter]
side = 1
[filter_location]
area = glyphs
[/filter_location]
[/filter]
# Do something, for example healing the unit
[/event]
[remove_time_area]
(Version 1.13.2 and later only)
This is a syntactic shortcut for [time_area] remove=.
- id: Comma-separated list of time area ids to remove.
[end_turn]
End the current side's turn. The current event is finished before the turn is ended. Also, if the current event (where the tag appears) has been fired by another event, that event (and the complete stack of other possible parent events) is ended before [end_turn] comes into affect. Also, events following the event stack that fired [end_turn] are not omitted (e.g. [end_turn] is used by a side turn event and a turn refresh event does something afterwards).
[replace_map]
Replaces the entire map.
- map_data: Content of a wesnoth map file. (This key used to be just map=.) Example:
map_data="{campaigns/Heir_To_The_Throne/maps/01_The_Elves_Besieged.map}"
- map_file: (Version 1.13.? and later only) Path to a Wesnoth map file; can be used instead of map. The file will be loaded when the tag is executed, rather than being embedded wholesale in the preprocessed WML. Example:
map_file=campaigns/Heir_To_The_Throne/maps/01_The_Elves_Besieged.map
(Version 1.15.3 and later only) If the file is not found directly, it will be searched for in the [binary_path]. Assuming a standard campaign or add-on layout, the example above can be replaced by:
map_file=01_The_Elves_Besieged.map
- expand: if 'yes', allows the map size to increase. The expansion direction is currently always bottom-right.
- shrink: if 'yes', allows the map size to decrease. If the map size is reduced, any units that would no longer be on the map due to its coordinates no longer existing will be put into the recall list.
Note: When a hex changes from a village terrain to a non-village terrain, and a team owned that village it loses that village. When a hex changes from a non-village terrain to a village terrain and there is a unit on that hex it does not automatically capture the village. The reason for not capturing villages it that there are too many choices to make; should a unit lose its movement points, should capture events be fired. It is easier to do this as wanted by the author in WML.
[replace_schedule]
Replace the time of day schedule of the entire scenario.
- TimeWML: the new schedule.
- current_time: The time slot number (starting with zero) active at schedule replacement. (NB: due to https://github.com/wesnoth/wesnoth/issues/5757 this attribute is ignored in versions 1.16.*. The fix was delivered in 1.17.* but wasn't backported due to backward-compatibility requirements)
[tunnel]
Create a tunnel between some locations, later usable by units to move from source hex to target hex (using the movement cost of unit on the target terrain).
Behavior Change as of Wesnoth 1.13.6: Vision is now possible (and enabled by default) through tunnels and allied units on the exit hex do not block a tunnel by default any more. This is done in order for moves through tunnels to be consistent with other moves. The previous behavior can still be accomplished by using the new optional keys listed below.
- [filter]: (required) StandardUnitFilter the units which can use the tunnel. Leave empty for "all units".
- [source]: (required) StandardLocationFilter the source hex(es). Use $teleport_unit to filter on unit being teleported.
- [target]: (required) StandardLocationFilter the target hex(es). Use $teleport_unit to filter on unit being teleported.
- id: (optional) identifier for the tunnel, to allow removing.
- remove: (boolean, default: no) If yes, removes all defined tunnels with the same ID (then only id= is necessary).
- bidirectional: (boolean, default: yes) If yes, creates also a tunnel in the other direction.
- always_visible: (boolean, default: no) If yes, the possible movement of enemies under fog can be seen.
- allow_vision: (boolean, default: yes) (Version 1.13.6 and later only) If no, vision through a tunnel is not possible. Note that in that case the tunnel cannot be used if the tunnel exit is under shroud (which previously was always the case).
- pass_allied_units: (boolean, default: yes) (Version 1.13.6 and later only) If no, allied (including own) units on the exit hex block a tunnel.
- delayed_variable_substitution (boolean, default: yes): If yes, the WML block contained in this [tunnel] is not variable-substituted at execution time of the event where this [tunnel] is within. Instead, variables are substituted when the tunnel is used by a unit. See EventWML#Nested_Events
(Note: The tunnel tag can also be used inside the [teleport] ability, without remove= and id=).
[do_command]
(Version 1.13.0 and later only)
Executes a command, specified using the same syntax as a [command] tag in ReplayWML. Not all [command]'s are valid: only these are accepted
- [attack]
- [move]
- [recruit]
- [recall]
- [disband]
- [fire_event]
- [lua_ai] (Version 1.13.12 and later only) This has been removed and is replaced with [custom_command]
The tags corresponding to player actions generally use the same codepath as if a player had ordered it. That means for example that only moves that player would be allowed to do are possible, and movement is interrupted when sighting enemy unit.
One purpose of this tag is to allow scripting of noninteractive scenarios -- without a tag like this, this might require elaborate mechanisms to coerce ais in order to test these code paths.
This command should be replay safe if it is either invoked in a synced context, or invoked in code that is never synced, like AI code, a select event, or a menu item with `synced = false`. However, if you use desynchronized logic during an event that is otherwise synced, invoking [do_command] based on that desynchronized logic will result in out-of-sync errors during the replay; in this case, you must explicitly synchronize which command to do using something like the lua function wesnoth.sync.evaluate_single.
[put_to_recall_list]
(Version 1.13.0 and later only)
Puts a unit to the recall list of its side.
- StandardUnitFilter: the unit(s) to get put to the recall list.
- heal: (default=no) Whether the unit should be refreshed, similar to the unit moving to the recall list at the end of a scenario.
[set_achievement]
(Version 1.17.13 and later only)
Sets the specified achievement as completed and shows a popup stating it's been completed. The popup is not shown if the achievement has already been achieved.
- content_for: The [achievement_group] that this achievement is part of.
- id: The id of the achievement.
[set_sub_achievement]
(Version 1.17.17 and later only)
Sets the specified sub-achievement as completed.
- content_for: The [achievement_group] that this achievement is part of.
- id: The id of the achievement.
- sub_id: The id of the sub-achievement.
[progress_achievement]
(Version 1.17.13 and later only)
Progress an achievement by the specified amount, with an optional limit for how far the achievement can be progressed.
- content_for: The [achievement_group] that this achievement is part of.
- id: The id of the achievement.
- amount: The amount to increment the achievement.
- limit: (optional) Using this attribute will prevent achievements from progressing past this value.
Useful Macros
There are some predefined macros that you find useful for direct actions. You can find a complete list along with a detailed explanation of how they work here.
- {MOVE_UNIT}: Moves a unit to another location in the map and the player sees the movement (unlike [teleport])
- {FULL_HEAL}: Brings a unit to full HP
- {LOYAL_UNIT}: Create a loyal unit
- {MODIFY_TERRAIN_MASK}: Modify an area of terrain