WML Utilities

From The Battle for Wesnoth Wiki
Revision as of 01:07, 15 August 2006 by Prometheus (talk | contribs) (General shortcuts)

General shortcuts

# Shortcut for IF statements testing the value of a variable. You still need to
# write [then] and [else] tags manually, though.
#
# You can use it like this:
#
# {IF some_variable equals yes (
#     [then]
#         # something
#     [/then]
#
#     [else]
#         # something else
#     [/else]
# )}
#define IF VAR OP VAL CONTENTS [if] [variable] name={VAR} {OP}={VAL} [/variable]
{CONTENTS} [/if] #enddef
# Just a variation of the above, testing [have_unit] instead of [variable].
#define IF_HAVE_UNIT FILTER CONTENTS [if] [have_unit] {FILTER} [/have_unit]
{CONTENTS} [/if] #enddef
# Stores an attribute of a unit to the given variable.
#
# Example that flips all orcs to whatever side James is on:
#
# {STORE_UNIT_VAR description=James side side_of_James}
# {MODIFY_UNIT race=orc side $side_of_James}
#define STORE_UNIT_VAR FILTER VAR TO_VAR [store_unit] [filter] {FILTER} [/filter]
kill=no variable=STORE_UNIT_VAR_store [/store_unit]
{VARIABLE_OP {TO_VAR} format $STORE_UNIT_VAR_store.{VAR}}
{CLEAR_VARIABLE STORE_UNIT_VAR_store} #enddef
# This is a way to check whether or not the terrain in the given coordinates
# is of the given type or types. Might be useful, since filtering by terrain
# isn't possible directly.
#
# You can use it for example like this:
#
# [event]
#     name=moveto
#     first_time_only=no
#
#     {IF_TERRAIN $x1 $y1 gfm (
#         [then]
#             {DEBUG_MSG "Stepped on grassland, forest or mountains!"}
#         [/then]
#     )}
# [/event]
#define IF_TERRAIN X Y TYPES CONTENTS [store_locations] x={X} y={Y} terrain={TYPES} variable=IF_TERRAIN_temp [/store_locations]
[if] [variable] name=IF_TERRAIN_temp.length not_equals=0 [/variable]
{CONTENTS} [/if]
{CLEAR_VARIABLE IF_TERRAIN_temp} #enddef
# You can iterate through a range of numbers with this macro. The CONTENTS
# are repeated with every iteration, and you can use the VAR variable to
# insert the number of the current step into each iteration. Note that
# when using this, you must iterate from a smaller number to the bigger
# number, because the increment is always 1.
#
# Example that spawns a row of skeletons into the coordinates (4,5),
# (5,5), (6,5), (7,5), (8,5) and (9,5):
#
# {ITERATE 4 9 i (
#     [unit]
#         type=Skeleton
#         x=$i
#         y=5
#     [/unit]
# )}
#define ITERATE FROM TO VAR CONTENTS {VARIABLE {VAR} {FROM}}
[while] [variable] name={VAR} less_than_equal_to={TO} [/variable]
[do] {CONTENTS}
{VARIABLE_OP {VAR} add 1} [/do] [/while] #enddef

General macros

#define FORMAT ARRAY VARIABLE
{VARIABLE_OP {VARIABLE} to_variable {ARRAY}.{VARIABLE}}
#enddef
##this is a "partial" macro; not all of the tags match up
#put {NEXT INDEX} after it
#define FOREACH_FORMAT ARRAY INDEX
 {FOREACH {ARRAY} {INDEX}}
  {FORMAT {ARRAY}[${INDEX}] x}
  {FORMAT {ARRAY}[${INDEX}] y}
#enddef
#define STORE_UNIT NAME
[store_unit]
 [filter]
 description={NAME}
 [/filter]
variable={NAME}_store
[/store_unit]
#enddef
#define UNSTORE_UNIT NAME X Y
{VARIABLE {NAME}_store.x {X}}
{VARIABLE {NAME}_store.y {Y}}
[unstore_unit]
variable={NAME}_store
[/unstore_unit]
{CLEAR_VARIABLE {NAME}_store}
#enddef
#define UNSTORE_ARRAY ARRAY
{FOREACH {ARRAY} i}
  [unstore_unit]
  variable={ARRAY}[$i]
  [/unstore_unit]
  [clear_variable]
  variable={ARRAY}[$i]
  [/clear_variable]
{NEXT i}
#enddef

More uncommon tasks

Adding unit overlays with a filter instead of (x,y)

# UNIT_OVERLAY adds an overlay to a unit, taking in a standard filter
#
# Example that gives all spearmen a book:
# {UNIT_OVERLAY type=Spearman items/book1.png}

#define UNIT_OVERLAY FILTER IMG
    [store_unit]
        [filter]
            {FILTER}
        [/filter]
        variable=UNIT_OVERLAY_store
        kill=no
    [/store_unit]
    {FOREACH UNIT_OVERLAY_store UNIT_OVERLAY_i}
	{VARIABLE_OP UNIT_OVERLAY_tempx format $UNIT_OVERLAY_store[$UNIT_OVERLAY_i].x}
	{VARIABLE_OP UNIT_OVERLAY_tempy format $UNIT_OVERLAY_store[$UNIT_OVERLAY_i].y}
        [unit_overlay]
            x=$UNIT_OVERLAY_tempx
            y=$UNIT_OVERLAY_tempy
		image={IMG}
        [/unit_overlay]
    {NEXT UNIT_OVERLAY_i}
    {CLEAR_VARIABLE UNIT_OVERLAY_store}
#enddef

Returning a unit to the recall list

# This places a given unit back to the recall list of the side it is on.
# Note however, that the unit is not healed to full health, so when
# recalled (even if not until the next scenario) the unit may have less
# than his maximum hp left.
#
# An example, that returns all units stepping on (20,38) back to the recall
# list:
# 
# [event]
#     name=moveto
#
#     [filter]
#         x,y=20,38
#     [/filter]
#
#     {PUT_TO_RECALL_LIST x,y=20,38}
# [/event]
#define PUT_TO_RECALL_LIST FILTER [store_unit] [filter] {FILTER} [/filter]
variable=temp kill=yes [/store_unit]
{FOREACH temp i} {VARIABLE temp[$i].x "recall"} {VARIABLE temp[$i].y "recall"}
[unstore_unit] variable=temp[$i] find_vacant=no [/unstore_unit] {NEXT i} #enddef

Determining opposite coordinates

# 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 multiply 0.5} {VARIABLE_OP x_odd multiply 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 s_x greater_than $c_x ( [then] {VARIABLE_OP result_x add -1} [/then] )}
{IF s_x less_than $c_x ( [then] {VARIABLE_OP result_x add 1} [/then] )}
{IF s_x equals $c_x ( [then] {IF s_y less_than $c_y ( [then] {VARIABLE_OP result_y add 1} [/then] )}
{IF s_y greater_than $c_y ( [then] {VARIABLE_OP result_y add -1} [/then] )} [/then] )}
{IF x_odd not_equals $s_x ( [then] {IF s_y equals $c_y ( [then] {VARIABLE_OP result_y add 1} [/then] )} [/then]
[else] {IF 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

See Also