Difference between revisions of "LuaAPI/wml"

From The Battle for Wesnoth Wiki
(Initial documentation of the new wml module, mostly by copy-pasting from the deprecated forms)
 
m (wml.tovconfig)
Line 91: Line 91:
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
 
wml.variables["varname"] = "to_be_deleted"
 
wml.variables["varname"] = "to_be_deleted"
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" }              -- correct
+
 
wesnoth.wml_actions.clear_variable { name = "$varname" }                   -- error: try to delete a variable literally called "$varname"
+
-- correct
wesnoth.wml_actions.clear_variable(wml.tovconfig { name = "$varname" }) -- correct: "$varname" is replaced by "to_be_deleted" at the right time
+
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" }
 +
 
 +
-- error: try to delete a variable literally called "$varname"
 +
wesnoth.wml_actions.clear_variable { name = "$varname" }
 +
 
 +
-- correct: "$varname" is replaced by "to_be_deleted" at the right time
 +
wesnoth.wml_actions.clear_variable(wml.tovconfig { name = "$varname" })
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Revision as of 01:37, 19 June 2018

The wml module contains functions for working with WML tables. This module is available starting in 1.14.0.

wml.child_array

  • wml.child_array(config, child_tag_name)array

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

wml.child_count

  • wml.child_count(config, child_tag_name)count

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

wml.child_range

  • wml.child_range(config, child_tag_name)iterator

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 wml.child_range(u.__cfg, "attack") do
    wesnoth.message(tostring(att.description))
end

wml.get_child

  • wml.get_child(config, child_tag_name [, id])child_table

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

local u = wesnoth.get_units({ id = "Delfador" })[1]
local costs = wml.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.

wml.get_nth_child

  • wml.get_nth_child(config, child_tag_name, n)child_table

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

wml.remove_child

  • wml.remove_child(config, child_tag_name)

Deletes the first child tag with the given name. This does not work on vconfig objects, however.

wml.remove_children

  • wml.remove_children(config, child_tag_name)

Deletes all child tags with the given name. This does not work on vconfig objects, however.

wml.tag

  • wml.tag.tag_name(contents)tag_table

Returns a table representing a tag within a WML table; can be used to create subtags with less brackets. It's common to use direct-table invocation for this, omitting the function parentheses.

wesnoth.wml_actions.event { name = "new turn", wml.tag.message { speaker = "narrator", message = "?" } }

wml.tostring

  • wml.tostring(wml_table)string

Takes a userdata with metatable wml object or a wml table and dumps its content into a pretty string.

wml.variables["number"] = 100
local vconfig = wml.tovconfig({ key = "$number", another_key = true,
    {"a_subtag", { a_key_in_the_subtag = "foo" }}
})
wesnoth.message(wml.tostring(vconfig))
wesnoth.message(wml.tostring(vconfig.__literal))

wml.tovconfig

  • wml.tovconfig(config)vconfig

Converts a WML table into a proxy object which performs variable substitution on the fly.

wml.variables["varname"] = "to_be_deleted"

-- correct
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" }

-- error: try to delete a variable literally called "$varname"
wesnoth.wml_actions.clear_variable { name = "$varname" }

-- correct: "$varname" is replaced by "to_be_deleted" at the right time
wesnoth.wml_actions.clear_variable(wml.tovconfig { name = "$varname" })

wml.literal

  • wml.literal(config)wml_table

Returns the __literal field of its argument if it is a userdata, the argument itself otherwise. If the argument is nil, it returns an empty table. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).

function wml_actions.display_literal_value(cfg)
   cfg = wml.literal(cfg)
   wesnoth.message(tostring(cfg.value)) 
end

Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.

wml.parsed

  • wml.parsed(config)wml_table

Returns the __parsed field of its argument if it is a userdata, the argument itself otherwise. See also #wml.literal.

wml.shallow_literal

  • wml.shallow_literal(config)wml_table

Returns the __shallow_literal field of its argument if it is a userdata, the argument itself otherwise. See also #wml.literal.

wml.shallow_parsed

  • wml.shallow_parsed(config)wml_table

Returns the __shallow_parsed field of its argument if it is a userdata, the argument itself otherwise. See also #wml.literal.

wml.all_variables

  • (game only) wml.all_variablestable

Returns a copy of all the WML variables currently set in the form of a WML table.

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

wml.variables

  • (game only) wml.variables.variablevariable_contents
  • (game only) wml.variables[variable_path]variable_contents

This table grants read-write access to the WML variables by their fully-qualified name. Looking up a non-existent variable yields nil; otherwise, it returns 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 = wml.variables["my_unit[0].hitpoints"]
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))

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 #wml.get_variable_array instead. If you need a specific one, include the index in the lookup key.

Assigning to a key in this table converts the Lua object to a WML variable if possible. For a table, a WML object is created; otherwise, an attribute is created. Note that you cannot assign a simple array as it will be mistaken for a WML table and give an error. Assigning nil clears the variable.

wml.variables["my_unit.hitpoints"] = heros_hp + 10

wml.variables_proxy

  • (game only) wml.variables_proxy.variableproxy
  • (game only) wml.variables_proxy[variable_path]proxy

Similar to wml.variables, but if the variable is a container, then the fields of the returned table are then proxies to the WML objects with the same names; reading/writing to them will directly access the WML sub-variables. Note that this is still somewhat experimental and doesn't allow you to fully treat variables as if they were standard Lua tables.

wml.array_access.get

  • (game only) wml.array_access.get(var_name[, context])array of variable_contents

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 = wml.array_access.get "LUA_recall_list"
    wml.variables.LUA_recall_list = nil
    return l
end

wml.array_access.get_proxy

  • (game only) wml.array_access.get_proxy(var_name)array of proxies

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 #wml.array_access.get, except that the proxies can be used for modifying WML containers. Note that changes to the returned array itself will not be reflected in the variable, however; only changes to the array elements.

wml.array_access.set

  • (game only) wml.array_access.set(varname, array [, context])

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.

wml.array_access.set("target", { {t=t1}, {t=t2}, {t=t3} })
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3