WFL conditionals and variable substitution

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
white_haired_uncle
Posts: 1285
Joined: August 26th, 2018, 11:46 pm
Location: A country place, far outside the Wire

WFL conditionals and variable substitution

Post by white_haired_uncle »

I encountered this piece of code:

Code: Select all

 [effect] 
     apply_to=attack 
     increase_damage="$($quests.met_lilith*2-$quests.lilith_deaths)" 
 [/effect] 
 [effect] 
     apply_to=hitpoints 
     increase_total="$($quests.met_lilith*60-$quests.lilith_deaths*30)" 
     heal_full=yes 
 [/effect] 
which throws these errors

Code: Select all

20240514 00:13:30 error engine: Formula in WML string cannot be evaluated due to Expected another token
	--> "
20240514 00:13:30 error engine: Formula in WML string cannot be evaluated due to Illegal unary operator: '*'
	--> "
which I am reasonably sure is caused by the fact that $quests.lilith_deaths is undefined.

A couple attempts to correct this fail with 'illegal unary operator '=' ' which makes me think it still doesn't like $quests.lilith_deaths. It's as if variable substitution is literally just replacing $quests.lilith_deaths with ''. The examples for testing for null do not use variable substitution.

Code: Select all

                            [effect]
                                apply_to=attack
                                increase_damage="$($quests.met_lilith*2-(if($quests.lilith_deaths=null(),0,$quests.lilith_deaths)))"
                            [/effect]
                            [effect]
                                apply_to=hitpoints
                                increase_total="$(if($quests.lilith_deaths=null(),$quests.met_lilith*60,$quests.met_lilith*60-$quests.lilith_deaths*30))"
                                heal_full=yes
                            [/effect]

Can I fix this in WFL, or do I have to wrap the whole thing with a WML conditional, like

Code: Select all

[if]
    [variable]
        name=quests.lilith_deaths
        greater_than=0   # I wish I could actually test for null
...
[then]
[effect]  # with calculation done including $quests.lilith_deaths
...
[else]
[effect]  # with calculation done excluding $quests.lilith_deaths
Speak softly, and carry Doombringer.
User avatar
Ravana
Forum Moderator
Posts: 3068
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: WFL conditionals and variable substitution

Post by Ravana »

$quests.met_lilith -> ($quests.met_lilith-0)

It was more important around 1.10 when error in formula crashed game. "-" is operator that is valid both as binary and unary.
gnombat
Posts: 719
Joined: June 10th, 2010, 8:49 pm

Re: WFL conditionals and variable substitution

Post by gnombat »

white_haired_uncle wrote: May 14th, 2024, 1:49 pm

Code: Select all

[if]
    [variable]
        name=quests.lilith_deaths
        greater_than=0   # I wish I could actually test for null
...
I think you could replace that with this:

Code: Select all

[if]
    [variable]
        name=quests.lilith_deaths
        equals=""
...
Of course, you would have to switch the [then] and [else] code.
User avatar
Pentarctagon
Project Manager
Posts: 5592
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: WFL conditionals and variable substitution

Post by Pentarctagon »

equals=$variable_that_doesn't_exist should also work, I believe.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
white_haired_uncle
Posts: 1285
Joined: August 26th, 2018, 11:46 pm
Location: A country place, far outside the Wire

Re: WFL conditionals and variable substitution

Post by white_haired_uncle »

Ravana wrote: May 14th, 2024, 2:28 pm $quests.met_lilith -> ($quests.met_lilith-0)

It was more important around 1.10 when error in formula crashed game. "-" is operator that is valid both as binary and unary.
Sorry, I don't follow. It's puking on "=", not "-" so I'm a bit confused.

Honestly though, every attempt I've made at WFL end up like this:

Code: Select all

                        [lua]
                            code=<<
                                if wml.variables["quests.deaths_lilith"] ~= nil then
                                    wml.variables["lil_incr_damage"] = wml.variables["quests.met_lilith"] * 2 - wml.variables["quests.lilith_deaths"]
                                    wml.variables["lil_incr_total"] = wml.variables["quests.met_lilith"] * 60 - wml.variables["quests.lilith_deaths"] * 30
                                else
                                    wml.variables["lil_incr_damage"] = wml.variables["quests.met_lilith"] * 2
                                    wml.variables["lil_incr_total"] = wml.variables["quests.met_lilith"] * 60
                                end
                            >>
                        [/lua]
 
Speak softly, and carry Doombringer.
User avatar
Ravana
Forum Moderator
Posts: 3068
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: WFL conditionals and variable substitution

Post by Ravana »

You dont need any = in formula. You only started using = as another workaround idea.
User avatar
Celtic_Minstrel
Developer
Posts: 2274
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: WFL conditionals and variable substitution

Post by Celtic_Minstrel »

For substituting WML variables into any moderately complicated WFL formula, I'd recommend using a where clause.

Code: Select all

 [effect] 
     apply_to=attack 
     increase_damage="$(met_lilith*2-lilith_deaths where met_lilith = $quests.met_lilith - 0, lilith_deaths = $quests.lilith_deaths - 0)" 
 [/effect] 
 [effect] 
     apply_to=hitpoints 
     increase_total="$(met_lilith*60-lilith_deaths*30 where met_lilith = $quests.met_lilith - 0, lilith_deaths = $quests.lilith_deaths - 0)" 
     heal_full=yes 
 [/effect] 
The effect of this will be to make it use 0 as the value if either of the variables are undefined.

Note that if the variable was intended to be a string (obviously not the case here however), you would need to enclose it in quotes instead:

where met_lilith = '$quests.met_lilith'

And you'd have to make sure the variable cannot itself contain quotes.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
white_haired_uncle
Posts: 1285
Joined: August 26th, 2018, 11:46 pm
Location: A country place, far outside the Wire

Re: WFL conditionals and variable substitution

Post by white_haired_uncle »

If I'm following this right,

X - null = error, but
null - X = X

therefore
X - (null - 0) = X

[which of course, should mean that X - null + 0 = X -> X - null = X ]

But, I think I might see what's going on. Using simple substitution:

"X - $undefined_variable" = "X - ", which is invalid, while
"$undefined_variable - Y" = "-Y"

so basically in the second example the "-" which originally looked like an arithmetic operator actually parses as a negative sign. So,

"$undefined_variable - 0" -> "-0" -> 0, is a funky way of turning a null value into 0.

From which we can conclude: Do it in lua.
Speak softly, and carry Doombringer.
User avatar
Ravana
Forum Moderator
Posts: 3068
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: WFL conditionals and variable substitution

Post by Ravana »

(Celtic_Minstrel can correct if my understanding is wrong)

WML variables are expanded in increase_damage attribute as string. Only after expansion has been done, increase_damage is parsed as formula. Undefined WML variable expands to empty string, not formula-null.
User avatar
Celtic_Minstrel
Developer
Posts: 2274
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: WFL conditionals and variable substitution

Post by Celtic_Minstrel »

That's roughly correct, except that increase_damage is never actually parsed as a formula. The formula is parsed by $(...) in this case. Dollar substitutions are always evaluated from right to left, and $(...) is just a special type of dollar substitution. So yes, by the time it's parsing as a formula, the nonexistent variables have already been expanded to an empty string.

WFL does have an actual null value, represented as null(). I don't quite remember, but I think it functions as in SQL, which is to say you can add or subtract or multiply it or whatever and you'll always just get null back. But that doesn't come into play here at all.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply