Wesnoth formula language function "contains_string"
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.
-
- Posts: 33
- Joined: March 31st, 2018, 7:52 pm
- Location: USA
Wesnoth formula language function "contains_string"
I am attempting to utilize the WFL in my code, specifically the contain_string(string, search_string) function.
Here is what I've got:
I'm not sure what I am doing wrong, or if i am able to pass WML variables into the WFL at all. The variable "lookup" in the code is set to one if condtions in other part of the code.
Here is what I've got:
Code: Select all
[variable]
name=lookup
equals=$contains_string('[x]' where x = $attacks_array[$idx_1].id, '[y]' where y = $magic_list_array[{grp_idx}].name)
[/variable]
- Celtic_Minstrel
- Developer
- Posts: 2222
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: Wesnoth formula language function "contains_string"
In order to use WFL code in this context, you need to enclose the entire formula in parentheses. It's also strongly recommended to enclose the whole thing in double quotes, since not doing so will result in the
Applying those two fixes to your snippet gives the following:
The
+
sign being parsed out by the WML, which means WFL will raise a syntax error. You don't use +
in this case so it's not required, but it's recommended anyway.Applying those two fixes to your snippet gives the following:
Code: Select all
[variable]
name=lookup
equals="$(contains_string('[x]' where x = $attacks_array[$idx_1].id, '[y]' where y = $magic_list_array[{grp_idx}].name))"
[/variable]
$
substitution syntax is evaluated from right to left, which means that you can indeed include WML variables in a WFL formula similar to how you're doing it here. However, this should be thought of as similar to how the WML preprocessor works. The Wesnoth Formula Language knows nothing of WML variables; what's happening is that the contents of those variables are substituted in the WFL code before it's compiled into an executable form. That means that the result of substituting the WML variable into the formula must result in valid WFL code. In particular, if the WML variable contains a string (as seems to be the case here), you'll need to enclose the reference in single quotes if you want to references it as a string from the WFL.-
- Posts: 33
- Joined: March 31st, 2018, 7:52 pm
- Location: USA
Re: Wesnoth formula language function "contains_string"
Man, that is super useful. I read up about that but didn't find it super clear.Celtic_Minstrel wrote: ↑April 17th, 2018, 2:06 am In order to use WFL code in this context, you need to enclose the entire formula in parentheses. It's also strongly recommended to enclose the whole thing in double quotes, since not doing so will result in the+
sign being parsed out by the WML, which means WFL will raise a syntax error. You don't use+
in this case so it's not required, but it's recommended anyway.
Applying those two fixes to your snippet gives the following:TheCode: Select all
[variable] name=lookup equals="$(contains_string('[x]' where x = $attacks_array[$idx_1].id, '[y]' where y = $magic_list_array[{grp_idx}].name))" [/variable]
$
substitution syntax is evaluated from right to left, which means that you can indeed include WML variables in a WFL formula similar to how you're doing it here. However, this should be thought of as similar to how the WML preprocessor works. The Wesnoth Formula Language knows nothing of WML variables; what's happening is that the contents of those variables are substituted in the WFL code before it's compiled into an executable form. That means that the result of substituting the WML variable into the formula must result in valid WFL code. In particular, if the WML variable contains a string (as seems to be the case here), you'll need to enclose the reference in single quotes if you want to references it as a string from the WFL.
I ended up solving it with lua though after I got frustrated with wfl.
Here was my solution just in case it may help someone else.
Code: Select all
#define find_string string string_query
[lua]
code = << local t = ...;
if(((string.find(string.lower(t.string), string.lower(t.string_query))) ~= nil))
then
wesnoth.set_variable("find_string", "1")
end >>
[args]
string={string}
string_query={string_query}
[/args]
[/lua]
#enddef
Once you call it then all you have to do is clear it with this:
Code: Select all
#define clear_find_string
[lua]
code = << wesnoth.set_variable("find_string", nil) >>
[/lua]
#enddef
- Celtic_Minstrel
- Developer
- Posts: 2222
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: Wesnoth formula language function "contains_string"
For the record, you don't need to use Lua in a custom macro to clear the variable, you can just use
{CLEAR_VARIABLE find_string}
.Re: Wesnoth formula language function "contains_string"
If you are trying to filter units, you may want to make use of lua_function attribute in StandardUnitFilter. That one just needs to return true/false, so there's no need to store a WML variable.
By the way, using Lua code as you have done is a nicer solution than using WFL because a variable substitution could easily create invalid WFL (for example, if the WML variable contains single-quote ' that would prematurely terminate the WFL string). However, I would suggest your lua code store something or clear the variable on false instead of only storing for true. That would eliminate the errors caused by failing to clear the variable.
By the way, using Lua code as you have done is a nicer solution than using WFL because a variable substitution could easily create invalid WFL (for example, if the WML variable contains single-quote ' that would prematurely terminate the WFL string). However, I would suggest your lua code store something or clear the variable on false instead of only storing for true. That would eliminate the errors caused by failing to clear the 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."
-
- Posts: 33
- Joined: March 31st, 2018, 7:52 pm
- Location: USA
Re: Wesnoth formula language function "contains_string"
Hey, no I created a large database with base words with meta and sub data in order to easily categorize unit weapons (supposing that a modder has named their weapon something reasonable.Sapient wrote: ↑April 19th, 2018, 3:33 pm If you are trying to filter units, you may want to make use of lua_function attribute in StandardUnitFilter. That one just needs to return true/false, so there's no need to store a WML variable.
By the way, using Lua code as you have done is a nicer solution than using WFL because a variable substitution could easily create invalid WFL (for example, if the WML variable contains single-quote ' that would prematurely terminate the WFL string). However, I would suggest your lua code store something or clear the variable on false instead of only storing for true. That would eliminate the errors caused by failing to clear the variable.
That way, I can "can" some macros that allow one to generate basic weapon local variables based on the types of weapons a unit has. This was useful because I could inject amla's dynamically into a unit based on if they have say a silly weapon called "the killing goedendag of eternal chaos" and I had injections that injected on a successful query of meta "hammer" and sub of "reach" well there is a name in the database of "goedendag" that would return true based on the "find_string" result which would drill down into my conditionals and grant the amla.
I must be honest, I have to force myself to worry about error handling. After this post, I think I might just implement that.
Awesome! Thanks celtic!Celtic_Minstrel wrote: ↑April 19th, 2018, 2:35 am For the record, you don't need to use Lua in a custom macro to clear the variable, you can just use{CLEAR_VARIABLE find_string}
.
Last edited by Pentarctagon on April 22nd, 2018, 7:29 pm, edited 1 time in total.
Reason: Please avoid double posting - it's fine to reply to multiple people in the same post.
Reason: Please avoid double posting - it's fine to reply to multiple people in the same post.