# This file contains general utility macros for WML authors. # # Also see #### TABLE OF CONTENTS #### # variable operations # RANDOM # VARIABLE # VARIABLE_OP # CLEAR_VARIABLE # FOREACH # NEXT # IF_TERRAIN # DEBUG_MSG # scenario/campaign setup # DEFAULT_MUSIC_PLAYLIST # SCENARIO_MUSIC # STARTING_VILLAGES # DOT # CROSS # MENU_IMG_TXT # MENU_IMG_TXT2 # side setup # TURNS # GOLD # INCOME # ATTACK_DEPTH # NO_SCOUTS # in-scenario actions # PLACE_IMAGE # TREMOR # IS_HERO # UNIT # UNDEAD_UNIT # CREATE_UNIT # MOVE_UNIT # MODIFY_UNIT # STORE_UNIT_VAR # PUT_TO_RECALL_LIST # utilities not intended for general use # QUANTITY # MAGENTA_IS_THE_TEAM_COLOR # COLOR_HEAL # COLOR_HARM # COLOR_WHITE #### END OF TABLE OF CONTENTS #### #macro to define a 'quantity' differently based on difficulty levels #define QUANTITY ATTRIBUTE ON_EASY ON_NORMAL ON_HARD #ifdef EASY {ATTRIBUTE}={ON_EASY} #endif #ifdef NORMAL {ATTRIBUTE}={ON_NORMAL} #endif #ifdef HARD {ATTRIBUTE}={ON_HARD} #endif #enddef #macro to define number of turns for different difficulty levels #define TURNS ON_EASY ON_NORMAL ON_HARD {QUANTITY turns {ON_EASY} {ON_NORMAL} {ON_HARD}} #enddef #macro which will let you go {GOLD x y z} to set #the gold depending on easy/medium/hard - x/y/z #define GOLD ON_EASY ON_NORMAL ON_HARD {QUANTITY gold {ON_EASY} {ON_NORMAL} {ON_HARD}} #enddef #define INCOME ON_EASY ON_NORMAL ON_HARD {QUANTITY income {ON_EASY} {ON_NORMAL} {ON_HARD}} #enddef #macro to define AI attack depth for different difficulty levels (set it to 1-6) #define ATTACK_DEPTH ON_EASY ON_NORMAL ON_HARD {QUANTITY attack_depth {ON_EASY} {ON_NORMAL} {ON_HARD}} #enddef #macro to make an AI team not recruit scouts #define NO_SCOUTS villages_per_scout=0 #enddef #macro to add a hero icon to the unit #define IS_HERO overlays="misc/hero-icon.png" #enddef #define DOT X Y [image] x,y={X},{Y} file=misc/dot.png delay=500 [/image] #enddef #define CROSS X Y [image] x,y={X},{Y} file=misc/cross.png delay=500 [/image] #enddef #macro to quickly pick a random value (in the $random variable, to avoid #cluterring up savegames with such temporary variables) #define RANDOM RANGE [set_variable] name=random random={RANGE} [/set_variable] #enddef #macro to initialize a variable #define VARIABLE VAR VALUE [set_variable] name={VAR} value={VALUE} [/set_variable] #enddef #macro to do mathematical operations on variables #define VARIABLE_OP VAR OP ARG [set_variable] name={VAR} {OP}={ARG} [/set_variable] #enddef #define CLEAR_VARIABLE VAR [clear_variable] name={VAR} [/clear_variable] #enddef #macro to iterate over an array #define FOREACH ARRAY VAR {VARIABLE {VAR} 0} [while] [variable] name={VAR} less_than=${ARRAY}.length [/variable] [do] #enddef #define NEXT VAR [set_variable] name={VAR} add=1 [/set_variable] [/do] [/while] {CLEAR_VARIABLE {VAR}} #enddef #define DEBUG_MSG MSG [message] speaker=narrator message={MSG} [/message] #enddef # MODIFY_UNIT alters a unit variable (such as unit.x, unit.type, # unit.side), handling all the storing and unstoring. # # Example that flips all spearmen to side 2: # {MODIFY_UNIT type=Spearman side 2} #define MODIFY_UNIT FILTER VAR VALUE [store_unit] [filter] {FILTER} [/filter] variable=MODIFY_UNIT_store kill=yes [/store_unit] {FOREACH MODIFY_UNIT_store MODIFY_UNIT_i} [set_variable] name=MODIFY_UNIT_store[$MODIFY_UNIT_i].{VAR} value={VALUE} [/set_variable] [unstore_unit] variable=MODIFY_UNIT_store[$MODIFY_UNIT_i] find_vacant=no [/unstore_unit] {NEXT MODIFY_UNIT_i} {CLEAR_VARIABLE MODIFY_UNIT_store} #enddef # Stores an attribute of a unit to the given variable. # # Example where this is used to flip 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 # Creates a unit of TYPE belonging to SIDE at X,Y. UNIT_ID can be used # when filtering on it. For example, let's create a wose for player 1 # at 4,7 # # {CREATE_UNIT 1 "Wose" 4 7 () ()} # # As a second example, let's make it a female wose which can recruit and # is name "Woselina": # # {CREATE_UNIT 1 "Wose" 4 7 "Woselina" ( # canrecruit=1 # )} #define CREATE_UNIT SIDE TYPE X Y UNIT_ID OTHER [unit] side={SIDE} type={TYPE} x={X} y={Y} description={UNIT_ID} upkeep=full animate=yes {OTHER} [/unit] #enddef # Moves a unit from its current location to the given location along a # relatively straight line displaying the movement just like [move_unit_fake] # does. # # Note that setting the destination on an existing unit does not kill either # one, but causes the unit to move to the nearest vacant hex instead. #define MOVE_UNIT FILTER TO_X TO_Y [store_unit] [filter] {FILTER} [/filter] variable=MOVE_UNIT_temp kill=no [/store_unit] [scroll_to] x=$MOVE_UNIT_temp.x y=$MOVE_UNIT_temp.y [/scroll_to] [hide_unit] x=$MOVE_UNIT_temp.x y=$MOVE_UNIT_temp.y [/hide_unit] {VARIABLE_OP x_coords format ("$MOVE_UNIT_temp.x|,{TO_X}")} {VARIABLE_OP y_coords format ("$MOVE_UNIT_temp.y|,{TO_Y}")} [move_unit_fake] type=$MOVE_UNIT_temp.type x=$x_coords y=$y_coords [/move_unit_fake] [teleport] [filter] {FILTER} [/filter] x,y={TO_X},{TO_Y} [/teleport] [unhide_unit][/unhide_unit] [redraw][/redraw] #enddef # 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=PUT_TO_RECALL_LIST_temp kill=yes [/store_unit] {FOREACH PUT_TO_RECALL_LIST_temp i} {VARIABLE PUT_TO_RECALL_LIST_temp[$i].x "recall"} {VARIABLE PUT_TO_RECALL_LIST_temp[$i].y "recall"} [unstore_unit] variable=PUT_TO_RECALL_LIST_temp[$i] find_vacant=no [/unstore_unit] {NEXT i} #enddef #macro to make a side start a scenario with villages #define STARTING_VILLAGES SIDE RADIUS [event] name=prestart [store_starting_location] side={SIDE} variable=temp_starting_location [/store_starting_location] [store_locations] x,y=$temp_starting_location.x,$temp_starting_location.y radius={RADIUS} variable=temp_starting_locs #all the types of villages terrain=Vhha, Vhh, Vda, Vhm, Vu, Vea, Vht, Vud, Veg, Vdt, Vhg, Vha, Vwm, Vs [/store_locations] {FOREACH temp_starting_locs i} {VARIABLE_OP temp_x_var to_variable temp_starting_locs[$i].x} {VARIABLE_OP temp_y_var to_variable temp_starting_locs[$i].y} [capture_village] side={SIDE} x,y=$temp_x_var,$temp_y_var [/capture_village] {NEXT i} {CLEAR_VARIABLE temp_x_var} {CLEAR_VARIABLE temp_y_var} {CLEAR_VARIABLE temp_starting_location} {CLEAR_VARIABLE temp_starting_locs} {CLEAR_VARIABLE i} [/event] #enddef #define MENU_IMG_TXT IMG TXT "&"+{IMG}+"="+{TXT}#enddef #define MENU_IMG_TXT2 IMG TXT1 TXT2 "&"+{IMG}+"="+{TXT1}+"="+{TXT2}#enddef # #USAGE {UNIT (Elvish Fighter) (Myname) ( _ "Myname") 1 1 1} # #define UNIT TYPE DESCRIPTION UDESCRIPTION SIDE X Y [unit] type={TYPE} description={DESCRIPTION} user_description={UDESCRIPTION} side={SIDE} x={X} y={Y} [modifications] {TRAIT_LOYAL} [/modifications] [/unit] #enddef #define UNDEAD_UNIT TYPE SIDE X Y [unit] type={TYPE} side={SIDE} x={X} y={Y} [modifications] {TRAIT_UNDEAD} {TRAIT_LOYAL} [/modifications] [/unit] #enddef #define PLACE_IMAGE IMAGE_FILE X Y [item] x={X} y={Y} image={IMAGE_FILE} [/item] #enddef #define TREMOR [sound] name="rumble.ogg" [/sound] [scroll] x=5 y=0 [/scroll] [scroll] x=-10 y=0 [/scroll] [scroll] x=5 y=5 [/scroll] [scroll] x=0 y=-10 [/scroll] [scroll] x=0 y=5 [/scroll] #enddef # a macro to define a common set of magenta color values which different # units can be color shifted by using the team color system #define MAGENTA_IS_THE_TEAM_COLOR flag_rgb=magenta #enddef # Music macros. As of 1.1.3, music is parsed as follows: # 1. the [scenario]-level [music] tag # 2. the [story]-level music key # 3. any [event]-level [music] tags # # If you change the music at a lower level, the tags above it will NOT be re-parsed # and your scenario will sound wrong. For example, if you set scenario music # with the normal [scenario]-level music tag but change the music during the [story], # it is never reset back to normal. Therefore, these macros are intended to catch # instances like that. Of course, if you want something more elaborate, code it # manually. # A macro to define a standard playlist suitable for any level. The music is defined # twice to catch instances where music is changed in a story and not set back. #define DEFAULT_MUSIC_PLAYLIST [music] name=gameplay01.ogg ms_before=12000 [/music] [music] name=gameplay02.ogg ms_before=12000 append=yes [/music] [music] name=gameplay03.ogg ms_before=12000 append=yes [/music] [music] name=main_menu.ogg ms_before=12000 append=yes [/music] [music] name=wesnoth-1.ogg ms_before=12000 append=yes [/music] [music] name=wesnoth-2.ogg ms_before=12000 append=yes [/music] [event] name=prestart [music] name=gameplay01.ogg ms_before=12000 [/music] [music] name=gameplay02.ogg ms_before=12000 append=yes [/music] [music] name=gameplay03.ogg ms_before=12000 append=yes [/music] [music] name=main_menu.ogg ms_before=12000 append=yes [/music] [music] name=wesnoth-1.ogg ms_before=12000 append=yes [/music] [music] name=wesnoth-2.ogg ms_before=12000 append=yes [/music] [/event] #enddef # # This music macro ensures that the correct music is selected # for a scenario just in case it is changed by [story]. # It should be positioned at the top of the scenario file # so it can be overridden by other prestart or start events. # # It also allows for the convenient use of a standardized # intra-scenario music, should we decide to use one. # #define SCENARIO_MUSIC MUSIC [music] name="wesnoth-2.ogg" [/music] [event] name=prestart [music] name={MUSIC} [/music] [/event] #enddef #define COLOR_HEAL green=255 #enddef #define COLOR_HARM red=255 #enddef #define COLOR_WHITE red=255 green=255 blue=255 #enddef