How to use Array Variables in WML?

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.
meriton
Posts: 77
Joined: March 17th, 2007, 1:17 pm

How to use Array Variables in WML?

Post by meriton »

Is foo[3] a legal variable name? The wiki doesn't tell explictly. In my tests, assigning and retrieving such a variable works fine. So does creating and loading a saved game - provided the save is binary. If it is text, I get the following WML error on loading it:
error general: Die Datei, die Ihr laden wolltet, ist beschädigt: 'Unerwartete Zeichen nach einem Variablennamen (erwartet werden , oder =) an <unknown>:9380
Unerwartete Zeichen nach einem Variablennamen (erwartet werden , oder =) an <unknown>:9381
Unerwartete Zeichen nach einem Variablennamen (erwartet werden , oder =) an <unknown>:9382
Unerwartete Zeichen nach einem Variablennamen (erwartet werden , oder =) an <unknown>:9383
Unerwartete Zeichen nach einem Variablennamen (erwartet werden , oder =) an <unknown>:9384
Unerwartete Zeichen nach einem Variablennamen (erwartet werden , oder =) an <unknown>:9391
(translation: "general error: the file you wanted to load is damaged. Unexpected character following a variable name (expected , or =) at <unknown:9380> ...)

The relevant lines in the save file are:

Code: Select all

	[variables]
		armors[1]="10"
		armors[2]="10"
		armors[3]="10"
		armors[4]="10"
		armors[5]="10"
Am I right in concluding such variable names are not supported for text saves and hence shouldn't be used?
Last edited by meriton on July 14th, 2007, 12:42 am, edited 1 time in total.
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Post by Sapient »

not a valid variable name if you want to be able to load it from a save game.

if you want a scalar variable you should use $foo_3
if you want an array variable you should use $foo[3].name_of_a_variable_inside_foo

If you think about how array variables are stored in WML, and you will see why treating foo[3] as a scalar variable makes absolutely no sense:

Code: Select all

[variables]
  [foo]
    #index 0
  [/foo]
  [foo]
    #index 1
  [/foo]
  [foo]
    #index 2
  [/foo]
  [foo]
    #inidex 3
    name_of_a_variable_inside_foo=_"sample value"
  [/foo]
[/variables]
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
meriton
Posts: 77
Joined: March 17th, 2007, 1:17 pm

Post by meriton »

I think I'll update the wiki to state this explicitly, as opposed to by deduction from the save file format ;)

I was not aware I could nest variable lookups as in $foo_$i. Amazing how well adjusted I am to compiled languages; I observe their restrictions even when coding in an interpreted one ...
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Post by Sapient »

If you are just storing a single value at each index or plan to skip lots of indeces without data, then you really don't need an array.

If you want to see a good example of how to construct a simple scalar variable based on an integer such as side number (or series of integers, such as coordinates), then I suggest you read the Victory by controlling villages Macro on the Useful WML Fragments page in the wiki.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
meriton
Posts: 77
Joined: March 17th, 2007, 1:17 pm

Post by meriton »

I have spent the afternoon rewriting VariablesWML. Hopefully it is clearer and more complete now. Feel free to edit / point out mistakes.

In particular, the old version claimed variable substitution only occurred for "action tags" and the scenario tag. I have successfully used variable substitution in an event filter, which is no such tag. If someone knows the true extent of variable substitution, please clarify it in the wiki.

Oh, and the Village Victory condition is quite instructive. It is now listed as example on VariablesWML.
Mathijs
Posts: 146
Joined: May 23rd, 2007, 10:38 am
Location: Belgium

Post by Mathijs »

Got this from the new wiki page:
There is no tag to assign an array with arbitrary information, but there are tags to assign specific information, for instance [store_unit].
The above clearly indicates that's not right?
You can create ararys using [set_variable] and using [variables] !

I've added my comment on the wiki, remove it if it is incorrect. I havn't mentioned [variables] as I don't know how it works exactly. Would this:

Code: Select all

   [variables]
      [coordinates]
        x=10
        y=11
      [/coordinates]
      [coordinates]
        x=12
        y=13
      [/coordinates]
      [coordinates]
        x=14
        y=15
      [/coordinates]
      [coordinates]
        x=16
        y=17
      [/coordinates]      
   [/variables]
create an array you can acces like this?

Code: Select all

   $coordinates[1].x #would eqaul 12
   $coordinates[3].y #would eqaul 17
mat
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Post by Sapient »

Mat - you are correct about both methods of assigning values to an array. However, the [variables] method only works for setting *initial* values when the scenario is first loaded. The reason for this is that the [variables] tag is only understood inside the main scenario tag; inside events you must use [set_variable] for each value in the array (or the {VARIABLE} macros, which call [set_variable]).
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
meriton
Posts: 77
Joined: March 17th, 2007, 1:17 pm

Post by meriton »

About array assignment: I'll look into expressing myself more clearly there.

When I say there is no means to assign an array with arbitrary information, I don't imply there is no means to create an array or update variables contained therein: Assigning a variable replaces its value. [set_variable] can not do that for an array.

You are right about [variables] though. It is already described in the Overview section, but repeating it here wouldn't hurt.

---

[variables] is documented on VariablesWML towards the end. Your example of its use looks correct. As far as I know, support for [variables] outside save games is broken in the current stable release.
Dret
Posts: 79
Joined: June 13th, 2007, 11:06 pm
Contact:

Re: How to use Array Variables in WML?

Post by Dret »

I'm reading all post about arrays but i still have problem with them.

Im now working on a [set_menu_item] option that allows players to "Place Traps" on battle field.

Using:

Code: Select all

    [store_locations]
       x=$x1
       y=$y1
       variable=trap_pos
    [/store_locations]
I find the coordinates of each single Hex, selected by player, to place the trap (stored in "trap_pos" temp variabile).

How can I pass these values into an array, for storing all hexes that contain a trap, to be used later in a "moveto" event to check an eventual "encounter" with a unit?.

It's possible to do...?

I made a lot of trials but with no good result...!
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: How to use Array Variables in WML?

Post by Sapient »

Add to trap_pos using:

Code: Select all

    [store_locations]
       x=$x1
       y=$y1
       [or]
           find_in=trap_pos
       [/or]
       variable=trap_pos
    [/store_locations]
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
Dret
Posts: 79
Joined: June 13th, 2007, 11:06 pm
Contact:

Re: How to use Array Variables in WML?

Post by Dret »

I tryed with no results... but probably i was not able to express my problem in the best way..

I try now with this example:

PLAYER 1 TURN

- Select an Hex on map
- Place a "Trap" (with Customized Menu Option)
- coordinates x,y are store in an array (here I used the code in the first post)
- (player can repeat this operation for more times)

PLAYER 2 TURN

- Move units on a map
- A units finishes his movement on a "Trap" hex, previously posed by Player1 (Check if coordinates of the units are the same of trap stored in the array)
- If yes, the unit is Killed

In bold the passage that give me problem...!

Thanks a lot....
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: How to use Array Variables in WML?

Post by Sapient »

- A units finishes his movement on a "Trap" hex, previously posed by Player1 (Check if coordinates of the units are the same of trap stored in the array)

Code: Select all

   [event]
      name=moveto
      first_time_only=no
      [filter]
         [filter_location]
           find_in=trap_pos
         [/filter_location]
      [/filter]
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
Dret
Posts: 79
Joined: June 13th, 2007, 11:06 pm
Contact:

Re: How to use Array Variables in WML?

Post by Dret »

PS I have prepared a special thanks for you Sapient, in the introduction!
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: How to use Array Variables in WML?

Post by Sapient »

PS I have prepared a special thanks for you Sapient, in the introduction!
awww :oops:

You didn't ask this, but here is how to remove a location from an array of locations:

Code: Select all

[store_locations]
  find_in=trap_pos
  [not]
    x=$x1
    y=$y1
  [/not]
  variable=trap_pos
[/store_locations]
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
Dret
Posts: 79
Joined: June 13th, 2007, 11:06 pm
Contact:

Re: How to use Array Variables in WML?

Post by Dret »

... I don't ask because....I don't need...!!

I explain: the traps are the classic "Hole in the ground"... so when the units pass over... the terrain location are chaged to "Qxu" (and the unit is killed!).

This prevent another unit to pass over!!

But I'll preserve this code for other scenarios!

Thanks a lot again...!!
Post Reply