Difference between revisions of "LuaWML/Variables"

From The Battle for Wesnoth Wiki
(Add new argument for set_variable_array and get_variable_array)
(Add move notice)
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
{{Template:LuaMove}}
 +
 
This page describes the [[LuaWML]] functions and helpers for handling WML variables and containers.
 
This page describes the [[LuaWML]] functions and helpers for handling WML variables and containers.
  
Line 7: Line 9:
 
Loads a WML variable with the given qualified name (argument 1) and converts it into a Lua object. Returns ''nil'' if the name does not point to anything, a scalar for a WML attribute, and a table for a WML object. The format of the table is described in [[LuaWML#Encoding WML objects into Lua tables]].
 
Loads a WML variable with the given qualified name (argument 1) and converts it into a Lua object. Returns ''nil'' if the name does not point to anything, a scalar for a WML attribute, and a table for a WML object. The format of the table is described in [[LuaWML#Encoding WML objects into Lua tables]].
  
wesnoth.fire("store_unit", { variable="my_unit", { "filter", { id="hero" } } })
+
<syntaxhighlight lang=lua>
local heros_hp = wesnoth.get_variable("my_unit[0].hitpoints")
+
wesnoth.fire("store_unit", { variable="my_unit", { "filter", { id="hero" } } })
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))
+
local heros_hp = wesnoth.get_variable("my_unit[0].hitpoints")
 +
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))
 +
</syntaxhighlight>
  
 
Argument 2, if ''true'', prevents the recursive conversion when the name points to an object; a fresh empty table is returned in this case. This is mainly used for writing proxy objects, e.g. in [[#helper.set_wml_var_metatable]].
 
Argument 2, if ''true'', prevents the recursive conversion when the name points to an object; a fresh empty table is returned in this case. This is mainly used for writing proxy objects, e.g. in [[#helper.set_wml_var_metatable]].
Line 21: Line 25:
 
Converts and stores a Lua object (argument 2) to a WML variable (argument 1). A WML object is created for a table, an attribute otherwise.
 
Converts and stores a Lua object (argument 2) to a WML variable (argument 1). A WML object is created for a table, an attribute otherwise.
  
wesnoth.set_variable("my_unit.hitpoints", heros_hp + 10)
+
<syntaxhighlight lang=lua>
 +
wesnoth.set_variable("my_unit.hitpoints", heros_hp + 10)
 +
</syntaxhighlight>
  
 
Setting a WML variable to nil erases it.
 
Setting a WML variable to nil erases it.
Line 31: Line 37:
 
{{DevFeature1.13|0}} Returns all the WML variables currently set in form of a WML table. This function accepts no arguments.
 
{{DevFeature1.13|0}} Returns all the WML variables currently set in form of a WML table. This function accepts no arguments.
  
for key, value in pairs( wesnoth.get_all_vars() ) do
+
<syntaxhighlight lang=lua>
    if type( value ) == "table" then
+
for key, value in pairs( wesnoth.get_all_vars() ) do
        print( key, value[1], value[2] )
+
    if type( value ) == "table" then
    else
+
        print( key, value[1], value[2] )
        print( key, value )
+
    else
    end
+
        print( key, value )
end
+
    end
 
+
end
==== helper.set_wml_var_metatable ====
+
</syntaxhighlight>
 
 
* '''helper.set_wml_var_metatable{}'''
 
 
 
Sets the metatable of a table so that it can be used to access WML variables. Returns the table. The fields of the tables are then proxies to the WML objects with the same names; reading/writing to them will directly access the WML variables.
 
 
 
helper.set_wml_var_metatable(_G)
 
my_persistent_variable = 42
 
 
 
 
 
it's not reccomended to use helper.set_wml_var_metatable(_G) because that limits possible gobal variables to valid wml attributes or tables. This can have some surprising effects:
 
 
 
c = { a= 9}
 
d = c
 
c.a = 8
 
wesnoth.message(d.a) -- normaly prints 8 but prints 9 with helper.set_wml_var_metatable(_G)
 
 
 
local lla = { {"a", {}}}
 
lla[1][2] = lla
 
la = lla -- crashes wesnoth with helper.set_wml_var_metatable(_G)
 
 
 
helper = wesnoth.require("lua/helper.lua")
 
helper.set_wml_var_metatable(_G)
 
-- some code later (maybe in another addon)
 
H = wesnoth.require("lua/helper.lua") -- fails because wesnoth.require("lua/helper.lua") doesn' return a valid wmltable..
 
  
helper = wesnoth.require("lua/helper.lua")
+
==== wesnoth.wml_matches_filter ====
helper.set_wml_var_metatable(_G)
 
-- some code later (maybe in another addon)
 
T = helper.set_wml_tag_metatable {}  -- doesn't work
 
V = helper.set_wml_var_metatable({}) -- doesn't work
 
  
even if you don't use such code in your addon it's still bad because other code of modifications or eras to be used with your addon might do. And you'll mess up their code. This is also true for SP campaigns because it might interfere with ai code and we plan to enable modifications in SP too.
+
* '''wesnoth.wml_matches_filter(''config'', ''filter'')'''
Instead you should use set_wml_var_metatable with another table ('V' in this example):
 
  
V = helper.set_wml_var_metatable({})
+
Test if a config matches a WML filter (as <tt>[filter_wml]</tt>).
V.my_persistent_variable = 42
 
  
 
==== helper.get_child ====
 
==== helper.get_child ====
Line 83: Line 59:
 
Returns the first sub-tag of a WML object with the given name.
 
Returns the first sub-tag of a WML object with the given name.
  
local u = wesnoth.get_units({ id = "Delfador" })[1]
+
<syntaxhighlight lang=lua>
local costs = helper.get_child(u.__cfg, "movement_costs")
+
local u = wesnoth.get_units({ id = "Delfador" })[1]
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))
+
local costs = helper.get_child(u.__cfg, "movement_costs")
 +
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))
 +
