Foreach location in each position of an array.

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
BajMic
Posts: 42
Joined: January 24th, 2023, 1:22 am

Foreach location in each position of an array.

Post by BajMic »

Hello, I need some help with multiple locations inside one variable in an array. I.e., in the following code, only the first set of coordinates x,y gives me result of spawning only one scarecrow in the first position. I tried to check the variables with messages, but it blanks out.

Namely - I created an array, in which each element is a set of coordinates for multiple hexes. Next, I store it as a location with find_in=array, where i is the turn number. Last, I am looping through all the hexes in the location to spawn an item on each. Alas, only the first hex in the loop gets the item.

What am I doing wrong? Please help.

Code: Select all

		[set_variables]
			name=sw_spots
			[value]
				x=2
				y=31
			[/value]
			[value]
				x=5
				y=30
			[/value]
			[value]
				x=1,7
				y=32,27
			[/value]
			[value]
				x=4,11
				y=29,26
			[/value]
			[value]
				x=1,5,6,13
				y=30,33,26,27
			[/value]
			[value]
				x=4,5,10,13
				y=29,30,25,27
			[/value]
			[value]
				x=1,4,6,7,12,13
				y=30,32,26,27,25,27
			[/value]
			[value]
				x=4,5,10,11,12,13
				y=29,30,25,26,25,27
			[/value]
			[value]
				x=6,7,11,12,12,13
				y=26,27,26,26,25,27
			[/value]
			[value]
				x=9,10,11,12,12,13
				y=25,25,26,26,25,27
			[/value]
		[/set_variables]
	[/event]

	[event]
		name=southwest_advances
		first_time_only=no
		{VARIABLE sw_turn $turn_number}
		{VARIABLE_OP sw_turn sub ($sw_takeoff)}
		[remove_item]
			x=$sw_spots_current.x
			y=$sw_spots_current.y
		[/remove_item]
		[store_locations]
			variable=sw_spots_current
			find_in=sw_spots[$sw_turn]
		[/store_locations]
		[if]
			[variable]
				name=sw_turn
				greater_than_equal_to=0
			[/variable]
			[then]
				[foreach]
					array=sw_spots_current
					variable=sw_spot
					[do]
						[item]
							x=$sw_spot.x
							y=$sw_spot.y
							image=items/blue-scarecrow.png
						[/item]
					[/do]
				[/foreach]
			[/then]
		[/if]
	[/event]
User avatar
Ravana
Forum Moderator
Posts: 2949
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Foreach location in each position of an array.

Post by Ravana »

> I tried to check the variables with messages, but it blanks out.
That suggests the data you have is not in the format you expect it to have. You could add [inspect][/inspect] after each data manipulation operation.

> x=$sw_spots_current.x
I dont think this does what you expect it to do.
User avatar
Ravana
Forum Moderator
Posts: 2949
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Foreach location in each position of an array.

Post by Ravana »

After simplifying code so that it can be applied without knowing external content

Code: Select all

# lua wesnoth.require("wml-utils").handle_event_commands(wml.load("~add-ons/EventLoader/action.cfg"))
		[set_variables]
			name=sw_spots
			[value]
				x=2
				y=31
			[/value]
			[value]
				x=5
				y=30
			[/value]
			[value]
				x=1,7
				y=32,27
			[/value]
			[value]
				x=4,11
				y=29,26
			[/value]
			[value]
				x=1,5,6,13
				y=30,33,26,27
			[/value]
			[value]
				x=4,5,10,13
				y=29,30,25,27
			[/value]
			[value]
				x=1,4,6,7,12,13
				y=30,32,26,27,25,27
			[/value]
			[value]
				x=4,5,10,11,12,13
				y=29,30,25,26,25,27
			[/value]
			[value]
				x=6,7,11,12,12,13
				y=26,27,26,26,25,27
			[/value]
			[value]
				x=9,10,11,12,12,13
				y=25,25,26,26,25,27
			[/value]
		[/set_variables]

		[store_locations]
			variable=sw_spots_current
			x=$sw_spots[$turn_number].x
			y=$sw_spots[$turn_number].y
		[/store_locations]
		[if]
			[variable]
				name=turn_number
				greater_than_equal_to=0
			[/variable]
			[then]
				[foreach]
					array=sw_spots_current
					variable=sw_spot
					[do]
						[item]
							x=$sw_spot.x
							y=$sw_spot.y
							image=items/ball-blue.png
						[/item]
					[/do]
				[/foreach]
			[/then]
		[/if]
