Problem with WML for mp scenario

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
Hieronymus
Posts: 41
Joined: February 24th, 2005, 2:10 pm

Problem with WML for mp scenario

Post by Hieronymus »

Ok, since my first mp scenario is still not working and nobody seems to be able to tell me what's wrong (see http://www.wesnoth.org/forum/viewtopic.php?t=5037), I have decided to try making another scenario, a bit more simple. It is called "Domination" and the idea behind it is: there are 9 so called "domination villages" on the map. The player which controls 6 of them, wins.

Here is the code:

Code: Select all

[multiplayer] 
   	id=domination4p
   	name="Domination4p 0.1" 
   	map_data="{maps/multiplayer/Domination4p}" 
   	description="Domination4p 0.1"
	turns=20

   	{DAWN} 
   	{MORNING} 
   	{AFTERNOON} 
   	{DUSK} 
   	{FIRST_WATCH} 
   	{SECOND_WATCH} 

#####MACROS#####

#define ADD_SIDE SIDE
	[side] 
   		side={SIDE} 
   		team_name={SIDE} 
   		canrecruit=1 
   		controller=human 
   	[/side]
#enddef

#define SET_VILLAGE_CAPTURE_LISTENER X Y VILLAGENR
	# sets a capture event for this village, which stores the side which has captured it
	[message]
		message="Debug: SET_VILLAGE_CAPTURE_LISTENER village {VILLAGENR}"
	[/message]
	[event]
		name=capture
		first_time_only=no
		[filter]
			x={X}
			y={Y}
		[/filter]
		[message]
   			message="Debug: Village nr. {VILLAGENR} (pos {X},{Y}), captured by $primary_unit.side"
   		[/message]
		
		[set_variable]
			name=playerScores.score[$primary_unit.side]
			add=1
		[/set_variable]
		
		[if]
			[variable]
				name=playerScores.score[$primary_unit.side]
				equals=$nrVillagesToWin
			[/variable]
			[then]
				[message]
					message="Player $primary_unit.side has won!" #i will change that later
				[/message]
			[/then]
		[/if]

		[set_variable]
			name=playerScores.score[$villages.village[{VILLAGENR}].owner]
			add=-1
		[/set_variable]		
	
		[set_variable]
   			name=villages.village[{VILLAGENR}].owner
   			value=$primary_unit.side
   		[/set_variable]
		{DEBUGMSG {VILLAGENR}}
		{DEBUGMSGSCORES}
	[/event]
#enddef

#define DEBUGMSGSCORES
	[message]
		message="Scores = 0: $playerScores.score[0], 1: $playerScores.score[1], 2: $playerScores.score[2], 3: $playerScores.score[3]"
	[/message]
#enddef

#define DEBUGMSGVILLAGE VILLAGE
	[message]
		message="Village {VILLAGE} = x: $villages.village[{VILLAGE}].xPos, y: $villages.village[{VILLAGE}].yPos, owner: $villages.village[{VILLAGE}].owner"
	[/message]
#enddef

#define DEBUGMSGSTART
	[event]
		name=start
		{DEBUGMSGVILLAGE 0}
		{DEBUGMSGVILLAGE 1}
		{DEBUGMSGSCORES}		
	[/event]
#enddef

#define INIT
	[event]
		name=prestart
		[variables]
			[villages]
				[village]
					xPos=13
					yPos=4
					owner=0
				[/village]
				[village]
					xPos=8
					yPos=8
					owner=0
				[/village]
			[/villages]
			# left out the other domination villages for readability
			
			nrVillagesToWin=6
			
			[playerScores]
				score=-1 # there is no side 0!
				score=0
				score=0
				score=0
				score=0
			[/playerScores]
		[/variables]
	      {FOREACH villages villageNr}
			{SET_VILLAGE_CAPTURE_LISTENER $villages.village[$villageNr].xPos $villages.village[$villageNr].yPos $villageNr}
		{NEXT villageNr}									
	[/event]
#enddef

#####END MACROS#####

	{INIT}

	{ADD_SIDE 1}
	{ADD_SIDE 2}
	{ADD_SIDE 3}
	{ADD_SIDE 4}

	{DEBUGMSGSTART}