</syntaxhighlight>
  
 
If a third parameter is passed, only children having a ''id'' attribute equal to it are considered.
 
If a third parameter is passed, only children having a ''id'' attribute equal to it are considered.
Line 111: Line 89:
 
Returns an iterator over all the sub-tags of a WML object with the given name.
 
Returns an iterator over all the sub-tags of a WML object with the given name.
  
local u = wesnoth.get_units({ id = "Delfador" })[1]
+
<syntaxhighlight lang=lua>
for att in helper.child_range(u.__cfg, "attack") do
+
local u = wesnoth.get_units({ id = "Delfador" })[1]
    wesnoth.message(tostring(att.description))
+
for att in helper.child_range(u.__cfg, "attack") do
end
+
    wesnoth.message(tostring(att.description))
 +
end
 +
</syntaxhighlight>
  
 
==== helper.child_array ====
 
==== helper.child_array ====
Line 127: Line 107:
  
 
* '''helper.get_variable_array(''var_name'')'''
 
* '''helper.get_variable_array(''var_name'')'''
* {{DevFeature1.13|8} '''helper.get_variable_array(''var_name'' [, ''context''])'''
+
* {{DevFeature1.13|8}} '''helper.get_variable_array(''var_name'' [, ''context''])'''
  
 
Fetches all the WML container variables with given name and returns a table containing them (starting at index 1). The context specifies where to get variables from. You can pass either a unit or a side as the context in order to get an array from the unit variables or side variables, respectively.
 
Fetches all the WML container variables with given name and returns a table containing them (starting at index 1). The context specifies where to get variables from. You can pass either a unit or a side as the context in order to get an array from the unit variables or side variables, respectively.
  
function get_recall_list(side)
+
<syntaxhighlight lang=lua>
    wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list })
+
function get_recall_list(side)
    local l = get_variable_array "LUA_recall_list"
+
    wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list" })
    wesnoth.set_variable "LUA_recall_list"
+
    local l = get_variable_array "LUA_recall_list"
    return l
+
    wesnoth.set_variable "LUA_recall_list"
end
+
    return l
 +
end
 +
</syntaxhighlight>
  
 
==== helper.get_variable_proxy_array ====
 
==== helper.get_variable_proxy_array ====
Line 151: Line 133:
 
Creates WML container variables with given name from given table. The context specifies where to put the variables. You can pass either a unit or a side as the context in order to set an array in the unit variables or side variables, respectively.
 
Creates WML container variables with given name from given table. The context specifies where to put the variables. You can pass either a unit or a side as the context in order to set an array in the unit variables or side variables, respectively.
  
