Difference between revisions of "StandardLocationFilter"

From The Battle for Wesnoth Wiki
(Added an in-depth clarification of how radius= works.)
(Added "Attributes" section (and removed __NOTOC__ !!!))
(40 intermediate revisions by 14 users not shown)
Line 1: Line 1:
 
{{WML Tags}}
 
{{WML Tags}}
 +
From [[FilterWML]], this is the standard way of filtering on locations.
 +
The term [[StandardLocationFilter]] means that the set of such keys and tags (see below) can appear at that point. Sometimes a [[StandardLocationFilter]] needs to be included in a [filter_location] tag. There are however many tags which accept the [[StandardLocationFilter]] directly as an argument such as [store_locations]. Generally, if the tag [filter_location] is not mentioned to be a possible subtag of the outer tag in question, then don't put it.
  
From [[FilterWML]], this is the standard way of filtering on locations. The following attributes and sub-tags are permitted:
+
== Attributes ==
 +
The following attributes and sub-tags are permitted:
  
* '''time_of_day''': filter matches only on a given time of day (one of lawful, chaotic or neutral).
+
* '''time_of_day''': filter matches only on a given time of day (one of lawful, chaotic, or neutral). Note: ''chaotic'', ''lawful'', and ''neutral''; these are not times of day, these are ''alignments''. To match against 'dawn', 'dusk', 'first watch' etc., use the '''time_of_day_id''' key described below.
* '''terrain''': comma separated list of terrains. (See also: [http://www.wesnoth.org/wiki/FilterWML#Filtering_Terrains Filtering Terrains]).
+
* '''time_of_day_id''': this accepts a list of one or more actual times of day, separated by commas. These IDs are taken from '''data/core/macros/schedules.cfg'''. Permissible values are case-sensitive: dawn, morning, afternoon, dusk, first_watch, second_watch, indoors, underground and deep_underground.
* '''x,y''': the same as in the unit filter; supports any range ([http://www.wesnoth.org/wiki/StandardLocationFilter#Notes_about_Coordinate_Usage notes])
+
* '''terrain''': comma separated list of terrains. (See also: [[#Filtering_Terrains|Filtering Terrains]]).
* '''[filter]''': a [[StandardUnitFilter]]; if present a unit must also be there
+
* '''x,y''': the same as in the unit filter; supports any range ([[StandardLocationFilter#Notes_about_Coordinate_Usage|notes]])
* '''owner_side''': the side of the owner, if this location is an owned village.
+
* '''location_id''': {{DevFeature1.13|?}} Matches a special location set in the map. This can also be a side number to match that side's starting location. Note: this does not accept a comma separated list, one has to use [or] tags. {{DevFeature1.15|0}} Accepts a comma separated list.
 +
* '''area''': matches locations assigned to the [[DirectActionsWML#.5Btime_area.5D|[time_area]]] with the given id.
 +
* '''include_borders''': {{DevFeature1.13|0}} whether the SLF will include border hexes or not. Will override the default behavior of the tag this appears in.
 +
* '''[filter]''' with a [[StandardUnitFilter]] as argument; if present a unit must also be there
 +
* '''owner_side''': If a valid side number, restricts stored locations to villages belonging to this side. If 0, restricts to all unowned locations (the whole map except villages which belong to some valid side). A hex is considered a village if and only if its [ [[TerrainWML|terrain_type]] ]gives_income= parameter was set to yes (which means a side can own that hex).
 +
* '''[filter_vision]''': this tests whether or not the location is currently visible
 +
** '''visible''': yes or no, default yes. "yes" filters for visible locations, "no" filters for invisible locations.
 +
** '''respect_fog''': yes or no, default yes. "yes" filters for locations that are clear of both fog and shroud, "no" filters for locations that are clear of shroud.
 +
** [[StandardSideFilter]] tags and keys as arguments. If there is *at least one* matching side which can see the location then the filter matches, and otherwise it fails to match.
 +
*'''[filter_owner]''': If present, inline owner_side= is ignored. Restricts stored locations to villages, each of which must belong to any of the matching sides. If no sides match, restricts to unowned villages (and only these).
 +
**'''[[StandardSideFilter]]''' tags and keys as arguments
 
* '''find_in''': name of an array or container variable; if present, the location will not match unless it is also found stored in the variable
 
* '''find_in''': name of an array or container variable; if present, the location will not match unless it is also found stored in the variable
* '''radius''': matches if any location within the radius matches this filter ([http://www.wesnoth.org/wiki/StandardLocationFilter#Notes_about_Radius_Usage notes])
+
* '''radius''': matches if any location within the radius matches this filter ([[StandardLocationFilter#Notes_about_Radius_Usage|notes]])
 
* '''[filter_radius]''': a standard location filter; normally the radius extends outwards from matching locations one step at a time without checking any additional information-- however, if this tag is present, the radius will be restricted so that it can only expand outwards in the directions where it passes the given location filter
 
* '''[filter_radius]''': a standard location filter; normally the radius extends outwards from matching locations one step at a time without checking any additional information-- however, if this tag is present, the radius will be restricted so that it can only expand outwards in the directions where it passes the given location filter
 
* '''[and]''': an extra location filter. Unless a location matches the [and] filter, then it will be excluded. ''Note: [and],[or],and [not] extra location filters are considered after everything else in the containing filter (except radius, which is considered last in 1.3.8 and greater); they are then processed in the order encountered.''
 
* '''[and]''': an extra location filter. Unless a location matches the [and] filter, then it will be excluded. ''Note: [and],[or],and [not] extra location filters are considered after everything else in the containing filter (except radius, which is considered last in 1.3.8 and greater); they are then processed in the order encountered.''
Line 16: Line 29:
 
* '''[filter_adjacent_location]''': a standard location filter; if present the correct number of adjacent locations must match this filter
 
* '''[filter_adjacent_location]''': a standard location filter; if present the correct number of adjacent locations must match this filter
 
** '''count''': a number, range, or comma separated range; default "1-6"
 
** '''count''': a number, range, or comma separated range; default "1-6"
** '''adjacent''': a comma separated list of directions; default "n,ne,se,s,sw,nw"
+
** '''adjacent''': a comma separated list of directions; default "n,ne,se,s,sw,nw" (see [[#Directions|notes]])
 +
* '''formula''': {{DevFeature1.13|5}} a [[Wesnoth Formula Language]] formula. Some terrain-specific variables, for example "light" and "castle", can be used in the filter [[#Wesnoth_Formula_Language|(see list below)]].
 +
* '''lua_function''': {{DevFeature1.13|5}} the name of a [[LuaWML|Lua]] function in the global environment that takes arguments <code>x, y</code> and returns true if the given location matches the filter. Non-global functions can now be used here by building a dot-separated "path". Note that this is not actually interpreted as Lua code even though it superficially resembles it, so using a Lua keyword in the path will work, for example "my_filter_functions.goto" will correctly use the function which in actual Lua code would need to be referenced as <code>my_filter_functions["goto"]</code>.
  
 
==Notes about Coordinate Usage==
 
==Notes about Coordinate Usage==
 +
 
When specifying coordinates, the following keys are used:
 
When specifying coordinates, the following keys are used:
 
* '''x''': the first coordinate
 
* '''x''': the first coordinate
Line 32: Line 48:
  
 
Commas(''',''') are used to separate coordinates into a list.
 
Commas(''',''') are used to separate coordinates into a list.
The '''x''' and '''y''' lists are then paired up, with each pair representing one hex or range.
+
The '''x''' and '''y''' lists are then paired up, with each pair representing one hex or range.  
 +
E.g. in order to specify multiple locations 1,4 and 2,5, use:
 +
 
 +
<syntaxhighlight lang='wml'>
 +
[tag]
 +
    x=1,2
 +
    y=4,5
 +
[/tag]
 +
</syntaxhighlight>
 +
 
 +
You should have the same number of commas in each list, and both '''x''' and '''y''' are always lists. For example, this does not mean the locations (1,4) and (2,4):
 +
<syntaxhighlight lang='wml'>
 +
[tag]
 +
    x=1,2
 +
    y=4    # bad example, implementation-defined behavior
 +
[/tag]
 +
</syntaxhighlight>
 +
 
 +
A pair can have a single value for one coordinate and a range for the other. This matches (1,4) and the entire column from (2,1) downwards:
 +
<syntaxhighlight lang='wml'>
 +
[tag]
 +
    x=1,    2
 +
    y=4,1-999
 +
[/tag]
 +
</syntaxhighlight>
 +
 
 +
Providing only '''x''' or only '''y''' is valid. This matches the entire columns from (1,1) and (2,1) downwards:
 +
<syntaxhighlight lang='wml'>
 +
[tag]
 +
    x=1,2
 +
[/tag]
 +
</syntaxhighlight>
  
 
Note: although the ordering of locations in a list generally does not matter,
 
Note: although the ordering of locations in a list generally does not matter,
Line 39: Line 86:
  
 
==Notes about Radius Usage==
 
==Notes about Radius Usage==
:If you aren't storing any locations successfully, it may be because you put the radius or filters in the wrong place for them to combine correctly.
+
If you aren't storing any locations successfully, it may be because you put the radius or filters in the wrong place for them to combine correctly.
  [have_location]
+
 
  terrain=Gg^Vh
+
<syntaxhighlight lang='wml'>
  [and]
+
[have_location]
    x=$x1
+
    terrain=Gg^Vh
    y=$y1
+
    [and]
    radius=1
+
        x=$x1
  [/and]
+
        y=$y1
  [/have_location]
+
      radius=1
 +
    [/and]
 +
[/have_location]
 +
</syntaxhighlight>
 +
 
 
Note that the use of [and] here causes the radius to have a very different meaning. Normally, all of the criteria besides radius are checked, producing a set of hexes to which the radius is applied. This means, for example, that if you're trying to find "a hex without a unit on it within 5 hexes of (15, 23)", the code:
 
Note that the use of [and] here causes the radius to have a very different meaning. Normally, all of the criteria besides radius are checked, producing a set of hexes to which the radius is applied. This means, for example, that if you're trying to find "a hex without a unit on it within 5 hexes of (15, 23)", the code:
  [have_location]
+
 
  x,y=15,23
+
<syntaxhighlight lang='wml'>
  radius=5
+
[have_location]
  [not]
+
    x,y=15,23
 +
    radius=5 # oops... this time it won't work as expected
 +
    [not]
 +
        [filter]
 +
        [/filter]
 +
    [/not]
 +
[have_location]
 +
</syntaxhighlight>
 +
 
 +
will not work! First, it looks for a hex with x=15, y=23 without a unit on it. Then, it returns that hex and all hexes within 5 of it. If (15, 23) happens to be occupied, then it will return no hexes, because "all hexes within 5 hexes of (no hexes)" is still "no hexes". Instead, put an [and] around the x,y and radius requirements, and it will separately find "(15, 23) and all hexes within 5 of it" and "each of those hexes that doesn't have a unit on it", producing the desired result.
 +
 
 +
== Directions ==
 +
 
 +
Some attributes expect a direction or list of directions. Valid base directions are n, ne, nw, s, se, sw, and there are three operators supported as well:
 +
 
 +
* To take the opposite direction, use - (eg -n is the same as s)
 +
* {{DevFeature1.13|2}} To rotate clockwise, use :cw (eg n:cw is the same as ne)
 +
* {{DevFeature1.13|2}} To rotate counterclockwise, use :ccw (eg n:ccw is the same as nw)
 +
 
 +
You can't apply multiple rotation operators - for example, "n:cw:ccw" is not a valid direction. If for some reason you really need multiple rotations, you can use parentheses (so, "(n:cw):ccw" is valid and is the same as n). Similarly, "--n" is not valid, but "-(-n)" is valid and is the same as n.
 +
 
 +
This syntax is mainly useful when used in conjunction with variable substitution in the adjacent key in [filter_adjacent_location] and in [filter_adjacent] (in [[StandardUnitFilter]]), but will work anywhere a direction is expected. For example, using [modify_unit] to change a unit's direction:
 +
 
 +
<syntaxhighlight lang='wml'>
 +
[modify_unit]
 +
    [filter]
 +
        # ... Whatever filter you need
 +
    [/filter]
 +
    facing=-$this_unit.facing
 +
[/modify_unit]
 +
</syntaxhighlight>
 +
 
 +
That will cause the matched units to turn around.
 +
 
 +
== Filtering Terrains ==
 +
 
 +
The '''terrain=''' key allows you to filter based on the terrain of a space, for example:
 +
 
 +
<syntaxhighlight lang='wml'>
 +
[event]
 
     [filter]
 
     [filter]
 +
        [filter_location]
 +
            terrain=Ch
 +
        [/filter_location]
 
     [/filter]
 
     [/filter]
  [/not]
+
[/event]
  [have_location]
+
</syntaxhighlight>
will not work! First, it looks for a hex with x=15, y=23 without a unit on it. Then, it returns that hex and all hexes within 5 of it. If (15, 23) happens to be occupied, then it will return no hexes, because "all hexes within 5 hexes of (no hexes)" is still "no hexes". Instead, put an [and] around the x,y and radius requirements, and it will separately find "(15, 23) and all hexes within 5 of it" and "each of those hexes that doesn't have a unit on it", producing the desired result.
+
 
 +
At some places the terrains can be filtered with a match list. This list is a comma separated list of [[TerrainCodesWML|terrain strings]] and patterns which will be processed in order. As soon as a pattern matching the reference terrain is found, the result of the filter will be determined.
 +
 
 +
Normally, if one of the patterns matches, the filter is considered successful. However, the special pattern <tt>!</tt> inverts this every time it is encountered &ndash; when inverted, the filter is considered ''unsuccessful'' when one of the patterns matches. In other words, <tt>Gg</tt> matches only basic grass, while <tt>!,Gg</tt> matches ''anything but'' basic grass.
 +
 
 +
When the end of the list is reached without any matches, normally the result is an unsuccessful match. However, if the match is currently inverted, ie there are an odd number of <tt>!</tt>, then the result is a successful match.
 +
 
 +
An individual terrain pattern consists of two parts, the base and the overlay, separated by the <tt>^</tt> character. The overlay (including the preceding <tt>^</tt>) is optional; if omitted, only terrains without overlays can be matched. The pattern may end with the wildcard character <tt>*</tt> (or be composed solely of the wildcard character). The pattern to match any terrain is <tt>*^*</tt>.
 +
 
 +
<b>Example 1:</b> <br>
 +
ww* matches ww, www, wwW but not WWW <br>
 +
!, ww returns false if ww found and true if not <br>
 +
!, ww, wa, !, aa returns false if ww or wa found and true if aa found and false if none found.
 +
 
 +
<b>Example 2:</b> <br>
 +
<nowiki>*</nowiki>^V* matches all village-terrain <br>
 +
Notice how the * can be used separately for both layers (base and overlay layers are separated by the ^-character).
 +
 
 +
For a list of terrain types and their string codes see [[TerrainCodesWML|TerrainCodesWML]].
 +
 
 +
== Wesnoth Formula Language ==
 +
 
 +
When using SLF's '''formula''' attribute, the following read-only terrain properties are available:
 +
 
 +
* '''x'''
 +
* '''y'''
 +
* '''loc'''
 +
* '''id'''
 +
* '''name'''
 +
* '''editor_name'''
 +
* '''description'''
 +
* '''icon'''
 +
* '''light'''
 +
* '''village''': a boolean containing the value of [terrain_type]gives_income=
 +
* '''castle'''
 +
* '''keep'''
 +
* '''healing''': an integer containing the value of [terrain_type]heals=
 +
* '''owner'''
 +
 
 +
For an up-to-date list, check the C++ function terrain_callable::get_value(const std::string& key) const.
 +
 
 +
== Tutorial ==
 +
* [http://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter How To Use Filter (with examples)]
 +
 
 +
== See Also ==
 +
 
 +
* [[FilterWML]]
 +
 
 
[[Category: WML Reference]]
 
[[Category: WML Reference]]

Revision as of 19:53, 10 November 2019

[edit]WML Tags

A:

abilities, about, add_ai_behavior, advance, advanced_preference, advancefrom, advancement, advances, affect_adjacent, ai, allied_with, allow_end_turn, allow_extra_recruit, allow_recruit, allow_undo, and, animate, animate_unit, animation, aspect, attack, attack_anim, attacks, avoid;

B:

base_unit, berserk, binary_path, break, brush;

C:

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

D:

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

E:

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

F:

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

G:

game_config, get_global_variable, goal, gold, gold_carryover;

H:

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

I:

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

J:

jamming_costs, join;

K:

kill, killed;

L:

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

M:

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

N:

not, note;

O:

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

P:

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

R:

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

S:

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

T:

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

U:

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

V:

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

W:

while, wml_message, wml_schema;

Z:

zoom;

From FilterWML, this is the standard way of filtering on locations. The term StandardLocationFilter means that the set of such keys and tags (see below) can appear at that point. Sometimes a StandardLocationFilter needs to be included in a [filter_location] tag. There are however many tags which accept the StandardLocationFilter directly as an argument such as [store_locations]. Generally, if the tag [filter_location] is not mentioned to be a possible subtag of the outer tag in question, then don't put it.

Attributes

The following attributes and sub-tags are permitted:

  • time_of_day: filter matches only on a given time of day (one of lawful, chaotic, or neutral). Note: chaotic, lawful, and neutral; these are not times of day, these are alignments. To match against 'dawn', 'dusk', 'first watch' etc., use the time_of_day_id key described below.
  • time_of_day_id: this accepts a list of one or more actual times of day, separated by commas. These IDs are taken from data/core/macros/schedules.cfg. Permissible values are case-sensitive: dawn, morning, afternoon, dusk, first_watch, second_watch, indoors, underground and deep_underground.
  • terrain: comma separated list of terrains. (See also: Filtering Terrains).
  • x,y: the same as in the unit filter; supports any range (notes)
  • location_id: (Version 1.13.? and later only) Matches a special location set in the map. This can also be a side number to match that side's starting location. Note: this does not accept a comma separated list, one has to use [or] tags. (Version 1.15.0 and later only) Accepts a comma separated list.
  • area: matches locations assigned to the [time_area] with the given id.
  • include_borders: (Version 1.13.0 and later only) whether the SLF will include border hexes or not. Will override the default behavior of the tag this appears in.
  • [filter] with a StandardUnitFilter as argument; if present a unit must also be there
  • owner_side: If a valid side number, restricts stored locations to villages belonging to this side. If 0, restricts to all unowned locations (the whole map except villages which belong to some valid side). A hex is considered a village if and only if its [ terrain_type ]gives_income= parameter was set to yes (which means a side can own that hex).
  • [filter_vision]: this tests whether or not the location is currently visible
    • visible: yes or no, default yes. "yes" filters for visible locations, "no" filters for invisible locations.
    • respect_fog: yes or no, default yes. "yes" filters for locations that are clear of both fog and shroud, "no" filters for locations that are clear of shroud.
    • StandardSideFilter tags and keys as arguments. If there is *at least one* matching side which can see the location then the filter matches, and otherwise it fails to match.
  • [filter_owner]: If present, inline owner_side= is ignored. Restricts stored locations to villages, each of which must belong to any of the matching sides. If no sides match, restricts to unowned villages (and only these).
  • find_in: name of an array or container variable; if present, the location will not match unless it is also found stored in the variable
  • radius: matches if any location within the radius matches this filter (notes)
  • [filter_radius]: a standard location filter; normally the radius extends outwards from matching locations one step at a time without checking any additional information-- however, if this tag is present, the radius will be restricted so that it can only expand outwards in the directions where it passes the given location filter
  • [and]: an extra location filter. Unless a location matches the [and] filter, then it will be excluded. Note: [and],[or],and [not] extra location filters are considered after everything else in the containing filter (except radius, which is considered last in 1.3.8 and greater); they are then processed in the order encountered.
  • [or]: an extra location filter. If a location matches the [or] filter, then it will count as a match regardless of conditions in previous filters or the containing filter.
  • [not]: an extra location filter. If a location matches the [not] filter, then that location will be excluded.
  • [filter_adjacent_location]: a standard location filter; if present the correct number of adjacent locations must match this filter
    • count: a number, range, or comma separated range; default "1-6"
    • adjacent: a comma separated list of directions; default "n,ne,se,s,sw,nw" (see notes)
  • formula: (Version 1.13.5 and later only) a Wesnoth Formula Language formula. Some terrain-specific variables, for example "light" and "castle", can be used in the filter (see list below).
  • lua_function: (Version 1.13.5 and later only) the name of a Lua function in the global environment that takes arguments x, y and returns true if the given location matches the filter. Non-global functions can now be used here by building a dot-separated "path". Note that this is not actually interpreted as Lua code even though it superficially resembles it, so using a Lua keyword in the path will work, for example "my_filter_functions.goto" will correctly use the function which in actual Lua code would need to be referenced as my_filter_functions["goto"].

Notes about Coordinate Usage

When specifying coordinates, the following keys are used:

  • x: the first coordinate
  • y: the second coordinate

While some locations should only be one hex (like the starting position of a unit), others filter over multiple hexes. The following syntax is used to filter over multiple hexes:

Dashes(-) are used to have the location be a range of hexes. There must be values before and after the dash; everything in between these numbers (inclusively) is part of the range.

Commas(,) are used to separate coordinates into a list. The x and y lists are then paired up, with each pair representing one hex or range. E.g. in order to specify multiple locations 1,4 and 2,5, use:

[tag]
    x=1,2
    y=4,5
[/tag]

You should have the same number of commas in each list, and both x and y are always lists. For example, this does not mean the locations (1,4) and (2,4):

[tag]
    x=1,2
    y=4    # bad example, implementation-defined behavior
[/tag]

A pair can have a single value for one coordinate and a range for the other. This matches (1,4) and the entire column from (2,1) downwards:

[tag]
    x=1,    2
    y=4,1-999
[/tag]

Providing only x or only y is valid. This matches the entire columns from (1,1) and (2,1) downwards:

[tag]
    x=1,2
[/tag]

Note: although the ordering of locations in a list generally does not matter, the action [move_unit_fake] takes in a list of hexes, and moves an image onto each of those hexes in order.

Notes about Radius Usage

If you aren't storing any locations successfully, it may be because you put the radius or filters in the wrong place for them to combine correctly.

[have_location]
    terrain=Gg^Vh
    [and]
        x=$x1
        y=$y1
       radius=1
    [/and]
[/have_location]

Note that the use of [and] here causes the radius to have a very different meaning. Normally, all of the criteria besides radius are checked, producing a set of hexes to which the radius is applied. This means, for example, that if you're trying to find "a hex without a unit on it within 5 hexes of (15, 23)", the code:

[have_location]
    x,y=15,23
    radius=5 # oops... this time it won't work as expected
    [not]
        [filter]
        [/filter]
    [/not]
[have_location]

will not work! First, it looks for a hex with x=15, y=23 without a unit on it. Then, it returns that hex and all hexes within 5 of it. If (15, 23) happens to be occupied, then it will return no hexes, because "all hexes within 5 hexes of (no hexes)" is still "no hexes". Instead, put an [and] around the x,y and radius requirements, and it will separately find "(15, 23) and all hexes within 5 of it" and "each of those hexes that doesn't have a unit on it", producing the desired result.

Directions

Some attributes expect a direction or list of directions. Valid base directions are n, ne, nw, s, se, sw, and there are three operators supported as well:

You can't apply multiple rotation operators - for example, "n:cw:ccw" is not a valid direction. If for some reason you really need multiple rotations, you can use parentheses (so, "(n:cw):ccw" is valid and is the same as n). Similarly, "--n" is not valid, but "-(-n)" is valid and is the same as n.

This syntax is mainly useful when used in conjunction with variable substitution in the adjacent key in [filter_adjacent_location] and in [filter_adjacent] (in StandardUnitFilter), but will work anywhere a direction is expected. For example, using [modify_unit] to change a unit's direction:

[modify_unit]
    [filter]
        # ... Whatever filter you need
    [/filter]
    facing=-$this_unit.facing
[/modify_unit]

That will cause the matched units to turn around.

Filtering Terrains

The terrain= key allows you to filter based on the terrain of a space, for example:

[event]
    [filter]
        [filter_location]
            terrain=Ch 
        [/filter_location]
    [/filter]
[/event]

At some places the terrains can be filtered with a match list. This list is a comma separated list of terrain strings and patterns which will be processed in order. As soon as a pattern matching the reference terrain is found, the result of the filter will be determined.

Normally, if one of the patterns matches, the filter is considered successful. However, the special pattern ! inverts this every time it is encountered – when inverted, the filter is considered unsuccessful when one of the patterns matches. In other words, Gg matches only basic grass, while !,Gg matches anything but basic grass.

When the end of the list is reached without any matches, normally the result is an unsuccessful match. However, if the match is currently inverted, ie there are an odd number of !, then the result is a successful match.

An individual terrain pattern consists of two parts, the base and the overlay, separated by the ^ character. The overlay (including the preceding ^) is optional; if omitted, only terrains without overlays can be matched. The pattern may end with the wildcard character * (or be composed solely of the wildcard character). The pattern to match any terrain is *^*.

Example 1:
ww* matches ww, www, wwW but not WWW
!, ww returns false if ww found and true if not
!, ww, wa, !, aa returns false if ww or wa found and true if aa found and false if none found.

Example 2:
*^V* matches all village-terrain
Notice how the * can be used separately for both layers (base and overlay layers are separated by the ^-character).

For a list of terrain types and their string codes see TerrainCodesWML.

Wesnoth Formula Language

When using SLF's formula attribute, the following read-only terrain properties are available:

  • x
  • y
  • loc
  • id
  • name
  • editor_name
  • description
  • icon
  • light
  • village: a boolean containing the value of [terrain_type]gives_income=
  • castle
  • keep
  • healing: an integer containing the value of [terrain_type]heals=
  • owner

For an up-to-date list, check the C++ function terrain_callable::get_value(const std::string& key) const.

Tutorial

See Also