Difference between revisions of "WML Utilities"
From The Battle for Wesnoth Wiki
(→More uncommon tasks) |
m (→Determining opposite coordinates: Suggest using SLF's direction support instead) |
||
| (19 intermediate revisions by 8 users not shown) | |||
| Line 1: | Line 1: | ||
| − | == | + | == Determining opposite coordinates == |
| − | + | '''Obsolete?''' the Standard Location Filter now supports [[StandardLocationFilter#Directions|directions]], which might be able to replace any uses of this utility. | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
# Using this, you can determine the coordinates on the "opposite side" of a | # Using this, you can determine the coordinates on the "opposite side" of a | ||
| Line 268: | Line 20: | ||
#define OPPOSITE_SIDE CENTER_X CENTER_Y X Y VAR | #define OPPOSITE_SIDE CENTER_X CENTER_Y X Y VAR | ||
{VARIABLE x_odd {X}}<br> | {VARIABLE x_odd {X}}<br> | ||
| − | {VARIABLE_OP x_odd | + | {VARIABLE_OP x_odd modulo 2}<br> |
| − | |||
{VARIABLE c_x {CENTER_X}} | {VARIABLE c_x {CENTER_X}} | ||
{VARIABLE c_y {CENTER_Y}} | {VARIABLE c_y {CENTER_Y}} | ||
| Line 276: | Line 27: | ||
{VARIABLE result_x {CENTER_X}} | {VARIABLE result_x {CENTER_X}} | ||
{VARIABLE result_y {CENTER_Y}}<br> | {VARIABLE result_y {CENTER_Y}}<br> | ||
| − | { | + | {IF_VAR s_x greater_than $c_x ( |
[then] | [then] | ||
{VARIABLE_OP result_x add -1} | {VARIABLE_OP result_x add -1} | ||
[/then] | [/then] | ||
)}<br> | )}<br> | ||
| − | { | + | {IF_VAR s_x less_than $c_x ( |
[then] | [then] | ||
{VARIABLE_OP result_x add 1} | {VARIABLE_OP result_x add 1} | ||
[/then] | [/then] | ||
)}<br> | )}<br> | ||
| − | { | + | {IF_VAR s_x equals $c_x ( |
[then] | [then] | ||
| − | { | + | {IF_VAR s_y less_than $c_y ( |
[then] | [then] | ||
{VARIABLE_OP result_y add 1} | {VARIABLE_OP result_y add 1} | ||
[/then] | [/then] | ||
)}<br> | )}<br> | ||
| − | { | + | {IF_VAR s_y greater_than $c_y ( |
[then] | [then] | ||
{VARIABLE_OP result_y add -1} | {VARIABLE_OP result_y add -1} | ||
| Line 300: | Line 51: | ||
[/then] | [/then] | ||
)}<br> | )}<br> | ||
| − | { | + | {IF_VAR x_odd equals 1 ( |
[then] | [then] | ||
| − | { | + | {IF_VAR s_y equals $c_y ( |
[then] | [then] | ||
{VARIABLE_OP result_y add 1} | {VARIABLE_OP result_y add 1} | ||
| Line 309: | Line 60: | ||
[/then]<br> | [/then]<br> | ||
[else] | [else] | ||
| − | { | + | {IF_VAR s_y equals $c_y ( |
[then] | [then] | ||
{VARIABLE_OP result_y add -1} | {VARIABLE_OP result_y add -1} | ||
| Line 315: | Line 66: | ||
)} | )} | ||
[/else] | [/else] | ||
| − | )} | + | )} |
{VARIABLE {VAR}.x $result_x} | {VARIABLE {VAR}.x $result_x} | ||
{VARIABLE {VAR}.y $result_y}<br> | {VARIABLE {VAR}.y $result_y}<br> | ||
| Line 325: | Line 76: | ||
{CLEAR_VARIABLE result_y} | {CLEAR_VARIABLE result_y} | ||
{CLEAR_VARIABLE x_odd} | {CLEAR_VARIABLE x_odd} | ||
| + | #enddef | ||
| + | |||
| + | == Find nearest hex(es) == | ||
| + | |||
| + | #define FIND_NEARBY FILTER X Y LIMIT | ||
| + | # Does a search for a nearby location that matches the given filter. | ||
| + | # Basically just looks for such a location with increasing radius until it | ||
| + | # finds at least one. This is sadly inefficient, but implementing BFS in | ||
| + | # WML is... difficult. Once LIMIT is reached, the entire map is searched. | ||
| + | # This macro creates the 'nearby_locations' and 'nearby_distance' | ||
| + | # variables, which can be used to access a list of locations found and the | ||
| + | # distance to those locations, respectively. They should eventually be | ||
| + | # cleared, which can be accomplished using the CLEANUP_SEARCH macro. | ||
| + | [clear_variable] | ||
| + | name=nearby_locations | ||
| + | [/clear_variable] | ||
| + | [set_variable] | ||
| + | name=nearby_distance | ||
| + | value=0 | ||
| + | [/set_variable] | ||
| + | [while] | ||
| + | [not] | ||
| + | [variable] | ||
| + | name=nearby_locations.length | ||
| + | greater_than=0 | ||
| + | [/variable] | ||
| + | [/not] | ||
| + | [and] | ||
| + | [variable] | ||
| + | name=nearby_distance | ||
| + | less_than={LIMIT} | ||
| + | [/variable] | ||
| + | [/and] | ||
| + | [do] | ||
| + | {DEBUG "Searching depth $nearby_distance around ({X}, {Y})..."} | ||
| + | [store_locations] | ||
| + | variable=nearby_locations | ||
| + | {FILTER} | ||
| + | [and] | ||
| + | x,y={X},{Y} | ||
| + | radius=$nearby_distance | ||
| + | [/and] | ||
| + | [/store_locations] | ||
| + | {DEBUG "...found $nearby_locations.length locations."} | ||
| + | [set_variable] | ||
| + | name=nearby_distance | ||
| + | add=1 | ||
| + | [/set_variable] | ||
| + | [/do] | ||
| + | [/while] | ||
| + | [if] | ||
| + | [variable] | ||
| + | name=nearby_locations.length | ||
| + | equals=0 | ||
| + | [/variable] | ||
| + | [then] | ||
| + | [store_locations] | ||
| + | variable=nearby_locations | ||
| + | {FILTER} | ||
| + | [/store_locations] | ||
| + | [/then] | ||
| + | [/if] | ||
| + | #enddef | ||
| + | |||
| + | #define CLEANUP_SEARCH | ||
| + | # Clears variables involved in searching (the FIND_NEARBY macro). Put this | ||
| + | # in your name=victory,defeat tag to clean up if you use FIND_NEARBY within | ||
| + | # a scenario. | ||
| + | [clear_variable] | ||
| + | name=nearby_locations, nearby_distance | ||
| + | [/clear_variable] | ||
#enddef | #enddef | ||
| Line 330: | Line 152: | ||
* [[UsefulWMLFragments]] | * [[UsefulWMLFragments]] | ||
| + | * [[ReferenceWML]] | ||
| + | |||
| + | [[Category: UsefulWMLFragments]] | ||
Latest revision as of 21:20, 2 July 2019
Determining opposite coordinates
Obsolete? the Standard Location Filter now supports directions, which might be able to replace any uses of this utility.
# Using this, you can determine the coordinates on the "opposite side" of a
# central hex, relative to another hex adjacent to it. What this really means
# is illustrated below:
# __ __ __
# __/ \__ __/2 \__ __/ \__
# / \__/1 \ / \__/ \ /2 \__/ \ C: central point
# \__/C \__/ \__/C \__/ \__/C \__/ 1: the hex to "mirror"
# /2 \__/ \ / \__/ \ / \__/1 \ 2: the result
# \__/ \__/ \__/1 \__/ \__/ \__/
# \__/ \__/ \__/
#
# The coordinates of the central point are given in {CENTER_X} and {CENTER_Y},
# and the coordinates of hex 1 in {X} and {Y}. The coordinates of hex 2 are
# then stored in {VAR}, which will have member variables x and y.
#
# Note that this uses the IF macro given earlier on this page.
#define OPPOSITE_SIDE CENTER_X CENTER_Y X Y VAR
{VARIABLE x_odd {X}}
{VARIABLE_OP x_odd modulo 2}
{VARIABLE c_x {CENTER_X}}
{VARIABLE c_y {CENTER_Y}}
{VARIABLE s_x {X}}
{VARIABLE s_y {Y}}
{VARIABLE result_x {CENTER_X}}
{VARIABLE result_y {CENTER_Y}}
{IF_VAR s_x greater_than $c_x (
[then]
{VARIABLE_OP result_x add -1}
[/then]
)}
{IF_VAR s_x less_than $c_x (
[then]
{VARIABLE_OP result_x add 1}
[/then]
)}
{IF_VAR s_x equals $c_x (
[then]
{IF_VAR s_y less_than $c_y (
[then]
{VARIABLE_OP result_y add 1}
[/then]
)}
{IF_VAR s_y greater_than $c_y (
[then]
{VARIABLE_OP result_y add -1}
[/then]
)}
[/then]
)}
{IF_VAR x_odd equals 1 (
[then]
{IF_VAR s_y equals $c_y (
[then]
{VARIABLE_OP result_y add 1}
[/then]
)}
[/then]
[else]
{IF_VAR s_y equals $c_y (
[then]
{VARIABLE_OP result_y add -1}
[/then]
)}
[/else]
)}
{VARIABLE {VAR}.x $result_x}
{VARIABLE {VAR}.y $result_y}
{CLEAR_VARIABLE c_x}
{CLEAR_VARIABLE c_y}
{CLEAR_VARIABLE s_x}
{CLEAR_VARIABLE s_y}
{CLEAR_VARIABLE result_x}
{CLEAR_VARIABLE result_y}
{CLEAR_VARIABLE x_odd}
#enddef
Find nearest hex(es)
#define FIND_NEARBY FILTER X Y LIMIT
# Does a search for a nearby location that matches the given filter.
# Basically just looks for such a location with increasing radius until it
# finds at least one. This is sadly inefficient, but implementing BFS in
# WML is... difficult. Once LIMIT is reached, the entire map is searched.
# This macro creates the 'nearby_locations' and 'nearby_distance'
# variables, which can be used to access a list of locations found and the
# distance to those locations, respectively. They should eventually be
# cleared, which can be accomplished using the CLEANUP_SEARCH macro.
[clear_variable]
name=nearby_locations
[/clear_variable]
[set_variable]
name=nearby_distance
value=0
[/set_variable]
[while]
[not]
[variable]
name=nearby_locations.length
greater_than=0
[/variable]
[/not]
[and]
[variable]
name=nearby_distance
less_than={LIMIT}
[/variable]
[/and]
[do]
{DEBUG "Searching depth $nearby_distance around ({X}, {Y})..."}
[store_locations]
variable=nearby_locations
{FILTER}
[and]
x,y={X},{Y}
radius=$nearby_distance
[/and]
[/store_locations]
{DEBUG "...found $nearby_locations.length locations."}
[set_variable]
name=nearby_distance
add=1
[/set_variable]
[/do]
[/while]
[if]
[variable]
name=nearby_locations.length
equals=0
[/variable]
[then]
[store_locations]
variable=nearby_locations
{FILTER}
[/store_locations]
[/then]
[/if]
#enddef
#define CLEANUP_SEARCH
# Clears variables involved in searching (the FIND_NEARBY macro). Put this
# in your name=victory,defeat tag to clean up if you use FIND_NEARBY within
# a scenario.
[clear_variable]
name=nearby_locations, nearby_distance
[/clear_variable]
#enddef
See Also
This page was last edited on 2 July 2019, at 21:20.