Trouble with the [if]

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
Sgt. Groovy
Art Contributor
Posts: 1471
Joined: May 22nd, 2006, 9:15 pm
Location: Helsinki

Trouble with the [if]

Post by Sgt. Groovy »

I have the following event in my scenario:

Code: Select all

[event]
    name="victory"
    [store_unit]
        [filter]
            side="2"
        [/filter]
        kill="yes"
        variable="MODIFY_UNIT_store"
    [/store_unit]
    [set_variable]
        name="MODIFY_UNIT_i"
        value="0"
    [/set_variable]
    [while]
        [variable]
            name="MODIFY_UNIT_i"
            less_than="$MODIFY_UNIT_store.length"
        [/variable]
        [do]
            [set_variable]
                name="MODIFY_UNIT_store[$MODIFY_UNIT_i].side"
                value="3"
            [/set_variable]
            [if]
                [variable]
                    name="MODIFY_UNIT_store[$MODIFY_UNIT_i].description"
                    equals="Ramskoi"
                [/variable]
                [then]
                    [set_variable]
                        name="MODIFY_UNIT_store[$MODIFY_UNIT_i].canrecruit"
                        value="0"
                    [/set_variable]
                    [set_variable]
                        name="MODIFY_UNIT_store[$MODIFY_UNIT_i].overlays"
                        value="misc/hero-icon.png"
                    [/set_variable]
                [/then]
            [/if]
            [unstore_unit]
                variable="MODIFY_UNIT_store[$MODIFY_UNIT_i]"
                find_vacant="no"
            [/unstore_unit]
            [set_variable]
                name="MODIFY_UNIT_i"
                add="1"
            [/set_variable]
        [/do]
    [/while]
    [clear_variable]
        name="MODIFY_UNIT_i"
    [/clear_variable]
    [clear_variable]
        name="MODIFY_UNIT_store"
    [/clear_variable]
[/event]
The idea is to turn all the units on side 2 to the side 3, and while at it, change few attributes of the unit with a description "Ramskoi". Changing the side works, and changing any unit attributes for all the units work, but nothing that is changed inside the [if] statement works. I've tried testing against the unit type as well, to no avail. I've been staring at the code untill my eyes hurt, but I just can't find anything wrong with it.
Tiedäthän kuinka pelataan.
Tiedäthän, vihtahousua vastaan.
Tiedäthän, solmu kravatin, se kantaa niin synnit
kuin syntien tekijätkin.
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Post by Sapient »

did you ever set his description in the first place? keep in mind description and user_description are different. another thing, debug messages are your friend.
make a [message] in the [then] and another one in an [else], and display the unit's description, maybe the location, and the branch reached (then or else).
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
User avatar
Sgt. Groovy
Art Contributor
Posts: 1471
Joined: May 22nd, 2006, 9:15 pm
Location: Helsinki

Post by Sgt. Groovy »

The thing is, the description, type, etc. appear in the savefiles, so they are set all right. I'll have to see how the messages will display them.
Last edited by Sgt. Groovy on March 4th, 2008, 8:54 am, edited 1 time in total.
Tiedäthän kuinka pelataan.
Tiedäthän, vihtahousua vastaan.
Tiedäthän, solmu kravatin, se kantaa niin synnit
kuin syntien tekijätkin.
User avatar
Sgt. Groovy
Art Contributor
Posts: 1471
Joined: May 22nd, 2006, 9:15 pm
Location: Helsinki

Post by Sgt. Groovy »

Ok, I tried the following:

Code: Select all

                    [then]
                        [message]
                            speaker=narrator
                            message="then/description is $MODIFY_UNIT_store[$MODIFY_UNIT_i].description"
                        [/message]
                        [set_variable]
                            name="MODIFY_UNIT_store[$MODIFY_UNIT_i].canrecruit"
                            value="0"
                        [/set_variable]
                        [set_variable]
                            name="MODIFY_UNIT_store[$MODIFY_UNIT_i].overlays"
                            value="misc/hero-icon.png"
                        [/set_variable]
                    [/then]
                    [else]
                        [message]
                            speaker=narrator
                            message="else/description is $MODIFY_UNIT_store[$MODIFY_UNIT_i].description"
                        [/message]
                    [/else]