[/multiplayer]
The problem now is that it doesn't ta ... riablesWML.

Please help me and tell me what I am doing wrong... Thanks.
Invisible Philosopher
Posts: 873
Joined: July 4th, 2004, 9:14 pm
Location: My imagination
Contact:

Post by Invisible Philosopher »

There are lots of problems with this. (though I don't blame you for getting much of it wrong; VariablesWML is rather confusing.)
  • You can't use [variables] in an event like that. That tag is only used in savefiles. You would need to [set_variable] each one.
  • You seem to have an incorrect notion of how WML arrays work.
    This is how:

    Code: Select all

    [variables]
    [array_name]#this is element 0
    	some_array_element_var=something
    	another_array_element_var=another thing
    [/array_name]
    [array_name]#this is element 1
    	some_array_element_var=something
    	another_array_element_var=another thing
    [/array_name]
    [/variables]
    This is wrong:
    [variables]
    [playerScores]
    score=-1
    score=0
    score=0
    [/playerScores]

    [variables]
    A WML tag, such as [playerScores], contains a number of correspondences from distinct keys, such as score, to values, such as -1. Each key must be distinct and there is no conceptual ordering relationship. Tags can also contain other tags, which do have an order relationship. This is the mechanism by which arrays are stored (see the first example).

    This means that the element of an array does not have a value, because it is a tag; rather, it contains key/value pair(s) (often called attributes). This is the correct save-file representation of that array:

    Code: Select all

    [variables]
    [playerScores]#this is element 0
    	score=-1
    [/playerScores]
    [playerScores]#this is element 1
    	score=0
    [/playerScores]
    [playerScores]#this is element 2
    	score=0
    [/playerScores]
    [/variables]
    This means that the name of one of the variables is, for example,

    Code: Select all

    playerScores[2].score
    This means that to set it, you would do this (or use a macro shortcut):

    Code: Select all

    [set_variable]
    	name=playerScores[2].score
    	value=0
    [/set_variable]
    To retrieve it, usable in format=, message=, etc., as noted in VariablesWML, insert this:

    Code: Select all

    $playerScores[2].score
    That will only work in CVS or later versions (0.8.12+), though (this is the reason behind what you observed at the end of your post). If you want to be able to do it now, you have to do this before the relevant tag:

    Code: Select all

    [set_variable]
    	name=whatever
    	to_variable=playerScores[2].score
    [/set_variable]
    and then use

    Code: Select all

    $whatever
    in the attribute's value.
  • There are other problems but I'm tired from explaining the previous thing. Sorry.
Play a Silver Mage in the Wesvoid campaign.
Rhuvaen
Inactive Developer
Posts: 1272
Joined: August 27th, 2004, 8:05 am
Location: Berlin, Germany

Post by Rhuvaen »

Invisible Philosopher wrote:This means that to set it, you would do this (or use a macro shortcut):

Code: Select all

[set_variable]
	name=playerScores[2].score
	value=0
[/set_variable]
That's all nice and sweet if you use hard-coded indices with your arrays, but that's not really what you normally use them for, is it? What if...

... you want to extend your existing array by using a counter?
... you cross-index arrays?

I mean, how much does the engine actually interpret between those two brackets? Which of these will work:

Code: Select all

[set_variable]
	name=playerScores[$player_counter].score
	to_variable=$num_of_villages
[/set_variable]

Code: Select all

[set_variable]
	name=playerScores[$village[$x].owner].score
	add=1
[/set_variable]
I've found some of these at least to be highly problematic...
Invisible Philosopher
Posts: 873
Joined: July 4th, 2004, 9:14 pm
Location: My imagination
Contact:

Post by Invisible Philosopher »

Rhuvaen wrote:...
Wait until the next version, in which have made all of those possible (your first example already works).
I doubt you wanted to do `to_variable=$num_of_villages' though; you probably wanted either `format=$num_of_villages' or `to_variable=num_of_villages'.
Play a Silver Mage in the Wesvoid campaign.
Post Reply