When giving string to be parsed as filter

Code: Select all

$ wesnoth.get_locations({x=wml.array_variables.sw_spots[4].x,y=wml.array_variables.sw_spots[4].y})
{{4,29,x=4,y=29},{11,26,x=11,y=26}}
With find_in it looks for x="4,11" and no location has noninteger x so no match.
IceSandslash
Developer
Posts: 17
Joined: February 12th, 2023, 1:13 pm

Re: Foreach location in each position of an array.

Post by IceSandslash »

You should be using x,y in your StandardLocationFilter (https://wiki.wesnoth.org/StandardLocationFilter) instead.

Code: Select all

	[store_locations]
		variable=sw_spots_current
		x=$sw_spots[$sw_turn].x
		y=$sw_spots[$sw_turn].y
	[/store_locations]
find_in is meant for when you already got the output of another store_locations operation,
and you want to filter only some of its elements.
BajMic
Posts: 42
Joined: January 24th, 2023, 1:22 am

Re: Foreach location in each position of an array.

Post by BajMic »

Ok, solved.

I did what Ravana and IceSandslash suggested, but I also used [literal] instead of [value] in [set_variables]. Posting the code for reference:

Code: Select all

[set_variables]
			name=nw_spots
			[literal]
				x=2
				y=1
			[/literal]
			[literal]
				x=6
				y=2
			[/literal]
			[literal]
				x=2,10
				y=1,4
			[/literal]
			[literal]
				x=6,14
				y=2,3
			[/literal]
			[literal]
				x=2,3,10,16
				y=3,1,4,5
			[/literal]
			[literal]
				x=6,7,14,16
				y=3,1,2,5
			[/literal]
			[literal]
				x=2,2,10,11,16,16
				y=1,3,4,3,3,5
			[/literal]
			[literal]
				x=6,7,14,15,16,16
				y=3,1,3,3,4,5
			[/literal]
			[literal]
				x=10,11,15,16,16,16
				y=4,3,3,3,4,5
			[/literal]
			[literal]
				x=14,15,15,16,16,16
				y=2,3,5,3,4,5
			[/literal]
		[/set_variables]

	[event]
		name=northwest_advances
		first_time_only=no
		{VARIABLE nw_turn $turn_number}
		{VARIABLE_OP nw_turn sub ($nw_takeoff)}
		[if]
			[variable]
				name=nw_turn
				equals=0
			[/variable]
			[then]
				[remove_item]
					x,y=2,1
				[/remove_item]
			[/then]
			[elseif]
				[variable]
					name=nw_turn
					less_than_equal_to=9
				[/variable]
				[then]
					[remove_item]
						image=nw_scarecrow
					[/remove_item]
				[/then]
			[/elseif]
		[/if]
		[store_locations]
			variable=nw_spots_current
			x=$nw_spots[$nw_turn].x
			y=$nw_spots[$nw_turn].y
		[/store_locations]
		[if]
			[variable]
				name=nw_turn
				greater_than_equal_to=0
			[/variable]
			[then]
				[foreach]
					array=nw_spots_current
					variable=nw_spot
					[do]
						[item]
							x=$nw_spot.x
							y=$nw_spot.y
							image=items/blue-scarecrow.png
							name=nw_scarecrow
						[/item]
					[/do]
				[/foreach]
			[/then]
		[/if]
	[/event]
Thank you for your help.

So, what this code does is... it imitates a travel of items that arrive from the edge of the map. Since approaching them provokes a reaction, I needed to store the coordinates. Since there are so many, I needed to pack them conveniently somehow - hence every element of the topmost array represents all hexes occupied during the same given turn.
Post Reply