and get the following output:

Code: Select all

else/description is Ramskoi
So the description is correct, yet the "equals" still returns false. Weirder yet, if I use "contains" instead of "equals", the test passes with the "Ramskoi" unit, but also with units that don't have a description set (recruited units). WTF :?
Tiedäthän kuinka pelataan.
Tiedäthän, vihtahousua vastaan.
Tiedäthän, solmu kravatin, se kantaa niin synnit
kuin syntien tekijätkin.
User avatar
Mist
Inactive Developer
Posts: 753
Joined: February 15th, 2007, 8:44 am
Location: Milton Keynes, UK

Re: Trouble with the [if]

Post by Mist »

Short suggestion in the beggining, you're developing really ugly and hard to read style of WML. It probably won't be a problem as long as everything works, but it will bite you hard when debbuging longer and harder to read fragments of it after some time. And it will be an absolute pain for anyone else trying to have a uswe from it later.

Anyway, below you have slightly rewritten version of the event with two debug messages thrown in important places. Excecute that and paste the output somewhere.

Code: Select all

[event]
    name=victory
    [store_unit]
        [filter]
            side=2
        [/filter]
        variable=unit_to_modify
    [/store_unit]
    {VARIABLE iterator 0}
    {FOREACH unit_to_modify iterator}
            {VARIABLE unit_to_modify[$iterator].side 3}
            {DEBUG_MSG unit_to_modify[$iterator].description}
            [if]
                [variable]
                    name=unit_to_modify[$iterator].description
                    equals=Ramskoi
                [/variable]
                [then]
                     {DEBUG_MSG "If clause executed"}
                    {VARIABLE unit_to_modify[$iterator].canrecruit no}
                    {VARIABLE unit_to_modify[$iterator].overlays "misc/hero-icon.png"}
                [/then]
            [/if]
            [unstore_unit]
                variable=unit_to_modify[$iterator]
                find_vacant=no
            [/unstore_unit]
    {NEXT iterator}  
    {CLEAR_VARIABLE iterator}
    {CLEAR_VARIABLE unit_to_modify}
[/event]
And paste the fragment where you declare the unit/side with description Ramskoi.
Somewhere, between the sacred silence and sleep.
Disorder.
AI
Developer
Posts: 2396
Joined: January 31st, 2008, 8:38 pm

Re: Trouble with the [if]

Post by AI »

Actually, FOREACH and NEXT do the setting and clearing themselves, so this will do too:

Code: Select all

[event]
    name=victory
    [store_unit]
        [filter]
            side=2
        [/filter]
        variable=unit_to_modify
    [/store_unit]
    {FOREACH unit_to_modify iterator}
            {VARIABLE unit_to_modify[$iterator].side 3}
            {DEBUG_MSG unit_to_modify[$iterator].description}
            [if]
                [variable]
                    name=unit_to_modify[$iterator].description
                    equals=Ramskoi
                [/variable]
                [then]
                     {DEBUG_MSG "If clause executed"}
                    {VARIABLE unit_to_modify[$iterator].canrecruit no}
                    {VARIABLE unit_to_modify[$iterator].overlays "misc/hero-icon.png"}
                [/then]
            [/if]
            [unstore_unit]
                variable=unit_to_modify[$iterator]
                find_vacant=no
            [/unstore_unit]
    {NEXT iterator}  
    {CLEAR_VARIABLE unit_to_modify}
[/event]
Rhuvaen
Inactive Developer
Posts: 1272
Joined: August 27th, 2004, 8:05 am
Location: Berlin, Germany

Re: Trouble with the [if]

Post by Rhuvaen »

Mist wrote:Short suggestion in the beggining, you're developing really ugly and hard to read style of WML.
Please explain... :?:

I know I am sometimes accused of similar crimes :twisted:, but IMO this

Code: Select all

