FloodWML

From The Battle for Wesnoth Wiki
Revision as of 21:47, 20 August 2011 by Lipk (talk | contribs)

Usage

You can find sources at the bottom of the page. It's too long to include it here.

To create a flood:

{CREATE_FLOOD "1,1;2,3" "ne,n" "Gg>Ww;Gs>Wwt" awesome_flood}

Where "1,1;2,3" is a semicolon separated list of coordinate pairs where the flood starts from, "ne,n" is a comma separated list of directions in which the flood will spread, "Gg>Ww;Gs>Wwt" is a semicolon separated list of transformations where a>b means that the hexes with the terrain code a will be converted to b, and finally awesome_flood is the variable to store the current state of the flood in (but you might better think about it as the flood's id).

To spread a flood by one hex:

{SPREAD_FLOOD awesome_flood}

Where awesome_flood is the flood's id :)

To modify a flood's data:

{SET_FLOOD_DIRECTIONS "se,s" awesome_flood}
{SET_FLOOD_TERRAIN_TABLE "Gg>Wwg;Gs>Ww" awesome_flood}
{SET_FLOOD_SOURCE "3,3;5,4;6,6" awesome_flood}

One note: all of these macros replace current data in awesome_flood, so old information is lost. This is especially important for SET_FLOOD_SOURCE because that alters the list of hexes which are currently form the first wave of the flood. So if you call it, the original flood will stop and a new one will start from "3,3;5,4;6,6" or whatever you specify.

Source Code

#define INVERT_DIRECTIONS DIRECTIONS OUT_VAR
	#a macro to change directions to their opposites (n->s, sw->ne, etc)
	#DIRECTIONS is a comma-separated list of directions
	#OUT_VAR is the variable to write the output in. Output is an array
	#which contains the inverted directions in the order they were given
	#in DIRECTIONS. The values are stores in the 'direction' key.

[set_variables]
	name={OUT_VAR}
	[split]
		list={DIRECTIONS}
		separator=","
		key=direction
		remove_empty=yes
	[/split]
[/set_variables]

{FOREACH {OUT_VAR} TMP_ID_i}
	[if]
		[variable]
			name={OUT_VAR}[$TMP_ID_i].direction
			equals="n"
		[/variable]
		[then]
			[set_variable]
				name={OUT_VAR}[$TMP_ID_i].direction
				value="s"
			[/set_variable]
		[/then]
	[else]
	[if]
		[variable]
			name={OUT_VAR}[$TMP_ID_i].direction
			equals="s"
		[/variable]
		[then]
			[set_variable]
				name={OUT_VAR}[$TMP_ID_i].direction
				value="n"
			[/set_variable]
		[/then]
	[else]
	[if]
		[variable]
			name={OUT_VAR}[$TMP_ID_i].direction
			equals="se"
		[/variable]
		[then]
			[set_variable]
				name={OUT_VAR}[$TMP_ID_i].direction
				value="nw"
			[/set_variable]
		[/then]
	[else]
	[if]
		[variable]
			name={OUT_VAR}[$TMP_ID_i].direction
			equals="nw"
		[/variable]
		[then]
			[set_variable]
				name={OUT_VAR}[$TMP_ID_i].direction
				value="se"
			[/set_variable]
		[/then]
	[else]
	[if]
		[variable]
			name={OUT_VAR}[$TMP_ID_i].direction
			equals="ne"
		[/variable]
		[then]
			[set_variable]
				name={OUT_VAR}[$TMP_ID_i].direction
				value="sw"
			[/set_variable]
		[/then]
	[else]
	[if]
		[variable]
			name={OUT_VAR}[$TMP_ID_i].direction
			equals="sw"
		[/variable]
		[then]
			[set_variable]
				name={OUT_VAR}[$TMP_ID_i].direction
				value="ne"
			[/set_variable]
		[/then]
	[/if]
	[/else]
	[/if]
	[/else]
	[/if]
	[/else]
	[/if]
	[/else]
	[/if]
	[/else]
	[/if]
{NEXT TMP_ID_i}

#enddef

#define STORE_FLOODABLE_LOCATIONS SOURCE_X SOURCE_Y DIRECTIONS TERRAINS OUT_VAR
	#stores hexes of type TERRAINS whose neighbour in one of DIRECTIONS directions is one of SOURCE_X ; SOURCE_Y
	#SOURCE_X & SOURCE_Y comma-separated list of coordinates
	#DIRECTIONS an array of directions, values stored in the 'direction' key (same as the output format of INVERT_DIRECTIONS)
	#TERRAINS comma-separated list of terrain codes
	#OUT_VAR the variable to write the output in
	#
	#NOTE: this macro is in fact used to store the hexes of type TERRAINS which are neighbours of SOURCE_X ; SOURCE_Y in
	#certain directions, but we achieve that by inverting those directions outside of this macro. See INVERT_DIRECTIONS.

[store_locations]
	variable={OUT_VAR}

	terrain={TERRAINS}

	[filter_adjacent_location]
		adjacent=${DIRECTIONS}[0].direction
		x={SOURCE_X}
		y={SOURCE_Y}
	[/filter_adjacent_location]
	[or]
	terrain={TERRAINS}
		
	[filter_adjacent_location]
		adjacent=${DIRECTIONS}[1].direction
		x={SOURCE_X}
		y={SOURCE_Y}
	[/filter_adjacent_location]
	[or]
	terrain={TERRAINS}
		
	[filter_adjacent_location]
		adjacent=${DIRECTIONS}[2].direction
		x={SOURCE_X}
		y={SOURCE_Y}
	[/filter_adjacent_location]
	[or]
	terrain={TERRAINS}
		
	[filter_adjacent_location]
		adjacent=${DIRECTIONS}[3].direction
		x={SOURCE_X}
		y={SOURCE_Y}
	[/filter_adjacent_location]
	[or]
	terrain={TERRAINS}
		
	[filter_adjacent_location]
		adjacent=${DIRECTIONS}[4].direction
		x={SOURCE_X}
		y={SOURCE_Y}
	[/filter_adjacent_location]
	[or]
	terrain={TERRAINS}
		
	[filter_adjacent_location]
		adjacent=${DIRECTIONS}[5].direction
		x={SOURCE_X}
		y={SOURCE_Y}
	[/filter_adjacent_location]
	[/or]
	[/or]
	[/or]
	[/or]
	[/or]

[/store_locations]
#enddef


#define SPLIT_PAIRS PAIRS SEP1 SEP2 OUT_VAR
[set_variables]
	name=TMP_pairs
	[split]
		list={PAIRS}
		key=pair
		separator={SEP1}
		remove_empty=true
	[/split]
[/set_variables]

{FOREACH TMP_pairs TMP_SP_i}
	[set_variables]
		name=TMP_splitted
		[split]
			list=$TMP_pairs[$TMP_SP_i].pair
			separator={SEP2}
			key=value
		[/split]
	[/set_variables]

	[set_variable]
		name={OUT_VAR}[$TMP_SP_i].value1
		value=$TMP_splitted[0].value
	[/set_variable]
	[set_variable]
		name={OUT_VAR}[$TMP_SP_i].value2
		value=$TMP_splitted[1].value
	[/set_variable]
{NEXT TMP_SP_i}

{CLEAR_VARIABLE TMP_pairs}
{CLEAR_VARIABLE TMP_splitted}
#enddef

#define FLOOD_SINGLE_HEX X Y TERRAIN_TABLE
[store_locations]
	variable=TMP_current_hex
	x={X}
	y={Y}
[/store_locations]

{FOREACH {TERRAIN_TABLE} FSH_i}
	[if]
		[variable]
			name=TMP_current_hex.terrain
			equals=${TERRAIN_TABLE}[$FSH_i].value1
		[/variable]
		[then]
			{MODIFY_TERRAIN ${TERRAIN_TABLE}[$FSH_i].value2 {X} {Y}}
			[set_variable]
				name=FSH_i
				value=${TERRAIN_TABLE}.length
			[/set_variable]
		[/then]
	[/if]
{NEXT FSH_i}


{CLEAR_VARIABLE TMP_current_hex}
#enddef

#define SET_FLOOD_TERRAIN_TABLE TERRAIN_TABLE DATA_VAR
{SPLIT_PAIRS {TERRAIN_TABLE} ";" ">" {DATA_VAR}.terrain_table}
[set_variable]
	name={DATA_VAR}.floodable_terrains
	[join]
		variable={DATA_VAR}.terrain_table
		separator=","
		key=value1
	[/join]
[/set_variable]
#enddef

#define SET_FLOOD_DIRECTIONS DIRECTIONS DATA_VAR
{INVERT_DIRECTIONS {DIRECTIONS} {DATA_VAR}.directions}
#enddef

#define SET_FLOOD_SOURCE SOURCE DATA_VAR
{SPLIT_PAIRS {SOURCE} ";" "," TMP_source_coordinates}
[set_variable]
	name={DATA_VAR}.fields_x
	[join]
		variable=TMP_source_coordinates
		key=value1
		separator=","
	[/join]
[/set_variable]
[set_variable]
	name={DATA_VAR}.fields_y
	[join]
		variable=TMP_source_coordinates
		key=value2
		separator=","
	[/join]
[/set_variable]
#enddef

#define CREATE_FLOOD SOURCE DIRECTIONS TERRAIN_TABLE DATA_VAR
[clear_variable]
	name={DATA_VAR}
[/clear_variable]

{SET_FLOOD_SOURCE {SOURCE} {DATA_VAR}}
{SET_FLOOD_TERRAIN_TABLE {TERRAIN_TABLE} {DATA_VAR}}
{SET_FLOOD_DIRECTIONS {DIRECTIONS} {DATA_VAR}}
#enddef

#define SPREAD_FLOOD DATA_VAR
{STORE_FLOODABLE_LOCATIONS ${DATA_VAR}.fields_x ${DATA_VAR}.fields_y {DATA_VAR}.directions ${DATA_VAR}.floodable_terrains TMP_floodable}

{FOREACH TMP_floodable TMP_SF_i}
	{FLOOD_SINGLE_HEX $TMP_floodable[$TMP_SF_i].x $TMP_floodable[$TMP_SF_i].y {DATA_VAR}.terrain_table}
{NEXT TMP_SF_i}
[redraw][/redraw]

[set_variable]
	name={DATA_VAR}.fields_x
	[join]
		variable=TMP_floodable
		key=x
		separator=","
	[/join]
[/set_variable]
[set_variable]
	name={DATA_VAR}.fields_y
	[join]
		variable=TMP_floodable
		key=y
		separator=","
	[/join]
[/set_variable]
#enddef