tekelili advanced WML questions

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
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

I am trying become a code that demads player input become more stable. In order to do it I found myself with this question:
It is possible detect era in wich scenario was hosted and check if a variable value is a valid unit type in that era?
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: tekelili WML noob questions

Post by Anonymissimus »

tekelili wrote:It is possible detect era in wich scenario was hosted
Not without ugly complicated code I guess. Unless the era used prepares for this. For instance, in SoW era (which is useful if and only if the scenario is "Settlers of Wesnoth") I set a variable in an event, which is checked from an event in the scenario whether the correct required era is used.
I guess you could [use store_unit_types] and compare the result against known data about what unit types are in various eras...
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

I need a function (done with an event or anything else can work for it) to operate over an array (that I include as parameter when calling function). And I need can call recursively that function from inside itself. But as macros can not be called recursively,and {CALL_FUNTION} doesnt look accept arrays as parameter, I dont manage to imagine how do it. Can events be used for this in some way?
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: tekelili WML noob questions

Post by mattsc »

tekelili wrote:Can events be used for this in some way?
You can do something like this:

Code: Select all

[event]
    name=moveto
    first_time_only=no

    [fire_event]
        name=recursive_event
    [/fire_event]
[/event]

[event]
    name=recursive_event
    first_time_only=no

    {MESSAGE narrator "" "" _"Recursive event"}
    [fire_event]
        name=recursive_event
    [/fire_event]
[/event]
This starts the first time any unit moves. Of course, you'd need some condition to break it, this results in an infinite loop.
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

@mattsc: ¿where can I pass an array as parameter on your example?

I was starting to imagine I could modify {CALL_FUNCTION} macro. Store length of array passed as parameter and purge that amount of containers instead clear variable :hmm: It is that a possible way? it is the best?
Will this work for purge if I append arrays passed?

Code: Select all

{VARIABLE_OP Param_Arr.length sub $Stored_Length}
Last edited by tekelili on October 31st, 2011, 9:03 pm, edited 1 time in total.
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: tekelili WML noob questions

Post by mattsc »

tekelili wrote:@mattsc: ¿where can I pass an array as parameter on your example?
Oops! I shouldn't reply to posts quickly in between doing other things. Sorry...
tekelili wrote:I was starting to imagine I could modify {CALL_FUNCTION} macro. Store length of array passed as parameter and purge that amount of containers instead clear variable :hmm: It is that a possible way? it is the best?
That is certainly a way to do that. Whether that's the best way, after my gaffe a few minutes ago, I don't want to commit to that. ;)
tekelili wrote:Will this work for purge if I append arrays passed?

Code: Select all

    {VARIABLE Param_Arr.length sub $Stored_Length}
No, that won't work. And even if it did work, it would remove the parameters at the end of the array, while you want to remove them at the beginning. (At least if you want to follow what {CALL_FUNCTION} does.) You could use a while loop though. (Edit: of course, if you do it that way, it doesn't matter whether you insert at the beginning or append at the end. I should really shut up now ...)

Another possibility if you want to go that way: you can easily do this with Lua.
Last edited by mattsc on October 31st, 2011, 9:10 pm, edited 1 time in total.
User avatar
Natasiel
Moderator Emeritus
Posts: 60
Joined: February 28th, 2007, 7:43 pm

Re: tekelili WML noob questions

Post by Natasiel »

For your era detection thing, you can use something like:

Code: Select all

[set_variables]
        name=era[0]
        mode=replace
        [value]
	    id=default
            {multiplayer/factions/loyalists-default.cfg}
            ...
            {multiplayer/factions/khalifate-default.cfg}
        [/value]
    [/set_variables]
For any wanted era. (using ~/ ofc)
You can then check the variable era[0].multiplayer_side[0].id for a value.
Unfortunately it won't be any help on WC to detect Khalifate, as the host might have it but not the guests.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: tekelili WML noob questions

Post by Anonymissimus »

1. You get certified to no longer be a wml noob. Recursive events are certainly not noob wml. ^_^
2. It could look about like this (but I don't know what exactly you want to do there):

Code: Select all

	[event]
		name=caller
		{VARIABLE array_name name}
		[fire_event]
			name=recursive_function
		[/fire_event]
		{CLEAR_VARIABLE name}#depending on if/where you need it
	[/event]
	[event]
		name=recursive_function
		first_time_only=no
		{FOREACH $array_name i}
			#do stuff with $array_name|[$i]
			{NEXT i}
		[if]
			#some condition
			[then]
				[fire_event]
					name=recursive_function
				[/fire_event]
			[/then]
			[else]
				{CLEAR_VARIABLE array_name}
			[/else]
		[/if]
	[/event]
3. Actually yes, this is about the time one should use lua since wml wasn't designed to allow functions in the first place. Yet alone recursive ones.
4. There is somewhere a limit to prevent infinite recursions when calling events I think, this could be very disturbing in this case.

EDIT
In trunk I get a C stack overflow lua error for a recursive event without break condition, that's ok. So it seems there's no or no more an infinite recursion preventer.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

thanks guys for answer, I will try them (but will take me a while :lol2: ). I guess Anonymissimus will be best solution, but I justcome here with a idea, I will post it anyway, just in case I did something well for 1st time :whistle:
Spoiler:
I hope manage to have inside each event called recursively, information stored in first $length[0] containers of param array (in order reversed).

EDIT: This was jus an initial idea, see next post for a real solution
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

I managed to get a small victory 8)