{VARIABLE unit_to_modify[$iterator].side 3}
isn't better or worse in terms of readability or beauty than

Code: Select all

[set_variable]
    name=unit_to_modify[$iterator].side
    value=3
[/set_variable]
It's more convenient.

Personally, I even find the non-caps, spelled-out tags easier to read, usually, and the functionality is clearer in most cases.

My guess is that this could be a bug with [variable], array expression and equals=. I'd try substituting the array element to another variable, and using that for the condition.
User avatar
governor
Posts: 267
Joined: December 8th, 2006, 12:32 am

Re: Trouble with the [if]

Post by governor »

Rhuvaen wrote: I know I am sometimes accused of similar crimes :twisted:, but IMO this

Code: Select all

{VARIABLE unit_to_modify[$iterator].side 3}
isn't better or worse in terms of readability or beauty than

Code: Select all

[set_variable]
    name=unit_to_modify[$iterator].side
    value=3
[/set_variable]
Almost every programmer will agree with Mist. In programming and markup an efficient approach is almost always considered to be better. Even the size of the document is slightly less.

Elegant and beautiful:

Code: Select all

{VARIABLE unit_to_modify[$iterator].side 3}
Ugly:

Code: Select all

[set_variable]
    name=unit_to_modify[$iterator].side
    value=3
[/set_variable]
Readability:
Which is easier to read? 20 consecutive {VARIABLE} macros (20 lines which all fit on the screen at the same time), or 20 consecutive [set_variable] blocks (80 lines that span 3 pages). 20 lines is much easier and faster to debug/maintain/alter than 80 lines with sparse relevant information.
User avatar
Mist
Inactive Developer
Posts: 753
Joined: February 15th, 2007, 8:44 am
Location: Milton Keynes, UK

Re: Trouble with the [if]

Post by Mist »

Rhuvaen wrote:
Mist wrote:Short suggestion in the beggining, you're developing really ugly and hard to read style of WML.
Please explain... :?:
It might be somewat subjective but :
1) Spelled out explicit tags are good as long as you don't have few hundred lines of them. Subtle bugs tend to get lost in avalanche of letters, events and loops spanning over few screens are harder to understand for someone from outside than short and compact ones.
2) Most (all?) coding languages reserve capital indentifiers for preprocesor symbols, using them for variables is confusing for anyone with coding experience. And goes against mainline WML standart.
3) Evenif above was disregarded mixing capital and smallcase words in variable names is immensely ugly.
4) You either use short iterators ($i) and variable names or descriptive ones ($iterator), it doesn't help in large loops when ou have to remind yourself wether MY_VARIABLE_i is an iterator or MY_VARIABLE characterising object
5) That event could use some comments as well.

Generally if some trivial piece of code has shorter form and that shorter form is not worse in terms of readability or beauty, the shorter form should be used if just to prevent the code bloat and not distract outside people from more important places in the file.
Somewhere, between the sacred silence and sleep.
Disorder.
User avatar
Sgt. Groovy
Art Contributor
Posts: 1471
Joined: May 22nd, 2006, 9:15 pm
Location: Helsinki

Post by Sgt. Groovy »

Thanks for the style lesson, but it isn't my code, I ripped it from somewhere.

As far as I can see, the only thing your modification really does is hide lots of tags behind macros. When I tried it (having recruited two units plus Ramskoi to the side 2) I got the output:

Code: Select all

unit_to_modify[0].description
---
unit_to_modify[1].description
---
unit_to_modify[2].description
When I changed the 12th line into:

Code: Select all

{DEBUG_MSG $unit_to_modify[$iterator].description}
I got:

Code: Select all

Ramskoi
---
If clause executed
---
Ramskoi
---
If clause executed
---
Ramskoi
---
If clause executed
Outputting the value changed the outcome of the if-clause. :?
Tiedäthän kuinka pelataan.
Tiedäthän, vihtahousua vastaan.
Tiedäthän, solmu kravatin, se kantaa niin synnit
kuin syntien tekijätkin.
Post Reply