helper.set_variable_array("target", { {t=t1}, {t=t2}, {t=t3} })
+
<syntaxhighlight lang=lua>
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3
+
helper.set_variable_array("target", { {t=t1}, {t=t2}, {t=t3} })
 +
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3
 +
</syntaxhighlight>
  
 
[[Category: Lua Reference]]
 
[[Category: Lua Reference]]

Latest revision as of 13:26, 12 February 2021



This page describes the LuaWML functions and helpers for handling WML variables and containers.

wesnoth.get_variable

  • wesnoth.get_variable(var_name)

Loads a WML variable with the given qualified name (argument 1) and converts it into a Lua object. Returns nil if the name does not point to anything, a scalar for a WML attribute, and a table for a WML object. The format of the table is described in LuaWML#Encoding WML objects into Lua tables.

wesnoth.fire("store_unit", { variable="my_unit", { "filter", { id="hero" } } })
local heros_hp = wesnoth.get_variable("my_unit[0].hitpoints")
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))

Argument 2, if true, prevents the recursive conversion when the name points to an object; a fresh empty table is returned in this case. This is mainly used for writing proxy objects, e.g. in #helper.set_wml_var_metatable.

Note that, if the variable name happens to designate a sequence of WML objects, only the first one (index 0) is fetched. If all the WML objects with this name should have been returned, use #helper.get_variable_array instead.

wesnoth.set_variable

  • wesnoth.set_variable(var_name, value)

Converts and stores a Lua object (argument 2) to a WML variable (argument 1). A WML object is created for a table, an attribute otherwise.

wesnoth.set_variable("my_unit.hitpoints", heros_hp + 10)

Setting a WML variable to nil erases it.

wesnoth.get_all_vars

  • wesnoth.get_all_vars()

(Version 1.13.0 and later only) Returns all the WML variables currently set in form of a WML table. This function accepts no arguments.

for key, value in pairs( wesnoth.get_all_vars() ) do
    if type( value ) == "table" then
        print( key, value[1], value[2] )
    else
        print( key, value )
    end
end

wesnoth.wml_matches_filter

  • wesnoth.wml_matches_filter(config, filter)

Test if a config matches a WML filter (as [filter_wml]).

helper.get_child

  • helper.get_child(config, child_tag_name)

Returns the first sub-tag of a WML object with the given name.

local u = wesnoth.get_units({ id = "Delfador" })[1]
local costs = helper.get_child(u.__cfg, "movement_costs")
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))

If a third parameter is passed, only children having a id attribute equal to it are considered.

helper.get_nth_child

(Version 1.13.2 and later only)

  • helper.get_nth_child(config, child_tag_name, n)

Returns the nth sub-tag of a WML object with the given name.

helper.child_count

(Version 1.13.2 and later only)

  • helper.child_count(config, child_tag_name)

Returns the number of children in the config with the given tag name.

helper.child_range

  • helper.child_range(config, child_tag_name)

Returns an iterator over all the sub-tags of a WML object with the given name.

local u = wesnoth.get_units({ id = "Delfador" })[1]
for att in helper.child_range(u.__cfg, "attack") do
    wesnoth.message(tostring(att.description))
end

helper.child_array

(Version 1.13.2 and later only)

  • helper.child_array(config, child_tag_name)

Like helper.child_range, but returns an array instead of an iterator. Useful if you need random access to the children.

helper.get_variable_array

Fetches all the WML container variables with given name and returns a table containing them (starting at index 1). The context specifies where to get variables from. You can pass either a unit or a side as the context in order to get an array from the unit variables or side variables, respectively.

function get_recall_list(side)
    wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list" })
    local l = get_variable_array "LUA_recall_list"
    wesnoth.set_variable "LUA_recall_list"
    return l
end

helper.get_variable_proxy_array

  • helper.get_variable_proxy_array(var_name)

Creates proxies for all the WML container variables with given name and returns a table containing them (starting at index 1). This function is similar to #helper.get_variable_array, except that the proxies can be used for modifying WML containers.

helper.set_variable_array

Creates WML container variables with given name from given table. The context specifies where to put the variables. You can pass either a unit or a side as the context in order to set an array in the unit variables or side variables, respectively.

helper.set_variable_array("target", { {t=t1}, {t=t2}, {t=t3} })
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3
This page was last edited on 12 February 2021, at 13:26.