To use recursion with arrays I have defined a virtual stack of arrays with 2 macros.
I find them very usefull for general propose, but may be I am old fashion assembly lover :P
If I didnt follow other post advises, is because I think they didnt understand why I was looking for (but may be I am wrong). I wanted call a function with an array as paramater and that array becomed changed as outcome. But I wanted can call recursively with different size arrays. An example of problem that needs this, is divide an array in 2 halves, but flip a coin if has and odd length. If you want repeat this procedure until all "pieces" are of 1 cointainer size, and add a value in that cointainers or reorder cointainers during porcess, recursion is best solution imho.

Code: Select all

#define STACK ARRAY
#Put ARRAY on top of stack
    [set_variables]
        mode=insert
        name=L_stack
        [value]
            cont=${ARRAY}.length
        [/value]
    [/set_variables]
    {REPEAT $L_stack[0].cont (
        [set_variables]
            mode=insert
            name=A_stack
            to_variable={ARRAY}[$REPEAT_i]
        [/set_variables]
    )}
#enddef

#define UN_STACK ARRAY
#Substitutes ARRAY for top one in stack and delete stack´s top one (top one is last stacked)
    {CLEAR_VARIABLE {ARRAY}}
    {REPEAT $L_stack[0].cont (
        [set_variables]
            mode=insert
            name={ARRAY}
            to_variable=A_stack[0]
        [/set_variables]
        {CLEAR_VARIABLE A_stack[0]}
    )}
    {CLEAR_VARIABLE L_stack[0]}
#enddef
And a Triger function macro

Code: Select all

#define CALL_A_FUNCTION EVENT_NAME PARAM_ARR
    {STACK {PARAM_ARR}} 
    [fire_event]
        name={EVENT_NAME}
    [/fire_event]
    {UN_STACK {PARAM_ARR}}
#enddef
I did an extupid function to test them. After call it, the order of PARAM_ARR containers get inverse. It is code is not optimal... but I was so happy it worked after many hours that I didnt dare to touch it. And I dont want a funtion to do this simple thing :lol2:

Code: Select all

[event]
    name=inverse_order
    first_time_only=no
    {UN_STACK array_temp}
    [if]
        {CONDITION array_temp.length greater_than 1}
    [then]
        {STACK array_temp}
        {CLEAR_VARIABLE array_temp[0]}
        {CALL_A_FUNCTION inverse_order array_temp}
        {UN_STACK old}
        [set_variables]
            mode=append
            name=array_temp
            to_variable=old[0]
        [/set_variables]
        {CLEAR_VARIABLE old}
    [/then]
    [/if]
    {STACK array_temp}
[/event]
Hard work is code well fuction events. You must use virtual stack to save variables used in each iteration and un_stack them in right order.
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

I guess this question has a qick answer: can I use a macro for define macros?
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
Natasiel
Moderator Emeritus
Posts: 60
Joined: February 28th, 2007, 7:43 pm

Re: tekelili WML noob questions

Post by Natasiel »

I don't know if it is pertinent, but you can actually do something like:

Code: Select all

#define FACTION_ERA
[multiplayer_side]
...
[/multiplayer_side]
#enddef

#define FACTION_MENU
[message]
...
[/message]
#enddef

#define FACTION CODE UNIT PRICE
{FACTION_{CODE} ({UNIT}) ({PRICE})}
#enddef

{FACTION ERA (fire drake) 21}
{FACTION MENU (drake fighter) 17}
I don't know if it makes sense, but you can do it. :)
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

Is there a defined tag or action in WML to clear all labels or should I create 2 nested loops to set a label "" on every hex of map?

And other question that can me bother in future. I am creating a data base and array I am using could have more than 1024 containers in future... will that cause me problems using FOREACH macro to operate over that array?
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: tekelili WML noob questions

Post by Anonymissimus »

tekelili wrote:Is there a defined tag or action in WML to clear all labels
No.
I can imagine it for 1.11 though. Tag [remove_label] which takes a SLF.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili WML noob questions

Post by tekelili »

My question in short format: Can different variables be used in function a value in a short way?
Now better explained :)

I have a variable called Victory. It can has orc, elf or loy as values. I want add 1 to variable orc_victory, elf_victory or loy_victory in function of Victory value. I am using this code right now for do this:

Code: Select all

[switch]
    variable=Victory
    [case]
        value=orc
        {VARIABLE_OP orc_victory add 1}
    [/case]
    [case]
        value=elf
        {VARIABLE_OP elf_victory add 1}
    [/case]
    [case]
        value=loy
        {VARIABLE_OP loy_victory add 1}
    [/case]
[/switch]
I would like be able to avoid switch tag to make code shorter, but I dont know if it is possible.

EDIT: a 2nd question for a problem I have: I want to create a message with as many [option] tags as containers in a given array, but it looks like I cant employ FOREACH macro inside [message] tag to create multiple [option] tags. Can be it done in some way I dont know?
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
Post Reply