https://wiki.wesnoth.org/api.php?action=feedcontributions&user=Vasya&feedformat=atomThe Battle for Wesnoth Wiki - User contributions [en]2024-03-29T09:05:17ZUser contributionsMediaWiki 1.31.16https://wiki.wesnoth.org/index.php?title=LuaAPI/wml&diff=71941LuaAPI/wml2023-12-25T18:44:32Z<p>Vasya: Undo revision 71940 by Vasya (talk)</p>
<hr />
<div><div class="tright"> __TOC__ </div><br />
<br />
The <tt>wml</tt> module contains functions for working with WML tables. This module is available starting in 1.14.0.<br />
<br />
A WML table is a specially-formatted Lua table representing WML tags and values. For more detail on the format of WML tables, see [[LuaWML#Encoding_WML_objects_into_Lua_tables|LuaWML]].<br />
<br />
=== wml.attribute_count ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.attribute_count'''(''config'') &rarr; ''count''<br />
<br />
Returns the number of attributes in the specified WML table.<br />
<br />
=== wml.child_array ===<br />
<br />
* '''wml.child_array'''(''config'', ''child_tag_name'') &rarr; ''array''<br />
<br />
Like [[#wml.child_range]], but returns an array instead of an iterator. Useful if you need random access to the children.<br />
<br />
=== wml.child_count ===<br />
<br />
* '''wml.child_count'''(''config'', ''child_tag_name'') &rarr; ''count''<br />
<br />
Returns the number of children in the config with the given tag name.<br />
<br />
=== wml.child_range ===<br />
<br />
* '''wml.child_range'''(''config'', ''child_tag_name'') &rarr; ''iterator'' &rArr; ''wml table''<br />
<br />
Returns an iterator over all the sub-tags of a WML object with the given name.<br />
<br />
<syntaxhighlight lang=lua><br />
local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]<br />
for att in wml.child_range(u.__cfg, "attack") do<br />
wesnoth.message(tostring(att.description))<br />
end<br />
</syntaxhighlight><br />
<br />
=== wml.find_child ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.find_child'''(''config'', [''tag_name''], ''filter'') &rarr; ''child or nil'', ''index''<br />
<br />
Finds a child of the given config that matches the given filter, and returns the child or nil if not found. The index of the child is also returned. If a tag name is specified, the search is restricted to that tag.<br />
<br />
=== wml.get_child ===<br />
<br />
* '''wml.get_child'''(''config'', ''child_tag_name'', [''id'']) &rarr; ''child_table''<br />
<br />
Returns the first sub-tag of a WML object with the given name.<br />
<br />
<syntaxhighlight lang=lua><br />
local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]<br />
local costs = wml.get_child(u.__cfg, "movement_costs")<br />
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))<br />
</syntaxhighlight><br />
<br />
If a third parameter is passed, only children having a ''id'' attribute equal to it are considered.<br />
<br />
=== wml.get_nth_child ===<br />
<br />
* '''wml.get_nth_child'''(''config'', ''child_tag_name'', ''n'') &rarr; ''child_table''<br />
<br />
Returns the ''n''th sub-tag of a WML object with the given name.<br />
<br />
=== wml.remove_child ===<br />
<br />
* '''wml.remove_child'''(''config'', ''child_tag_name'')<br />
<br />
Deletes the first child tag with the given name. This does not work on vconfig objects, however.<br />
<br />
=== wml.remove_children ===<br />
<br />
{{DevFeature1.17|0}}<br />
<br />
* '''wml.remove_children'''(''config'', ''child_tag_name'', ...)<br />
<br />
Deletes all child tags with the given names. This does not work on vconfig objects, however. You can pass as many tag names as you want as separate arguments.<br />
<br />
=== wml.tag ===<br />
<br />
* '''wml.tag'''.''tag_name''(''contents'') &rarr; ''tag_table''<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.wml_actions.event { name = "new turn", wml.tag.message { speaker = "narrator", message = "?" } }<br />
</syntaxhighlight><br />
<br />
=== wml.clone ===<br />
<br />
{{DevFeature1.15|0}}<br />
<br />
* '''wml.clone'''(''wml_table'') &rarr; ''cloned_table''<br />
<br />
Returns a clone (deep copy) of the passed WML table.<br />
<br />
=== wml.equal ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.equal'''(''config'', ''config'') &rarr; ''true or false''<br />
<br />
Tests whether two WML objects are equal. Equal objects will produce an empty diff, and will be serialized to the same string.<br />
<br />
=== wml.valid ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.valid'''(''table'') &rarr; ''is_wml''<br />
<br />
Tests whether the passed table represents a valid WML table. It will also return true if passed a vconfig.<br />
<br />
=== wml.matches_filter ===<br />
<br />
* '''wml.matches_filter'''(''WML table'', ''filter'')''' &rarr; ''boolean''<br />
<br />
Test if a config matches a WML filter (as <tt>[filter_wml]</tt>).<br />
<br />
=== wml.load ===<br />
<br />
{{DevFeature1.15|0}}<br />
<br />
* '''wml.load'''(''file'', [''defines'', [''schema'']]) &rarr; ''config''<br />
<br />
Loads WML from a file and optionally validates it against a schema. The file and schema (if present) must both be a valid WML path. The second parameter can either be a boolean specifying whether or not to preprocess the file (defaults to true), or an array of macros to be defined in the preprocessor (which of course implies the file will be preprocessed). The second form only allows specifying names to be defined. It does not allow setting a value or anything more complex.<br />
<br />
=== wml.parse ===<br />
<br />
{{DevFeature1.15|0}}<br />
<br />
* '''wml.parse'''(''string'', [''schema'']) &rarr; ''config''<br />
<br />
Parses a string containing WML code and optionally validates it against the provided schema. Unlike load, this function does ''not'' run the preprocessor, though <tt>#textdomain</tt> directives will still be recognized.<br />
<br />
=== wml.merge ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.merge'''(''base table'', ''merge data'', ''mode'']) &rarr; ''merged config''<br />
<br />
Merges two WML tables recursively, using the specified mode. Possible modes are '''merge''', '''replace''', and '''append'''. The modes work the same as in [[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]. The mode only affects how child tags are merged; merging of attributes is always done the same way. The default mode is '''merge'''.<br />
<br />
=== wml.diff ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.diff'''(''left'', ''right'') &rarr; ''diff config''<br />
<br />
Compares two WML tables and produces an output table in [[DiffWML]] detailing their differences.<br />
<br />
=== wml.patch ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.patch'''(''base'', ''diff'') &rarr; ''patched config''<br />
<br />
Takes a WML table and a diff in [[DiffWML]] format and returns a new WML table modified according to the diff's instructions.<br />
<br />
=== wml.interpolate ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.interpolate'''('''template''', '''variables''') &rarr; ''interpolated config''<br />
<br />
Interpolates variables into a WML table, including '''[insert_tag]'''. This is the same as what a vconfig does implicitly, but can use any valid WML table as a source of variables.<br />
<br />
<syntaxhighlight lang=lua><br />
local variables = {<br />
-- A scalar variable<br />
number = 100,<br />
-- An array variable with two entries<br />
wml.tag.list{value = 42, rank = 3},<br />
wml.tag.list{value = 21, rank = 1},<br />
}<br />
local subst = {<br />
key = "$number",<br />
wml.tag.insert_tag{<br />
name = "entry",<br />
variable = "list"<br />
}<br />
}<br />
local result = wml.interpolate(subst, variables)<br />
print(wml.tostring(result))<br />
</syntaxhighlight><br />
<br />
The above code will output the following WML in the Lua console:<br />
<br />
<syntaxhighlight lang=wml><br />
key=100<br />
[entry]<br />
rank=3<br />
value=42<br />
[/entry]<br />
[entry]<br />
rank=1<br />
value=21<br />
[/entry]<br />
</syntaxhighlight><br />
<br />
=== wml.tostring ===<br />
<br />
* '''wml.tostring'''(''wml_table'') &rarr; ''string''<br />
<br />
Takes a userdata with metatable wml object or a wml table and dumps its content into a pretty string. {{DevFeature1.15|0}} The string output is syntactically valid WML that if parsed would produce the same config.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.variables["number"] = 100<br />
local vconfig = wml.tovconfig({ key = "$number", another_key = true,<br />
{"a_subtag", { a_key_in_the_subtag = "foo" }}<br />
})<br />
wesnoth.message(wml.tostring(vconfig))<br />
wesnoth.message(wml.tostring(vconfig.__literal))<br />
</syntaxhighlight><br />
<br />
=== wml.tovconfig ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.tovconfig'''(''config'') &rarr; ''vconfig''<br />
<br />
Converts a WML table into a proxy object which performs variable substitution on the fly. The proxy object can for most intents and purposes be treated as a read-only table - the length operator works as expected, as does the ipairs function. The pairs function also works, but it is a little different than on a plain table - it will return only the attributes of the vconfig and not the tags. See [[LuaWML#Encoding_WML_objects_into_Lua_tables|LuaWML]] for more information about the structure of a vconfig (which is the same as the structure of a WML table). A vconfig has four special keys (''__literal'', ''__parsed'', ''__shallow_literal'', ''__shallow_parsed'') which correspond to the functions in this module by the same name, but in most cases it is better to use the functions.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.variables["varname"] = "to_be_deleted"<br />
<br />
-- correct<br />
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" }<br />
-- error: try to delete a variable literally called "$varname"<br />
wesnoth.wml_actions.clear_variable { name = "$varname" }<br />
-- correct: "$varname" is replaced by "to_be_deleted" at the right time<br />
wesnoth.wml_actions.clear_variable(wml.tovconfig { name = "$varname" })<br />
</syntaxhighlight><br />
<br />
=== wml.literal ===<br />
<br />
* '''wml.literal'''(''config'') &rarr; ''wml_table''<br />
<br />
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).<br />
<br />
<syntaxhighlight lang=lua><br />
function wml_actions.display_literal_value(cfg)<br />
cfg = wml.literal(cfg)<br />
wesnoth.message(tostring(cfg.value)) <br />
end<br />
</syntaxhighlight><br />
<br />
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.<br />
<br />
=== wml.parsed ===<br />
<br />
* '''wml.parsed'''(''config'') &rarr; ''wml_table''<br />
<br />
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].<br />
<br />
=== wml.shallow_literal ===<br />
<br />
* '''wml.shallow_literal'''(''config'') &rarr; ''wml_table''<br />
<br />
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].<br />
<br />
=== wml.shallow_parsed ===<br />
<br />
* '''wml.shallow_parsed'''(''config'') &rarr; ''wml_table''<br />
<br />
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].<br />
<br />
=== wml.all_variables ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.all_variables''' &rarr; ''table''<br />
<br />
Returns a copy of all the WML variables currently set in the form of a WML table.<br />
<br />
<syntaxhighlight lang=lua><br />
for key, value in pairs(wml.all_variables) do<br />
if type(value) == "table" then<br />
print(key, value[1], value[2])<br />
else<br />
print(key, value)<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== wml.variables ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables'''.''variable'' &harr; ''variable_contents''<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables'''[''variable_path''] &harr; ''variable_contents''<br />
<br />
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]].<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.fire("store_unit", { variable="my_unit", { "filter", { id="hero" } } })<br />
local heros_hp = wml.variables["my_unit[0].hitpoints"]<br />
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))<br />
</syntaxhighlight><br />
<br />
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.array_access.get]] instead. If you need a specific one, include the index in the lookup key.<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.variables["my_unit.hitpoints"] = heros_hp + 10<br />
</syntaxhighlight><br />
<br />
=== wml.variables_proxy ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables_proxy'''.''variable'' &harr; ''proxy''<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables_proxy'''[''variable_path''] &harr; ''proxy''<br />
<br />
Similar to <tt>wml.variables</tt>, 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.<br />
<br />
=== wml.array_access.get ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.get'''(''var_name'', [''context'']) &rarr; ''array of variable_contents''<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
function get_recall_list(side)<br />
wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list" })<br />
local l = wml.array_access.get "LUA_recall_list"<br />
wml.variables.LUA_recall_list = nil<br />
return l<br />
end<br />
</syntaxhighlight><br />
<br />
=== wml.array_access.get_proxy ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.get_proxy'''(''var_name'') &rarr; ''array of proxies''<br />
<br />
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.<br />
<br />
=== wml.array_access.set ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.set'''(''varname'', ''array'', [''context''])<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.array_access.set("target", { {t=t1}, {t=t2}, {t=t3} })<br />
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3<br />
</syntaxhighlight><br />
<br />
=== wml.array_variables ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_variables'''.''variable'' &harr; ''array of variable_contents''<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_variables'''[''variable_path''] &harr; ''array of variable_contents''<br />
<br />
Like '''wml.variables''', except that it works on arrays as with '''wml.array_access.get''' and '''wml.array_access.set'''. This is a little more convenient when working with global WML variables rather than unit or side variables.<br />
<br />
=== wml.eval_conditional ===<br />
<br />
* {{LuaGameOnly}} '''wml.eval_conditional'''(''conditional_tags'') &rarr; ''boolean''<br />
<br />
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.<br />
<br />
<syntaxhighlight lang=lua><br />
local result = wml.eval_conditional {<br />
wml.have_unit { id = "hero" },<br />
wml.variable { name = "counter", numerical_equals = "$old_counter" }<br />
}<br />
</syntaxhighlight><br />
<br />
Note: Prior to 1.15.13, this was available as '''wesnoth.eval_conditional'''.<br />
<br />
=== wml.fire ===<br />
<br />
* {{LuaGameOnly}} '''wml.fire'''(''tag'', ''parameters'')<br />
* {{DevFeature1.17|17}} {{LuaGameOnly}} '''wml.fire'''.''tag''(''parameters'')<br />
<br />
Fire a WML action tag. Note: WML variables are substituted into the parameters table.<br />
<br />
Note: Prior to 1.15.13, this was available as '''wesnoth.fire'''. The second form was available through '''helper.set_wml_action_metatable'''.<br />
<br />
=== wml.error ===<br />
<br />
* {{LuaGameOnly}} '''wml.error'''(''message'')<br />
<br />
Interrupts the current execution and displays a WML error message. This is intended for error messages in the implementaton of custom ActionWML or ConditionalWML tags. For errors in a Lua API, the built-in '''error''' function is a more suitable choice.<br />
<br />
<syntaxhighlight lang=lua><br />
local names = cfg.name or wml.error("[clear_variable] missing required name= attribute.")<br />
</syntaxhighlight><br />
<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaAPI/wml&diff=71940LuaAPI/wml2023-12-25T16:49:09Z<p>Vasya: Add a migration note from set_wml_tag_metatable to wml.tag</p>
<hr />
<div><div class="tright"> __TOC__ </div><br />
<br />
The <tt>wml</tt> module contains functions for working with WML tables. This module is available starting in 1.14.0.<br />
<br />
A WML table is a specially-formatted Lua table representing WML tags and values. For more detail on the format of WML tables, see [[LuaWML#Encoding_WML_objects_into_Lua_tables|LuaWML]].<br />
<br />
=== wml.attribute_count ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.attribute_count'''(''config'') &rarr; ''count''<br />
<br />
Returns the number of attributes in the specified WML table.<br />
<br />
=== wml.child_array ===<br />
<br />
* '''wml.child_array'''(''config'', ''child_tag_name'') &rarr; ''array''<br />
<br />
Like [[#wml.child_range]], but returns an array instead of an iterator. Useful if you need random access to the children.<br />
<br />
=== wml.child_count ===<br />
<br />
* '''wml.child_count'''(''config'', ''child_tag_name'') &rarr; ''count''<br />
<br />
Returns the number of children in the config with the given tag name.<br />
<br />
=== wml.child_range ===<br />
<br />
* '''wml.child_range'''(''config'', ''child_tag_name'') &rarr; ''iterator'' &rArr; ''wml table''<br />
<br />
Returns an iterator over all the sub-tags of a WML object with the given name.<br />
<br />
<syntaxhighlight lang=lua><br />
local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]<br />
for att in wml.child_range(u.__cfg, "attack") do<br />
wesnoth.message(tostring(att.description))<br />
end<br />
</syntaxhighlight><br />
<br />
=== wml.find_child ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.find_child'''(''config'', [''tag_name''], ''filter'') &rarr; ''child or nil'', ''index''<br />
<br />
Finds a child of the given config that matches the given filter, and returns the child or nil if not found. The index of the child is also returned. If a tag name is specified, the search is restricted to that tag.<br />
<br />
=== wml.get_child ===<br />
<br />
* '''wml.get_child'''(''config'', ''child_tag_name'', [''id'']) &rarr; ''child_table''<br />
<br />
Returns the first sub-tag of a WML object with the given name.<br />
<br />
<syntaxhighlight lang=lua><br />
local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]<br />
local costs = wml.get_child(u.__cfg, "movement_costs")<br />
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))<br />
</syntaxhighlight><br />
<br />
If a third parameter is passed, only children having a ''id'' attribute equal to it are considered.<br />
<br />
=== wml.get_nth_child ===<br />
<br />
* '''wml.get_nth_child'''(''config'', ''child_tag_name'', ''n'') &rarr; ''child_table''<br />
<br />
Returns the ''n''th sub-tag of a WML object with the given name.<br />
<br />
=== wml.remove_child ===<br />
<br />
* '''wml.remove_child'''(''config'', ''child_tag_name'')<br />
<br />
Deletes the first child tag with the given name. This does not work on vconfig objects, however.<br />
<br />
=== wml.remove_children ===<br />
<br />
{{DevFeature1.17|0}}<br />
<br />
* '''wml.remove_children'''(''config'', ''child_tag_name'', ...)<br />
<br />
Deletes all child tags with the given names. This does not work on vconfig objects, however. You can pass as many tag names as you want as separate arguments.<br />
<br />
=== wml.tag ===<br />
<br />
* '''wml.tag'''.''tag_name''(''contents'') &rarr; ''tag_table''<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.wml_actions.event { name = "new turn", wml.tag.message { speaker = "narrator", message = "?" } }<br />
</syntaxhighlight><br />
<br />
Migration note from Wesnoth-1.16 and below. When you've previously used<br />
<syntaxhighlight lang=lua>local T = wesnoth.require("lua/helper.lua").set_wml_tag_metatable {}</syntaxhighlight><br />
You can now use:<br />
<syntaxhighlight lang=lua>local T = wml.tag</syntaxhighlight><br />
<br />
=== wml.clone ===<br />
<br />
{{DevFeature1.15|0}}<br />
<br />
* '''wml.clone'''(''wml_table'') &rarr; ''cloned_table''<br />
<br />
Returns a clone (deep copy) of the passed WML table.<br />
<br />
=== wml.equal ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.equal'''(''config'', ''config'') &rarr; ''true or false''<br />
<br />
Tests whether two WML objects are equal. Equal objects will produce an empty diff, and will be serialized to the same string.<br />
<br />
=== wml.valid ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.valid'''(''table'') &rarr; ''is_wml''<br />
<br />
Tests whether the passed table represents a valid WML table. It will also return true if passed a vconfig.<br />
<br />
=== wml.matches_filter ===<br />
<br />
* '''wml.matches_filter'''(''WML table'', ''filter'')''' &rarr; ''boolean''<br />
<br />
Test if a config matches a WML filter (as <tt>[filter_wml]</tt>).<br />
<br />
=== wml.load ===<br />
<br />
{{DevFeature1.15|0}}<br />
<br />
* '''wml.load'''(''file'', [''defines'', [''schema'']]) &rarr; ''config''<br />
<br />
Loads WML from a file and optionally validates it against a schema. The file and schema (if present) must both be a valid WML path. The second parameter can either be a boolean specifying whether or not to preprocess the file (defaults to true), or an array of macros to be defined in the preprocessor (which of course implies the file will be preprocessed). The second form only allows specifying names to be defined. It does not allow setting a value or anything more complex.<br />
<br />
=== wml.parse ===<br />
<br />
{{DevFeature1.15|0}}<br />
<br />
* '''wml.parse'''(''string'', [''schema'']) &rarr; ''config''<br />
<br />
Parses a string containing WML code and optionally validates it against the provided schema. Unlike load, this function does ''not'' run the preprocessor, though <tt>#textdomain</tt> directives will still be recognized.<br />
<br />
=== wml.merge ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.merge'''(''base table'', ''merge data'', ''mode'']) &rarr; ''merged config''<br />
<br />
Merges two WML tables recursively, using the specified mode. Possible modes are '''merge''', '''replace''', and '''append'''. The modes work the same as in [[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]. The mode only affects how child tags are merged; merging of attributes is always done the same way. The default mode is '''merge'''.<br />
<br />
=== wml.diff ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.diff'''(''left'', ''right'') &rarr; ''diff config''<br />
<br />
Compares two WML tables and produces an output table in [[DiffWML]] detailing their differences.<br />
<br />
=== wml.patch ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.patch'''(''base'', ''diff'') &rarr; ''patched config''<br />
<br />
Takes a WML table and a diff in [[DiffWML]] format and returns a new WML table modified according to the diff's instructions.<br />
<br />
=== wml.interpolate ===<br />
<br />
{{DevFeature1.15|3}}<br />
<br />
* '''wml.interpolate'''('''template''', '''variables''') &rarr; ''interpolated config''<br />
<br />
Interpolates variables into a WML table, including '''[insert_tag]'''. This is the same as what a vconfig does implicitly, but can use any valid WML table as a source of variables.<br />
<br />
<syntaxhighlight lang=lua><br />
local variables = {<br />
-- A scalar variable<br />
number = 100,<br />
-- An array variable with two entries<br />
wml.tag.list{value = 42, rank = 3},<br />
wml.tag.list{value = 21, rank = 1},<br />
}<br />
local subst = {<br />
key = "$number",<br />
wml.tag.insert_tag{<br />
name = "entry",<br />
variable = "list"<br />
}<br />
}<br />
local result = wml.interpolate(subst, variables)<br />
print(wml.tostring(result))<br />
</syntaxhighlight><br />
<br />
The above code will output the following WML in the Lua console:<br />
<br />
<syntaxhighlight lang=wml><br />
key=100<br />
[entry]<br />
rank=3<br />
value=42<br />
[/entry]<br />
[entry]<br />
rank=1<br />
value=21<br />
[/entry]<br />
</syntaxhighlight><br />
<br />
=== wml.tostring ===<br />
<br />
* '''wml.tostring'''(''wml_table'') &rarr; ''string''<br />
<br />
Takes a userdata with metatable wml object or a wml table and dumps its content into a pretty string. {{DevFeature1.15|0}} The string output is syntactically valid WML that if parsed would produce the same config.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.variables["number"] = 100<br />
local vconfig = wml.tovconfig({ key = "$number", another_key = true,<br />
{"a_subtag", { a_key_in_the_subtag = "foo" }}<br />
})<br />
wesnoth.message(wml.tostring(vconfig))<br />
wesnoth.message(wml.tostring(vconfig.__literal))<br />
</syntaxhighlight><br />
<br />
=== wml.tovconfig ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.tovconfig'''(''config'') &rarr; ''vconfig''<br />
<br />
Converts a WML table into a proxy object which performs variable substitution on the fly. The proxy object can for most intents and purposes be treated as a read-only table - the length operator works as expected, as does the ipairs function. The pairs function also works, but it is a little different than on a plain table - it will return only the attributes of the vconfig and not the tags. See [[LuaWML#Encoding_WML_objects_into_Lua_tables|LuaWML]] for more information about the structure of a vconfig (which is the same as the structure of a WML table). A vconfig has four special keys (''__literal'', ''__parsed'', ''__shallow_literal'', ''__shallow_parsed'') which correspond to the functions in this module by the same name, but in most cases it is better to use the functions.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.variables["varname"] = "to_be_deleted"<br />
<br />
-- correct<br />
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" }<br />
-- error: try to delete a variable literally called "$varname"<br />
wesnoth.wml_actions.clear_variable { name = "$varname" }<br />
-- correct: "$varname" is replaced by "to_be_deleted" at the right time<br />
wesnoth.wml_actions.clear_variable(wml.tovconfig { name = "$varname" })<br />
</syntaxhighlight><br />
<br />
=== wml.literal ===<br />
<br />
* '''wml.literal'''(''config'') &rarr; ''wml_table''<br />
<br />
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).<br />
<br />
<syntaxhighlight lang=lua><br />
function wml_actions.display_literal_value(cfg)<br />
cfg = wml.literal(cfg)<br />
wesnoth.message(tostring(cfg.value)) <br />
end<br />
</syntaxhighlight><br />
<br />
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.<br />
<br />
=== wml.parsed ===<br />
<br />
* '''wml.parsed'''(''config'') &rarr; ''wml_table''<br />
<br />
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].<br />
<br />
=== wml.shallow_literal ===<br />
<br />
* '''wml.shallow_literal'''(''config'') &rarr; ''wml_table''<br />
<br />
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].<br />
<br />
=== wml.shallow_parsed ===<br />
<br />
* '''wml.shallow_parsed'''(''config'') &rarr; ''wml_table''<br />
<br />
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].<br />
<br />
=== wml.all_variables ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.all_variables''' &rarr; ''table''<br />
<br />
Returns a copy of all the WML variables currently set in the form of a WML table.<br />
<br />
<syntaxhighlight lang=lua><br />
for key, value in pairs(wml.all_variables) do<br />
if type(value) == "table" then<br />
print(key, value[1], value[2])<br />
else<br />
print(key, value)<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== wml.variables ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables'''.''variable'' &harr; ''variable_contents''<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables'''[''variable_path''] &harr; ''variable_contents''<br />
<br />
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]].<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.fire("store_unit", { variable="my_unit", { "filter", { id="hero" } } })<br />
local heros_hp = wml.variables["my_unit[0].hitpoints"]<br />
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))<br />
</syntaxhighlight><br />
<br />
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.array_access.get]] instead. If you need a specific one, include the index in the lookup key.<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.variables["my_unit.hitpoints"] = heros_hp + 10<br />
</syntaxhighlight><br />
<br />
=== wml.variables_proxy ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables_proxy'''.''variable'' &harr; ''proxy''<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables_proxy'''[''variable_path''] &harr; ''proxy''<br />
<br />
Similar to <tt>wml.variables</tt>, 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.<br />
<br />
=== wml.array_access.get ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.get'''(''var_name'', [''context'']) &rarr; ''array of variable_contents''<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
function get_recall_list(side)<br />
wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list" })<br />
local l = wml.array_access.get "LUA_recall_list"<br />
wml.variables.LUA_recall_list = nil<br />
return l<br />
end<br />
</syntaxhighlight><br />
<br />
=== wml.array_access.get_proxy ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.get_proxy'''(''var_name'') &rarr; ''array of proxies''<br />
<br />
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.<br />
<br />
=== wml.array_access.set ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.set'''(''varname'', ''array'', [''context''])<br />
<br />
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.<br />
<br />
<syntaxhighlight lang=lua><br />
wml.array_access.set("target", { {t=t1}, {t=t2}, {t=t3} })<br />
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3<br />
</syntaxhighlight><br />
<br />
=== wml.array_variables ===<br />
<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_variables'''.''variable'' &harr; ''array of variable_contents''<br />
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_variables'''[''variable_path''] &harr; ''array of variable_contents''<br />
<br />
Like '''wml.variables''', except that it works on arrays as with '''wml.array_access.get''' and '''wml.array_access.set'''. This is a little more convenient when working with global WML variables rather than unit or side variables.<br />
<br />
=== wml.eval_conditional ===<br />
<br />
* {{LuaGameOnly}} '''wml.eval_conditional'''(''conditional_tags'') &rarr; ''boolean''<br />
<br />
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.<br />
<br />
<syntaxhighlight lang=lua><br />
local result = wml.eval_conditional {<br />
wml.have_unit { id = "hero" },<br />
wml.variable { name = "counter", numerical_equals = "$old_counter" }<br />
}<br />
</syntaxhighlight><br />
<br />
Note: Prior to 1.15.13, this was available as '''wesnoth.eval_conditional'''.<br />
<br />
=== wml.fire ===<br />
<br />
* {{LuaGameOnly}} '''wml.fire'''(''tag'', ''parameters'')<br />
* {{DevFeature1.17|17}} {{LuaGameOnly}} '''wml.fire'''.''tag''(''parameters'')<br />
<br />
Fire a WML action tag. Note: WML variables are substituted into the parameters table.<br />
<br />
Note: Prior to 1.15.13, this was available as '''wesnoth.fire'''. The second form was available through '''helper.set_wml_action_metatable'''.<br />
<br />
=== wml.error ===<br />
<br />
* {{LuaGameOnly}} '''wml.error'''(''message'')<br />
<br />
Interrupts the current execution and displays a WML error message. This is intended for error messages in the implementaton of custom ActionWML or ConditionalWML tags. For errors in a Lua API, the built-in '''error''' function is a more suitable choice.<br />
<br />
<syntaxhighlight lang=lua><br />
local names = cfg.name or wml.error("[clear_variable] missing required name= attribute.")<br />
</syntaxhighlight><br />
<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=EffectWML&diff=68063EffectWML2021-06-12T09:55:36Z<p>Vasya: Add information about a bug in permanent image_mod effect</p>
<hr />
<div>{{WML Tags}}<br />
<br />
=== [effect] ===<br />
<br />
The tag [effect] is used to describe one modification to a unit. Any number of [effect] tags can be used to describe a complete modification.<br />
<br />
Modifications are permanent changes to a unit; however using an [[DirectActionsWML#.5Bobject.5D|[object]]] with a limited ''duration'' to apply an [effect] will cause the unit to be rebuilt without the effect's effects when the duration expires. <br />
<br />
The following keys and subtags are always recognized:<br />
* '''[filter]''': only apply this effect if the affected unit matches. See [[StandardUnitFilter]] for details.<br />
* '''times''': describes how many times the effect is applied. The default is to apply the effect once. Other possible value : "per level" which means that the effect is applied level times, where level is the unit level. {{DevFeature1.13|5}} Integers are now supported for ''times''.<br />
* '''apply_to''': describes what the effect actually affects. New effect types can be added with [[LuaWML/Units#wesnoth.effects]].<br />
[effect] uses different keys depending on the value of '''apply_to'''. '''apply_to''' can take the following values:<br />
* '''new_attack''': will use all other keys and tags as the description of an attack that will be added to the unit. See [attack] in [[UnitTypeWML#Attacks|UnitTypeWML]].<br />
* '''remove_attacks''': remove the matching attacks. All tags from the attack filter construct will be used to match the attack; see [[FilterWML#Filtering Weapons|FilterWML]]. Do not use a [filter] tag otherwise it will not work properly.<br />
* '''attack''': find an attack and modify it. All tags from the attack filter construct will be used to match the attack; see [[FilterWML#Filtering Weapons|FilterWML]]. After that, the following keys and tags can be used to modify the attack. Note: do not use a [filter] tag. Just put the keys you want to filter on inside the [effect] tag.<br />
** '''set_name''': change the attack's name (ie identifier).<br />
** '''set_description''': change the attack's description (ie displayed name). <br />
** '''set_type''': change the attack type. The standard values are '''blade''', '''pierce''', '''impact''', '''fire''', '''cold''', and '''arcane'''.<br />
** '''set_range''': change the attack range. The standard values are '''ranged''' and '''melee'''.<br />
** '''set_icon''': change the attack's icon.<br />
** '''[set_specials]''': change the attack's specials. The specials to add are given exactly as in the [[AbilitiesWML#The_.5Bspecials.5D_tag|[specials]]] tag.<br />
*** '''mode''': if '''append''', adds the given specials to the attack. If '''replace''', replaces the existing specials with the given ones. Default '''replace'''.<br />
**** {{DevFeature1.15|3}} A deprecation warning is triggered unless the '''mode''' attribute is set, although the effect will still be '''replace'''. This is to allow the default to change in the 1.17.x series.<br />
** '''remove_specials''': remove the listed specials. The value of this key is the comma-separated list of the id of the specials to remove. This key is always evaluated before a [set_specials] tags in the same [effect]<br />
** '''increase_damage''': increases the attack's damage. This can be positive or negative, so you can use it to decrease damage as well. If it ends in a percent(''''%''''), the change in damage will be a percentage ratio of the attack's original damage.<br />
** '''increase_attacks''': increases the number of attack strikes. Like '''increase_damage''', it can be positive or negative, or a percentage.<br />
** '''increase_accuracy''': increases the attack accuracy; can be positive or negative, or a percentage<br />
** '''increase_parry''': increases the attack parry bonus; can be positive or negative, or a percentage<br />
** '''increase_movement_used''': {{DevFeature1.13|2}} increases the movement points used by the attack; can be positive or negative, or a percentage<br />
** '''set_damage''' {{DevFeature1.13|2}} like increase_damage, but sets the damage to a specific value instead of setting it relative to its original value<br />
** '''set_attacks''' {{DevFeature1.13|2}} like increase_attacks, but sets the attacks to a specific value instead of setting it relative to its original value<br />
** '''set_accuracy''' {{DevFeature1.13|2}} like increase_accuracy, but sets the accuracy to a specific value instead of setting it relative to its original value<br />
** '''set_parry''' {{DevFeature1.13|2}} like increase_parry, but sets the parry to a specific value instead of setting it relative to its original value<br />
** '''set_movement_used''' {{DevFeature1.13|2}} like increase_movement_used, but sets the movement used to a specific value instead of setting it relative to its original value<br />
** '''attack_weight''': change the attack's attack_weight. See [attack] in [[UnitTypeWML#Attacks|UnitTypeWML]] for explanations about attack_weight.<br />
** '''defense_weight''': change the attack's defense_weight. See [attack] in [[UnitTypeWML#Attacks|UnitTypeWML]] for explanations about defense_weight.<br />
* '''max_attacks''': {{DevFeature1.13|2}} change the unit's maximum attacks per turn<br />
** '''increase''': how much to increase by; can be positive or negative, or a percentage<br />
* '''hitpoints''': modifies the unit's HP and/or max HP.<br />
** '''increase''': the amount to increase the unit's HP.<br />
** '''heal_full''': if present and not set to "no" the unit will be put back to full HP.<br />
** '''increase_total''': will increase the total HP of the unit. Can be specified either as a negative or a positive value. It can also be specified as a percentage of the current total; i.e. "-50%" will cut max HP in half.<br />
** '''violate_maximum''': it the unit ends up with more than its max HP after these modifications, and this key is present (set to any non-null value, ex. '''yes'''), the unit's HP won't be lowered to its max HP.<br />
* '''movement''': modifies the unit's movement points.<br />
** '''increase''': maximum movement is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': maximum movement is set to a specific value.<br />
** '''apply_to_vision''': {{DevFeature1.15|13}} if set to '''yes''' (which is the default), then the vision points will change by the same amount. See [[#Movement_and_Vision|Movement and Vision]].<br />
* '''vision''': {{DevFeature1.13|2}} modifies the unit's vision points. Note: this has side effects described in [[#Movement_and_Vision|Movement and Vision]].<br />
** '''increase''': maximum vision is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': maximum vision is set to a specific value. <br />
* '''jamming''': {{DevFeature1.13|2}} modifies the unit's jamming points.<br />
** '''increase''': maximum jamming is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': maximum jamming is set to a specific value.<br />
* '''experience''': affects the unit's current XP.<br />
** '''increase''': current XP is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': current XP is set to a specific value.<br />
* '''max_experience''': affects the amount of XP the unit needs for the next level.<br />
** '''increase''': how to change the xp; again it can be negative, positive or a percentage.<br />
* '''loyal''': no keys associated. The affected unit will be loyal i.e have an upkeep of 0.<br />
* '''movement_costs''': speed through specific terrain is modified<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).<br />
** '''[movement_costs]''': a subtag that describes the new movement costs just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''vision_costs''': vision through specific terrain is modified<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).<br />
** '''[vision_costs]''': a subtag that describes the new vision costs just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''jamming_costs''': jamming through specific terrain is modified<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).<br />
** '''[jamming_costs]''': a subtag that describes the new jamming costs just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''defense''': Sets the unit's chance to be hit in specific terrain (100 - the unit's defense as shown in-game). <br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values. In most cases, adding a positive number makes the unit easier to hit, while adding a negative number makes the unit harder to hit. The new value is added to the absolute value of the old, and the sign of the old value is preserved.<br />
** '''[defense]''': a subtag that describes the new defense just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''resistance''': Sets percent damage taken from combat (100 - the unit's resistance as shown in-game)<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values. Adding a positive number makes the unit take more damage, while adding a negative number makes the unit take less damage.<br />
** '''[resistance]''': a subtag that describes the new resistance just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''variation''': switches the unit into one of its variations. Similar to the '''type''' effect below, this might not behave properly outside of [advancement], and cannot be combined with '''type''' in the same object due to a bug.<br />
** '''name''': the id of the variation to invoke. <br />
* '''type''': transforms the unit into a new unit_type. This does not work in [trait]; in ActionWML it's recommended to use [transform_unit] instead of an [object] with this effect. This effect cannot be undone with [remove_object].<br />
** '''name''': the id of the unit_type to invoke.<br />
* '''status''': modifies the status affecting the unit.<br />
** '''add''': a list of status modifications to add. Beware, these may be reapplied later, such as when the unit is recalled or levels up; if in an event, you can use [[InternalActionsWML|[store_unit]]] and [[DirectActionsWML|[unstore_unit]]], modifying unit.status.name directly, to avoid this, or if you are creating the unit, you can just add it to the unit's [status] tag in the [unit] tag. These are listed in [status], [[SingleUnitWML]].<br />
** '''remove''': a list of status modifications to remove.<br />
* '''zoc''': toggle the zone of control.<br />
** '''value''': new value for zoc (boolean).<br />
* '''profile''': customize the profile of the unit. See [[UnitTypeWML]].<br />
** '''portrait''': new image to display when the unit speaks.<br />
** '''small_portrait''': new image to display in unit reports.<br />
** '''description''': sets the text to display when hovering over the unit's type in the righthand pane.<br />
** '''[special_note]''': {{DevFeature1.15|2}} Adds or removes a special note in the unit's description.<br />
*** '''remove''': A boolean value specifying whether to add or remove a note. Defaults to '''no'''.<br />
*** '''note''' (translatable): The text of the note you want to add or remove. If removing a note, this must be an exact match, character-for-character, for the note you want to remove, and must also be in the same textdomain.<br />
*** Since the tag name is the same, notes can also be added using the standard special note macros, eg '''{NOTE_HEALS}'''.<br />
*** To remove a note, you can simply suffix '''{NOTE_REMOVE}''' to the regular note macro, eg '''{NOTE_HEALS}{NOTE_REMOVE}'''.<br />
* '''new_ability''': Adds one or more abilities to a unit.<br />
** '''[abilities]''': A subtag that contains the ability definitions.<br />
* '''remove_ability''': Removes one or more abilities from a unit. Abilities are not reference counted: added, added, removed = gone.<br />
** '''[abilities]''': A subtag that contains the ability definitions. Strictly speaking, all that is needed is the id= inside some tag.<br />
* '''new_animation''': contain animations that will be added to the unit, it can contain multiple animation blocks, and a single "id=" line. That Id should be unique for each effect block and is used by the engine to reuse WML parsing, making the loading faster. <br />
* '''image_mod''': modify the image path function ([[ImagePathFunctions]]) of all the unit's frames. Due to a bug, the effect is permanent even inside [object]duration=turn<br />
** '''replace''': replaces the image path function(s) to be used, e.g. "RC(magenta>red)"<br />
** '''add''': adds an image path function without removing any existing ones.<br />
** If needed, you can also define new [[GameConfigWML#Color_Palettes|color palettes]] here.<br />
* '''ellipse''': Change the image used for the unit's ellipse.<br />
** '''ellipse''' : the new image to use. Can be set to "none" to disable the ellipse.<br />
* '''halo''': Change the image used for the unit's halo.<br />
** '''halo''': the new image to use.<br />
* '''overlay''': Change the unit's overlays.<br />
**'''add''': the specified overlay will be added to the unit's overlays. It can be a comma separated list with multiple overlays. ''Note: overlays added in this way cannot be removed by [remove_unit_overlay] until the effect's duration is over.''<br />
**'''replace''': all the unit's overlays will be removed and replaced with the specified one. Again, it can be a comma separated list. ''Note: overlays replaced in this way cannot be modified by [unit_overlay] or [remove_unit_overlay] until the effect's duration is over.''<br />
**'''remove''': {{DevFeature1.15|0}} the specified overlay will be removed from the unit's overlays. It can be a comma separated list with multiple overlays.<br />
** {{DevFeature1.15|0}} [unit_overlay] and [remove_unit_overlay] are now equivalent to adding a permanent object with this effect, after checking if the unit already has / already doesn't have the overlay (effects with temporary durations will cause false positives / false negatives in this check).<br />
* '''recall_cost''': {{DevFeature1.13|2}} change a unit's recall cost<br />
** '''set''': set recall cost to a specific value, or a percentage of original value<br />
** '''increase''': alter recall cost relative to original value; can be positive or negative, or a percentage<br />
* '''alignment''': {{DevFeature1.13|2}} change a unit's alignment<br />
** '''set''': the new alignment (one of chaotic, lawful, neutral, liminal)<br />
* '''new_advancement''': {{DevFeature1.13|2}} add new advancement choices to the unit<br />
** '''replace''': whether to replace existing advancement choices; if this key is set to yes, existing advancement choices are cleared only if you're adding a choice of the same type. (That is, unit type advancements are cleared only if you're adding a new unit advancement choice, and AMLA choices are cleared only if you're adding new AMLA choices.)<br />
** '''types''': a comma-separated list of additional unit types the unit can advance to. ('''Note:''' If using this, you probably want to include a filter to prevent the unit from being able to advance to this type once it has already done so.)<br />
** '''[advancement]''': an advancement choice to add, see [[UnitTypeWML#After_max_level_advancement_(AMLA)|AMLAs]]; you can have several of these tags to add multiple advancement choices at the same time.<br />
* '''remove_advancement''': {{DevFeature1.13|2}} remove existing advancement choices from the unit<br />
** '''types''': a list of unit type advancements to remove as a possibility<br />
** '''amlas''': a list of AMLA id attributes; any advancement possibility with the given id will be removed<br />
<br />
=== Movement and Vision ===<br />
<br />
Wesnoth 1.14 introduced vision points; by default units have the same number of vision points as their max movement points. However, combining effects that change vision with effects that change movement had edge cases which were reworked in 1.16:<br />
<br />
Consider a unit with 5 mp, and default vision:<br />
* It has (effectively) 5 mp and 5 vp.<br />
* After (mp + 1), it will have 6 mp and 6 vp.<br />
* After (vp + 2), it will have 5 mp and 7 vp.<br />
<br />
In 1.14, using an effect with apply_to=vision breaks the link between vision and movement:<br />
* After (mp + 1) (vp + 2), it will have 6 mp and 8 vp.<br />
* After (vp + 2) (mp + 1), it will have 6 mp and 7 vp.<br />
<br />
{{DevFeature1.15|13}}, [effect]apply_to=movement has another attribute apply_to_vision, which defaults to true. With that change, the order that the effects are applied in doesn't matter:<br />
* After (mp + 1) (vp + 2), it will have 6 mp and 8 vp.<br />
* After (vp + 2) (mp + 1), it will have 6 mp and 8 vp.<br />
<br />
Increasing movement by 50% increases vision by (50% of movement) not by (50% of vision). For a unit that started with 6 mp and 8 vp, the following effect would give it 9 mp and 11 vp.<br />
[effect]<br />
apply_to=movement<br />
increase=50%<br />
[/effect]<br />
<br />
=== Examples ===<br />
== Effect: apply_to = new_animation ==<br />
This is the only way to change animations of units after they have been placed on the map.<br />
In this example, I add very simple idle animation (taken from Goblin Spearman) to the unit, which moves to hex (x=1, y=5). If you want something more complex, you need to check [[AnimationWML]] page.<br />
<br />
[event]<br />
name = moveto<br />
[filter]<br />
x,y = 1,5<br />
[/filter]<br />
[object]<br />
[filter]<br />
x,y = 1,5<br />
[/filter]<br />
[effect]<br />
apply_to = new_animation<br />
[idle_anim]<br />
{STANDARD_IDLE_FILTER}<br />
start_time=0<br />
[frame]<br />
image="units/goblins/spearman-idle-[1~12].png:[150*3,300,150*8]"<br />
[/frame]<br />
[/idle_anim]<br />
[/effect]<br />
[/object]<br />
[/event]<br />
<br />
If you are going to use '''advanced WML''' and want to add animation to unit, stored in variable, then following example might help you. '''This way is not efficient if you have no additional logic like inventoriy, shops, advanced unit modifications in your add-on.''' Is is preferred to use first variant or define all needed animation in unit_type.<br />
[event]<br />
name = moveto<br />
[filter]<br />
x,y = 1,5<br />
[/filter]<br />
[store_unit]<br />
[filter]<br />
x,y=1,5<br />
[/filter]<br />
variable = stored_unit<br />
[/store_unit]<br />
[set_variables]<br />
name = stored_unit.modifications.object<br />
[value]<br />
[effect]<br />
apply_to = new_animation<br />
[idle_anim]<br />
{STANDARD_IDLE_FILTER}<br />
start_time=0<br />
[frame]<br />
image="units/goblins/spearman-idle-[1~12].png:[150*3,300,150*8]"<br />
[/frame]<br />
[/idle_anim]<br />
[/effect]<br />
[/value]<br />
[/set_variables]<br />
[unstore_unit]<br />
variable = stored_unit<br />
[/unstore_unit]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[UnitTypeWML]]<br />
* [[ReferenceWML]]<br />
* [[AnimationWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Units&diff=68022LuaWML/Units2021-06-05T20:53:20Z<p>Vasya: Fix formatting /* wesnoth.unit_movement_cost */</p>
<hr />
<div>{{Template:LuaMove}}<br />
<br />
<div class="tright"> __TOC__ </div><br />
<br />
This page describes the [[LuaWML]] functions for handling units.<br />
<br />
A unit is a proxy table with the following fields:<br />
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map. {{DevFeature1.13|11}} These are now read/write under all circumstances, including for on-map units)<br />
* '''loc''': {{DevFeature1.13|11}} shortcut to get/set both x and y at once (read/write). Setting x and y individually would result in two moves, and there's the possibility that the intermediate move fails if the hex is occupied by another unit. In general, note that moving a unit by changing the proxy unit's coordinates does not work if the goal hex is occupied (it is not executed), so it is necessary to check if the hex is available first.<br />
* '''side''': integer (read/write)<br />
* '''id''': string (read only)<br />
* '''type''': string (read only)<br />
* '''name''': translatable string (read only)<br />
* '''cost''' {{DevFeature1.13|10}}: integer (read)<br />
* '''max_hitpoints''', '''max_experience''', '''max_moves''': integers (read only)<br />
* '''max_attacks''': integer (read only)<br />
* '''attacks_left''': integer (read/write) Setting below 0 is limited to 0.<br />
* '''extra_recruit''': table (read/write)<br />
* '''advances_to''': table (read/write)<br />
* '''hitpoints''', '''experience''': integer (read/write)<br />
* '''moves''': integer (read/write)<br />
* '''level''': {{DevFeature1.13|5}} integer (read/write)<br />
* '''resting''': boolean (read/write)<br />
* '''hidden''': boolean (read/write)<br />
* '''petrified''', '''canrecruit''': booleans (read only)<br />
* '''role''', '''facing''': strings (read/write)<br />
* '''status''': proxy associative table (read only, read/write fields), provides fields like [[SingleUnitWML#Unit_State|poisoned, slowed, petrified, uncovered, guardian, unhealable, invulnerable]]<br />
* '''image_mods''': string (read only)<br />
* '''upkeep''' {{DevFeature1.13|5}}: one of 'loyal', 'full' or a number (read/writre)<br />
* '''variables''': proxy associative table (read only, read/write fields, including ''variables.__cfg''), only toplevel named fields are proxied. {{DevFeature1.13|2}} subcontainers can be accessed by using the usual variable syntax: <syntaxhighlight inline lang='lua'>unit.variables["a.b.c[6].d"]</syntaxhighlight><br />
* '''attacks''': {{DevFeature1.13|0}}an object to access the units attacks, you can use the attacks index or the attacks name to index an attack. every attack has the following members:<br />
** '''description''': translatable string (read/write)<br />
** '''name''': string (read)<br />
** '''type''': string (read/write)<br />
** '''range''': string (read/write)<br />
** '''damage''': number(read/write)<br />
** '''number''': number(read/write)<br />
** '''movement_used''': number(read/write)<br />
** '''attack_weight''': number(read/write)<br />
** '''defense_weight''': number(read/write)<br />
** '''specials''' wml table(read/write)<br />
* '''valid''': string or nil (read only)<br />
* '''advancements''': {{DevFeature1.13|2}} an array of wml tables (read/write)<br />
* '''__cfg''': WML table (dump) ([[SingleUnitWML]])<br />
* {{DevFeature1.13|2}} The following fields are unit methods synonymous to one of the functions described on this page:<br />
** '''[[#wesnoth.match_unit|matches]]'''<br />
** '''[[#wesnoth.put_recall_unit|to_recall]]'''<br />
** '''[[#wesnoth.put_unit|to_map]]'''<br />
** '''[[#wesnoth.erase_unit|erase]]'''<br />
** '''[[#wesnoth.copy_unit|clone]]'''<br />
** '''[[#wesnoth.extract_unit|extract]]'''<br />
** '''[[#wesnoth.advance_unit|advance]]'''<br />
** '''[[#wesnoth.add_modification|add_modification]]'''<br />
** '''[[#wesnoth.remove_modifications|remove_modifications]]'''<br />
** '''[[#wesnoth.unit_resistance|resistance]]'''<br />
** '''[[#wesnoth.unit_defense|defense]]'''<br />
** '''[[#wesnoth.unit_movement_cost|movement]]'''<br />
** '''[[#wesnoth.unit_vision_cost|vision]]'''<br />
** '''[[#wesnoth.unit_jamming_cost|jamming]]'''<br />
** '''[[#wesnoth.unit_ability|ability]]'''<br />
** '''[[#wesnoth.transform_unit|transform]]'''<br />
The metatable of these proxy tables appears as '''"unit"'''.<br />
<br />
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same "underlying_id" WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''"map"''', '''"recall"''', '''"private"''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.<br />
<br />
The term "proxy", here in particular "proxy unit", means that the variable retrieved in the lua code (with get_units for example) is an accessor (reference) to the C++ object which represents that unit. This is very different from unit variables obtained by [store_unit] in wml. The fields marked as "writable" above can be modified without the need to use put_unit afterwards. This same reason explains that modifications to the unit from outside the lua code (like [kill] invalidating the proxy unit) have immediate effect on the lua code's proxy unit variable (with the exception of private proxy units).<br />
<br />
==== wesnoth.get_units ====<br />
<br />
* '''wesnoth.get_units(''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_units(''filter'', ''fake_location'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_units(''filter'', ''other_unit'')'''<br />
<br />
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters. If a second unit is passed, it can be referenced via the $other_unit variable in the main filter as well as via the "other" variable in WFL formulas used in the main filter. If a location is passed, the filter is run as if the unit were at that location (rather than its real location). This affects things such as [filter_adjacent] and ability_active, and should work even for a unit on the recall list.<br />
<br />
<syntaxhighlight lang='lua'><br />
local leaders_on_side_two = wesnoth.get_units { side = 2, canrecruit = true }<br />
local name_of_leader = leaders_on_side_two[1].name<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_unit ====<br />
<br />
* '''wesnoth.get_unit(''x'', ''y'')'''<br />
* '''wesnoth.get_unit(''id'')'''<br />
<br />
Returns the unit at the given location or with the given ID.<br />
<br />
<syntaxhighlight lang='lua'><br />
local args = ...<br />
local unit = wesnoth.get_unit(args.x1, args.y1)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.match_unit ====<br />
<br />
* '''wesnoth.match_unit(''unit'', ''filter'')'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''other_unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''other_unit''])'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''location'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''location''])'''<br />
<br />
Returns true if the given unit matches the WML filter passed as the second argument. If ''other_unit'' is specified, it is used for the ''$other_unit'' auto-stored variable in the filter. Otherwise, this variable is not stored for the filter. If an extra ''location'' is specified, the filter matches as if the unit were at that location.<br />
<br />
<syntaxhighlight lang='lua'><br />
assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.put_unit ====<br />
<br />
* '''wesnoth.put_unit(''unit'')'''<br />
* '''wesnoth.put_unit(''x'', ''y'', ''unit'')''' -- Deprecated in {{DevFeature1.13|2}}, removed in {{DevFeature1.15|0}}<br />
* '''wesnoth.put_unit(''x'', ''y'')''' -- Deprecated in {{DevFeature1.13|2}}, removed in {{DevFeature1.15|0}}<br />
* {{DevFeature1.13|2}} '''wesnoth.put_unit(''unit'', ''x'', ''y'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':to_map([''x'', ''y''])<br />
<br />
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead. {{DevFeature1.13|2}} This use is now deprecated; use wesnoth.erase_unit instead.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- create a unit with random traits, then erase it<br />
wesnoth.put_unit(17, 42, { type = "Elvish Lady" })<br />
wesnoth.put_unit(17, 42)<br />
</syntaxhighlight><br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- move the leader back to the top-left corner<br />
wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])<br />
</syntaxhighlight><br />
<br />
If x,y is a village, this function does not capture it (as of 1.14). Use [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner(x, y, unit.side)]] if that's what you want.<br />
<br />
'''Caution:''' Using this function will trigger unit placed events. While this may be correct in most cases, there are some cases where it shouldn't, especially if the code is inside the definition of a custom WML tag — it would be an unexpected side-effect from the users point. To work around this, ''false'' can be passed additionally as the last argument. This is what is used internally for some tags such as [move_unit], [harm_unit], [unpetrify] or the feeding ability and is not officially part of the API.<br />
<br />
==== wesnoth.erase_unit ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
* '''wesnoth.erase_unit(''unit'')'''<br />
* '''wesnoth.erase_unit(''x'', ''y'')'''<br />
* '''''unit'':erase()'''<br />
<br />
Erases a unit from the map. After calling this on a unit, the unit is no longer valid.<br />
<br />
==== wesnoth.get_recall_units ====<br />
<br />
* '''wesnoth.get_recall_units()'''<br />
<br />
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.<br />
<br />
==== wesnoth.put_recall_unit ====<br />
<br />
* '''wesnoth.put_recall_unit(''unit'', [''side''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':to_recall([''side''])'''<br />
<br />
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- put the unit at location 17,42 on the recall list for side 2<br />
wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)<br />
</syntaxhighlight><br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.<br />
<br />
==== wesnoth.create_unit ====<br />
<br />
* '''wesnoth.create_unit(''unit_info'')'''<br />
<br />
Creates a private unit from a WML table.<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.create_unit { type = "White Mage", gender = "female" }<br />
</syntaxhighlight><br />
<br />
==== wesnoth.copy_unit ====<br />
<br />
* '''wesnoth.copy_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':clone()'''<br />
<br />
Creates a private unit from another unit.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- extract a unit from the map<br />
local u = wesnoth.copy_unit(wesnoth.get_units({ type = "Thug" })[1])<br />
wesnoth.erase_unit(u.x, u.y)<br />
-- u is still valid at this point<br />
</syntaxhighlight><br />
<br />
==== wesnoth.extract_unit ====<br />
<br />
* '''wesnoth.extract_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':extract()'''<br />
<br />
Removes a unit from the map or from a recall list and makes it private.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- remove all the units from the recall list of side 1 and put them in a WML container<br />
local l = {}<br />
for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do<br />
wesnoth.extract_unit(u)<br />
table.insert(l, u.__cfg)<br />
end<br />
helper.set_variable_array("player_recall_list", l)<br />
</syntaxhighlight><br />
<br />
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.<br />
<br />
<br />
==== wesnoth.advance_unit ====<br />
<br />
* '''wesnoth.advance_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':advance()'''<br />
<br />
{{DevFeature1.13|0}} Advances the unit (and shows the advance unit dialog if needed) if the unit has enough xp. This function should be called after modifying the units experience directly. A similar function is called by wesnoth internally after unit combat. The second argument is a boodean value that specifies whether the advancement should be animated. The third agrument is a boodean value that specifies whether advancement related events should be fired.<br />
<br />
<br />
This function only works for units on the map.<br />
<br />
This function can also trigger multiple advancements if the unit has enough xp.<br />
<br />
==== wesnoth.add_modification ====<br />
<br />
* '''wesnoth.add_modification(''unit'', ''type'', ''effects'', [''write_to_mods''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':add_modification(''type'', ''effects'', [''write_to_mods''])'''<br />
<br />
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (one of "trait", "object", or "advance"). The option "advance" applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.<br />
<br />
{{DevFeature1.13|2}} In 1.13.2 and later, the "advance" type is replaced with "advancement", to match the equivalent tag in [[UnitTypeWML|[unit_type]]]. Also, it takes a fourth argument which, if false, causes it to not write the modification tag to the unit's [modifications] (as would be done with an [object] with no_write=true).<br />
<br />
<syntaxhighlight lang='lua'><br />
local T = wml.tag<br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
local effects = {<br />
id = "my_effect_id",<br />
T.effect { <br />
apply_to = "image_mod", <br />
replace = "RC(red>blue)" <br />
},<br />
T.effect {<br />
apply_to = "new_animation",<br />
T.standing_animation {<br />
-- AnimationWML<br />
}<br />
}<br />
} <br />
wesnoth.add_modification(u, "object", effects)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.remove_modifications ====<br />
<br />
* {{DevFeature1.13|?}} '''wesnoth.remove_modifications(''unit'', ''cfg'' [, ''type''])'''<br />
* {{DevFeature1.13|?}} '''''unit'':remove_modifications(''cfg'' [, ''type''])'''<br />
<br />
Modifies a given unit. The unit needs to be a proxy unit. The second argument is a filter for the modifications to remove. It takes the same syntax as [[FilterWML#Filtering_on_WML_data|[filter_wml]]]; all matching modifications will be removed. The third argument is the type (tag name) of the modifications to search for; it defaults to <tt>"object"</tt>, but you can also pass <tt>"trait"</tt> or <tt>"advancement"</tt>.<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
wesnoth.remove_modifications(u, { id = "my_effect_id" })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_resistance ====<br />
<br />
* '''wesnoth.unit_resistance(''unit'', ''damage_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':resistance(''damage_type'')'''<br />
<br />
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).<br />
<br />
<syntaxhighlight lang='lua'><br />
local fire_resistance = 100 - wesnoth.unit_resistance(u, "fire")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_defense ====<br />
<br />
* '''wesnoth.unit_defense(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':defense(''terrain_code'')'''<br />
<br />
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)<br />
<br />
<syntaxhighlight lang='lua'><br />
local flat_defense = 100 - wesnoth.unit_defense(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_movement_cost ====<br />
<br />
* '''wesnoth.unit_movement_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':movement(''terrain_code'')'''<br />
<br />
Returns the movement cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local move_cost = wesnoth.unit_movement_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_vision_cost ====<br />
<br />
* '''wesnoth.unit_vision_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':vision(''terrain_code'')'''<br />
<br />
Returns the vision cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local see_cost = wesnoth.unit_vision_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_jamming_cost ====<br />
<br />
* '''wesnoth.unit_jamming_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':jamming(''terrain_code'')'''<br />
<br />
Returns the jamming cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local jam_cost = wesnoth.unit_jamming_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_ability ====<br />
<br />
* '''wesnoth.unit_ability(''unit'', ''ability_tag'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':ability(''ability_tag'')'''<br />
<br />
Returns true if the unit is currently under effect by an ability with this given TAG NAME. This means that the ability could be owned by the unit itself, or by an adjacent unit.<br />
<br />
<syntaxhighlight lang='lua'><br />
function has_teleport(u)<br />
return wesnoth.unit_ability(u, "teleport")<br />
end<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_types ====<br />
<br />
This is not a function but a read-only table indexed by unit type ids. Its elements are proxy tables with these fields:<br />
<br />
* '''id''': string<br />
* '''name''': translatable string (read only)<br />
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)<br />
* '''abilities''': array of ability keys (strings), e.g. {"curing", "regenerates"}<br />
* {{DevFeature1.13|11}} '''advances_to''': array of unit types to which unit can advance<br />
* {{DevFeature1.13|11}} '''advances_from''': array of unit types from which unit can advance. Note: this is OOS-unsafe in Multiplayer games. Different clients may have additional Era-s with units upgradable to this unit type.<br />
* '''__cfg''': WML table (dump), see [[UnitTypeWML]]<br />
<br />
The metatable of these proxy tables appears as '''"unit type"'''.<br />
<br />
<syntaxhighlight lang='lua'><br />
local lich_cost = wesnoth.unit_types["Ancient Lich"].cost<br />
</syntaxhighlight><br />
<br />
Note that different clients have different set of available units in a Multiplayer game. It is OOS-unsafe to e.g. count the number of units.<br />
Presuming correctly written add-ons, it is still safe to e.g. access any given unit or its properties.<br />
<br />
==== wesnoth.races ====<br />
<br />
This is not a function but a table indexed by race ids. Its elements are proxy tables for all races the engine knows about.<br />
known fields of each element:<br />
* '''id''': string<br />
* '''description''', '''name''', '''plural_name''' (translatable strings)<br />
* '''num_traits''' (integer)<br />
* '''ignore_global_traits''' (boolean)<br />
* '''undead_variation''' (string)<br />
(all read only)<br />
* '''__cfg''': WML table (dump)<br />
<br />
<syntaxhighlight lang='lua'><br />
wesnoth.message(tostring(wesnoth.races["lizard"].name))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_traits ====<br />
<br />
* '''wesnoth.get_traits()'''<br />
<br />
Returns a table with named fields (trait id strings) holding the wml tables defining the traits. arguments: none. All global traits the engine knows about, race-specific traits are not included.<br />
Known fields and subtags of each element are the ones which were given in the wml definition of the [[SingleUnitWML|trait]].<br />
wesnoth.message(tostring(wesnoth.get_traits().strong.male_name))<br />
<br />
==== wesnoth.simulate_combat ====<br />
<br />
* '''wesnoth.simulate_combat(''attacker'', [''attacker_weapon_index''], ''defender'', [''defender_weapon_index''])'''<br />
<br />
Computes the hitpoint distribution and status chance after a combat between two units. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.<br />
<br />
Optional integers can be passed after each unit to select a particular weapon, otherwise the "best" one is selected. When giving the weapon, the parameter is the weapon number (integer, starting at 1) and not an element from the table returned by helper.child_range(att, "attack").<br />
<br />
<syntaxhighlight lang='lua'><br />
local function display_stats(n, t)<br />
wesnoth.message(string.format(<br />
"Chance for the %s\n to be slowed: %f,\n to be poisoned: %f,\n to die: %f.\nAverage HP: %f.",<br />
n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))<br />
end<br />
local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def, def_weapon)<br />
display_stats("attacker", att_stats)<br />
display_stats("defender", def_stats)<br />
</syntaxhighlight><br />
<br />
Returns 2 additional tables which contain information about the weapons and the effect of single hits with these keys: num_blows, damage, chance_to_hit, poisons, slows, petrifies, plagues, plague_type, backstabs, rounds, firststrike, drains, drain_constant, drain_percent, attack_num, name. <br />
Name is the wml name not the description. If there is no weapon, then name will be nil<br />
<br />
<syntaxhighlight lang='lua'><br />
local att_stats, def_stats, att_weapon, def_weapon = wesnoth.simulate_combat(attacker, att_weapon_number, defender)<br />
wesnoth.message(string.format(<br />
"The attack %s should be countered with %s, which does %d damage, has %d%% chance to hit and forces %d attack rounds due to its berserk ability.",<br />
att_weapon.name, def_weapon.name or "no weapon", def_weapon.damage, def_weapon.chance_to_hit, def_weapon.rounds))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.transform_unit ====<br />
<br />
* '''wesnoth.transform_unit(''unit'', ''to_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':transform(''to_type'')'''<br />
<br />
Changes the type of a unit and adjust attributes accordingly. Note that hit points are only changed if necessary to accommodate the new maximum hit points. Poison is automatically removed if the transformed unit is immune.<br />
<br />
<syntaxhighlight lang='lua'><br />
local ev = wesnoth.current.event_context<br />
local u = wesnoth.get_units{x=ev.x1, y=ev.y1}[1]<br />
wesnoth.transform_unit(u, "Spearman")<br />
-- If a full heal is desired:<br />
u.hitpoints = u.max_hitpoints<br />
u.status.poisoned = false<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_known_unit ====<br />
<br />
* {{DevFeature1.13|10}} '''wesnoth.add_known_unit(''unit_type_id'')'''<br />
<br />
adds the unit type with the given id to the list of known units (so that they appear in the help)<br />
<br />
==== wesnoth.create_animator ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.create_animator()'''<br />
<br />
Returns an object that can be used to set up and run an animation. The object has three methods:<br />
<br />
* '''animator:run()'''<br />
<br />
Runs the animation. {{DevFeature1.15|0}} Implicitly clears the animator.<br />
<br />
* '''animator:clear()'''<br />
<br />
Clears any units previously added to the animation.<br />
<br />
* '''animator:add(''unit'', ''flag'', ''hits'', ''params'')'''<br />
<br />
Adds a unit to the animation. The ''flag'' specifies which animation to play, and the ''hits'' parameter is required for attack animations to specify which variant of the animation to play. Possibly keys in ''params'' are:<br />
<br />
* '''facing''': A location. The animation will be played with the unit facing that location.<br />
* '''value''': Either a number or a list of two numbers. Use this to pass ''value'' and/or ''value_second'' to default animations that use them.<br />
* '''with_bars''': Whether to show HP bars and such while the animation plays.<br />
* '''text''': Text to float as the animation plays.<br />
* '''color''': Color of the floating text - a list of red, green, blue.<br />
* '''primary''': The primary weapon to use for the animation. Must be a Lua unit attack proxy.<br />
* '''secondary''': The secondary weapon to use for the animation.<br />
<br />
Normal usage would be to create it, call '''add''' one or more times, then call '''run'''.<br />
<br />
==== wesnoth.effects ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
This table contains the implementation of custom [[EffectWML|[effect]]]s. Each value is a function that takes a unit and the effect config. Note that the default effects defined by the Wesnoth engine are not in this table. <br />
<br />
<syntaxhighlight lang='lua'><br />
function wesnoth.effects.min_resistance(u, cfg)<br />
local resistance_new = {}<br />
local resistance_old = helper.parsed(helper.get_child(cfg, "resistance"))<br />
for k,v in pairs(resistance_old) do<br />
if type(k) == "string" and type(v) == "number" and wesnoth.unit_resistance(u, k) >= v then<br />
resistance_new[k] = v<br />
end<br />
end<br />
--important: use wesnoth.add_modification(..., false) so that the function will only execute the effects of that object and not store the object in the unit.<br />
wesnoth.add_modification(u, "object", {<br />
T.effect {<br />
apply_to = "resistance",<br />
replace = true,<br />
T.resistance (resistance_new),<br />
},<br />
}, false)<br />
end<br />
</syntaxhighlight><br />
<br />
The code above adds a new <code>min_resistance</code> effect that will set the resistances to specific values if they are currently below that value. It can then be used like this (for example, in [[DirectActionsWML#.5Bobject.5D|[object]]]):<br />
<br />
<syntaxhighlight lang='wml'><br />
[effect]<br />
apply_to=min_resistance<br />
[resistance]<br />
cold=50<br />
[/resistance]<br />
[/effect]<br />
</syntaxhighlight><br />
<br />
Note that in order work properly effects must be registered before any units are created. This means it must be places into toplevel or scenario/era/modification level [lua] tag and in particular must not be done from within a preload event.<br />
<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Built-in effects are now present in the <code>wesnoth.effects</code> table and can be called by custom effects or by other Lua code. They take the same two arguments that a custom effect function does - the unit, and the effect WML.<br />
<br />
In addition, you can now specify description modifiers to be used if a custom effect is placed in a <code>[trait]</code> tag. Instead of setting a function as the effect, you set a table with a <code>__call</code> metafunction which does what the function would have done. The table can then have an additional <code>__descr</code> metafunction which updates descriptions as necessary. The built-in effects all use this structure. This metafunction takes the same arguments as the regular effect function, but should not modify the unit. Instead, it returns a string to be appended to the trait's effect description.<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=Older_News_2016&diff=67989Older News 20162021-05-24T17:52:35Z<p>Vasya: Remove server-specific IRC info</p>
<hr />
<div>==November==<br />
===Wesnoth 1.13.6: Development Release===<br />
''Friday, November 11 2016''<br />
<br />
<b>Wesnoth 1.13.6</b> is now available! This is the sixth development release in the 1.13.x series and it delivers a number of improvements, most notably to the UI, and bug fixes. If you want to know more about it, check out the [https://forums.wesnoth.org/viewtopic.php?t=44809 forum thread] with the list of changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.13.6/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.13.6/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code and Windows packages are already available on the [[Download#Development_.281.13_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br /><b>UPDATE 2016-11-12:</b> The macOS package is now available as well.<br />
<br />
Bear in mind that this is a development version, and one with major internal changes — as such, it is likely to include a lot of new bugs, some of which are already listed in the release notes. If you encounter other issues, make sure to [[ReportingBugs|report them]] to us so they can be fixed for future releases.<br />
<br />
You may [https://forums.wesnoth.org/viewtopic.php?t=44809 comment] on this release in the forums.<br />
<br />
==August==<br />
===New iOS port maintainer needed===<br />
''Wednesday, August 17 2016''<br />
<br />
As Dave mentioned [https://forums.wesnoth.org/viewtopic.php?p=600463#p600463 here], we're looking for someone to help us make a new iOS port of Battle for Wesnoth.<br />
<br />
<blockquote><br />
Also incidentally, we are looking for a new coder to help port Wesnoth to iOS. If anyone is interested or knows somebody who is interested please let me know. The iOS port is badly out of date at this point and someone with those skills would be very much appreciated.<br />
</blockquote><br />
<br />
Our arrangement with the old port's maintainer is sub-optimal, not to mention the port itself is still on version 1.10 even as 1.14 is fast approaching. As such, we're looking for someone to create and maintain a new iOS port and keep it up to date with stable releases as they come out.<br />
<br />
Keep in mind this is not a task to be taken with a dilettante attitude. We're looking for someone with both skill and expertise in app development who's willing to work on this long-term, as opposed to someone who would take this on as a learning experience.<br />
<br />
Additionally, do note you will receive a cut of the profits from sale of the port on the App Store.<br />
<br />
If anyone's interested, send [https://forums.wesnoth.org/memberlist.php?mode=viewprofile&u=125235 vultraz] (our Community Manager) a private message on the forums.<br />
<br />
Thanks<br />
<br />
===Wesnoth 1.13.5: Development Release===<br />
''Friday, August 5 2016''<br />
<br />
<b>Wesnoth 1.13.5</b> is now available! This is the fifth development release in the 1.13.x series and it delivers a number of improvements, most notably to the UI, and bug fixes. If you want to know more about it, check out the [https://forums.wesnoth.org/viewtopic.php?t=44428 forum thread] with the list of changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.13.5/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.13.5/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code, Windows, and macOS packages are already available on the [[Download#Development_.281.13_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br />
<br />
Bear in mind that this is a development version, and one with major internal changes — as such, it is likely to include a lot of new bugs, some of which are already listed in the release notes. If you encounter other issues, make sure to [[ReportingBugs|report them]] to us so they can be fixed for future releases.<br />
<br />
You may [https://forums.wesnoth.org/viewtopic.php?t=44428 comment] on this release in the forums.<br />
<br />
==July==<br />
===We got Greenlit!===<br />
''Wednesday, July 27 2016''<br />
<br />
In less than 4 days, through the incredible support of the community and fans both here and on Reddit, Twitter, Steam, and elsewhere, we reached <b>3,249</b> votes on our Greenlight submission and were Greenlit! The final ranking was <b>#28</b> out of over <b>2,000</b> other games on Greenlight. We honestly weren't expecting this to happen so quickly, and we'd like to extend sincere thanks to everyone who voted and spread the word. Our challenge now is making sure the 1.14.0 release is as good and polished a release as we can make it. In that vein, we again encourage anyone playing on the 1.13 development series to report any bugs they find on our [http://bugs.wesnoth.org bug tracker].<br />
<br />
Once again, thanks for your help, support, and feedback.<br />
<br />
===We're on Steam Greenlight!===<br />
''Saturday, July 23 2016''<br />
<br />
Today we are pleased to announce we have officially submitted an entry for Wesnoth on Steam Greenlight! This does not mean the game is available on Steam yet, though. Now we need your votes to make that happen!<br />
<br />
If Greenlit, we plan to release 1.14.0 on Steam sometime early next year alongside our current distribution channel on SourceForge. Wesnoth will remain completely free, and nothing will change for the people using the SourceForge version. We know this is something a lot of you have inquired about over the past few years. Sadly, it's taken us a long time to sort things out internally to enable this to happen, but we hope it was worth the wait.<br />
<br />
<big>[https://steamcommunity.com/sharedfiles/filedetails/?id=729138129 You can vote on the submission here.] A Steam account with at least one purchased game (activation codes and promotions do not count) is required for voting.</big><br />
<br />
Thanks to all of you who have supported and contributed to the project, and we hope to continue to have your support in our Greenlight campaign. Special thanks to ancestral for making the new trailer. As always, if you have any question feel free to send a private message to one of the developers here on the forums, or inquire in the #wesnoth or #wesnoth-dev IRC channels.<br />
<br />
Feel free to discuss this announcement [//forums.wesnoth.org/viewtopic.php?f=6&t=44366 here] on our forums!<br />
<br />
==June==<br />
===Wesnoth.org maintenance finished===<br />
''Saturday, June 11 2016''<br />
<br />
The scheduled extended maintenance downtime for Wesnoth.org is now over, 5 hours and 40 minutes later.<br />
<br />
If you notice any problems with the website (including forums and wiki), do make sure to report them to us as soon as possible on the appropriately-named [//forums.wesnoth.org/viewforum.php?f=17 Website] forum section.<br />
<br />
===Scheduled Wesnoth.org maintenance downtime===<br />
''Friday, June 3 2016''<br />
<br />
We have scheduled an extended maintenance downtime for the Wesnoth.org web site facilities for the upcoming <b style="color:#f00">Saturday, June 11th at 14:00 UTC</b>. This will affect <b style="color:#f00">all</b> parts of the website served via http/https, including the front page, wiki, forums, units database, web archive for the add-ons server, and files server. The add-ons server and MP servers will remain online during this procedure; however, user authentication capabilities on the primary MP server (<code>server.wesnoth.org</code>) will experience some downtime as well.<br />
<br />
The maintenance tasks to be performed will take at least an hour and up to eight hours to complete. There will be a forum post signaling the end of the downtime when we are finished. Additionally, you will be able to talk to us on IRC as usual.<br />
<br />
==May==<br />
===Wesnoth 1.12.6: Maintenance Release===<br />
''Saturday, May 21 2016''<br />
<br />
'''Wesnoth 1.12.6''' is now available. This is a maintenance release for the stable 1.12.x series and, as such, it delivers an assortment of bug fixes and other improvements over previous releases in this series. In particular, this version includes an important regression fix for non-QWERTY keyboards, and a few fixes for long-standing UI and terrain graphics issues. Check the [//forums.wesnoth.org/viewtopic.php?t=44175 forum thread] for a more detailed list of the most notable fixes and changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.12.6/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.12.6/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code and the Windows installer packages are already available on the [[Download#Stable_.281.12_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br />
<br />
You may [//forums.wesnoth.org/viewtopic.php?t=44175 comment] on this release in the forums.<br />
<br />
==March==<br />
===Wesnoth 1.13.4: Development Release===<br />
''Friday, March 11 2016''<br />
<br />
'''Wesnoth 1.13.4''' is now available! This is the fourth development release in the 1.13.x series and it delivers a number of improvements, bug fixes, as well as a major framework update. If you want to know more about it, check out the [//forums.wesnoth.org/viewtopic.php?t=43912 forum thread] with the list of changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.13.4/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.13.4/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code, Windows, and Apple OS X packages are already available on the [[Download#Development_.281.13_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br />
<br />
Bear in mind that this is a development version, and one with major internal changes — as such, it is likely to include a lot of new bugs, some of which are already listed in the release notes. If you encounter other issues, make sure to [[ReportingBugs|report them]] to us so they can be fixed for future releases.<br />
<br />
You may [//forums.wesnoth.org/viewtopic.php?t=43912 comment] on this release in the forums.<br />
<br />
{{OlderNewsNavigation}}<br />
<br />
[[Category:Announcements and News]]<br />
[[Category:Review on Release]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=Older_News_2016&diff=67987Older News 20162021-05-24T08:46:29Z<p>Vasya: IRC freenode -> libera.chat</p>
<hr />
<div>==November==<br />
===Wesnoth 1.13.6: Development Release===<br />
''Friday, November 11 2016''<br />
<br />
<b>Wesnoth 1.13.6</b> is now available! This is the sixth development release in the 1.13.x series and it delivers a number of improvements, most notably to the UI, and bug fixes. If you want to know more about it, check out the [https://forums.wesnoth.org/viewtopic.php?t=44809 forum thread] with the list of changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.13.6/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.13.6/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code and Windows packages are already available on the [[Download#Development_.281.13_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br /><b>UPDATE 2016-11-12:</b> The macOS package is now available as well.<br />
<br />
Bear in mind that this is a development version, and one with major internal changes — as such, it is likely to include a lot of new bugs, some of which are already listed in the release notes. If you encounter other issues, make sure to [[ReportingBugs|report them]] to us so they can be fixed for future releases.<br />
<br />
You may [https://forums.wesnoth.org/viewtopic.php?t=44809 comment] on this release in the forums.<br />
<br />
==August==<br />
===New iOS port maintainer needed===<br />
''Wednesday, August 17 2016''<br />
<br />
As Dave mentioned [https://forums.wesnoth.org/viewtopic.php?p=600463#p600463 here], we're looking for someone to help us make a new iOS port of Battle for Wesnoth.<br />
<br />
<blockquote><br />
Also incidentally, we are looking for a new coder to help port Wesnoth to iOS. If anyone is interested or knows somebody who is interested please let me know. The iOS port is badly out of date at this point and someone with those skills would be very much appreciated.<br />
</blockquote><br />
<br />
Our arrangement with the old port's maintainer is sub-optimal, not to mention the port itself is still on version 1.10 even as 1.14 is fast approaching. As such, we're looking for someone to create and maintain a new iOS port and keep it up to date with stable releases as they come out.<br />
<br />
Keep in mind this is not a task to be taken with a dilettante attitude. We're looking for someone with both skill and expertise in app development who's willing to work on this long-term, as opposed to someone who would take this on as a learning experience.<br />
<br />
Additionally, do note you will receive a cut of the profits from sale of the port on the App Store.<br />
<br />
If anyone's interested, send [https://forums.wesnoth.org/memberlist.php?mode=viewprofile&u=125235 vultraz] (our Community Manager) a private message on the forums.<br />
<br />
Thanks<br />
<br />
===Wesnoth 1.13.5: Development Release===<br />
''Friday, August 5 2016''<br />
<br />
<b>Wesnoth 1.13.5</b> is now available! This is the fifth development release in the 1.13.x series and it delivers a number of improvements, most notably to the UI, and bug fixes. If you want to know more about it, check out the [https://forums.wesnoth.org/viewtopic.php?t=44428 forum thread] with the list of changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.13.5/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.13.5/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code, Windows, and macOS packages are already available on the [[Download#Development_.281.13_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br />
<br />
Bear in mind that this is a development version, and one with major internal changes — as such, it is likely to include a lot of new bugs, some of which are already listed in the release notes. If you encounter other issues, make sure to [[ReportingBugs|report them]] to us so they can be fixed for future releases.<br />
<br />
You may [https://forums.wesnoth.org/viewtopic.php?t=44428 comment] on this release in the forums.<br />
<br />
==July==<br />
===We got Greenlit!===<br />
''Wednesday, July 27 2016''<br />
<br />
In less than 4 days, through the incredible support of the community and fans both here and on Reddit, Twitter, Steam, and elsewhere, we reached <b>3,249</b> votes on our Greenlight submission and were Greenlit! The final ranking was <b>#28</b> out of over <b>2,000</b> other games on Greenlight. We honestly weren't expecting this to happen so quickly, and we'd like to extend sincere thanks to everyone who voted and spread the word. Our challenge now is making sure the 1.14.0 release is as good and polished a release as we can make it. In that vein, we again encourage anyone playing on the 1.13 development series to report any bugs they find on our [http://bugs.wesnoth.org bug tracker].<br />
<br />
Once again, thanks for your help, support, and feedback.<br />
<br />
===We're on Steam Greenlight!===<br />
''Saturday, July 23 2016''<br />
<br />
Today we are pleased to announce we have officially submitted an entry for Wesnoth on Steam Greenlight! This does not mean the game is available on Steam yet, though. Now we need your votes to make that happen!<br />
<br />
If Greenlit, we plan to release 1.14.0 on Steam sometime early next year alongside our current distribution channel on SourceForge. Wesnoth will remain completely free, and nothing will change for the people using the SourceForge version. We know this is something a lot of you have inquired about over the past few years. Sadly, it's taken us a long time to sort things out internally to enable this to happen, but we hope it was worth the wait.<br />
<br />
<big>[https://steamcommunity.com/sharedfiles/filedetails/?id=729138129 You can vote on the submission here.] A Steam account with at least one purchased game (activation codes and promotions do not count) is required for voting.</big><br />
<br />
Thanks to all of you who have supported and contributed to the project, and we hope to continue to have your support in our Greenlight campaign. Special thanks to ancestral for making the new trailer. As always, if you have any question feel free to send a private message to one of the developers here on the forums, or inquire in the #wesnoth or #wesnoth-dev IRC channels on libera.chat.<br />
<br />
Feel free to discuss this announcement [//forums.wesnoth.org/viewtopic.php?f=6&t=44366 here] on our forums!<br />
<br />
==June==<br />
===Wesnoth.org maintenance finished===<br />
''Saturday, June 11 2016''<br />
<br />
The scheduled extended maintenance downtime for Wesnoth.org is now over, 5 hours and 40 minutes later.<br />
<br />
If you notice any problems with the website (including forums and wiki), do make sure to report them to us as soon as possible on the appropriately-named [//forums.wesnoth.org/viewforum.php?f=17 Website] forum section.<br />
<br />
===Scheduled Wesnoth.org maintenance downtime===<br />
''Friday, June 3 2016''<br />
<br />
We have scheduled an extended maintenance downtime for the Wesnoth.org web site facilities for the upcoming <b style="color:#f00">Saturday, June 11th at 14:00 UTC</b>. This will affect <b style="color:#f00">all</b> parts of the website served via http/https, including the front page, wiki, forums, units database, web archive for the add-ons server, and files server. The add-ons server and MP servers will remain online during this procedure; however, user authentication capabilities on the primary MP server (<code>server.wesnoth.org</code>) will experience some downtime as well.<br />
<br />
The maintenance tasks to be performed will take at least an hour and up to eight hours to complete. There will be a forum post signaling the end of the downtime when we are finished. Additionally, you will be able to talk to us on IRC as usual.<br />
<br />
==May==<br />
===Wesnoth 1.12.6: Maintenance Release===<br />
''Saturday, May 21 2016''<br />
<br />
'''Wesnoth 1.12.6''' is now available. This is a maintenance release for the stable 1.12.x series and, as such, it delivers an assortment of bug fixes and other improvements over previous releases in this series. In particular, this version includes an important regression fix for non-QWERTY keyboards, and a few fixes for long-standing UI and terrain graphics issues. Check the [//forums.wesnoth.org/viewtopic.php?t=44175 forum thread] for a more detailed list of the most notable fixes and changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.12.6/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.12.6/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code and the Windows installer packages are already available on the [[Download#Stable_.281.12_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br />
<br />
You may [//forums.wesnoth.org/viewtopic.php?t=44175 comment] on this release in the forums.<br />
<br />
==March==<br />
===Wesnoth 1.13.4: Development Release===<br />
''Friday, March 11 2016''<br />
<br />
'''Wesnoth 1.13.4''' is now available! This is the fourth development release in the 1.13.x series and it delivers a number of improvements, bug fixes, as well as a major framework update. If you want to know more about it, check out the [//forums.wesnoth.org/viewtopic.php?t=43912 forum thread] with the list of changes in this version.<br />
<br />
As on previous occasions, we also offer two versions of the changelog: a trimmed-down [https://raw.github.com/wesnoth/wesnoth/1.13.4/players_changelog players changelog] including only those items considered to be relevant in regular gameplay, and a more technical [https://raw.github.com/wesnoth/wesnoth/1.13.4/changelog full changelog] for enthusiasts and content creators.<br />
<br />
The source code, Windows, and Apple OS X packages are already available on the [[Download#Development_.281.13_branch.29|downloads page]]. You may also find packages for other platforms there as they become available.<br />
<br />
Bear in mind that this is a development version, and one with major internal changes — as such, it is likely to include a lot of new bugs, some of which are already listed in the release notes. If you encounter other issues, make sure to [[ReportingBugs|report them]] to us so they can be fixed for future releases.<br />
<br />
You may [//forums.wesnoth.org/viewtopic.php?t=43912 comment] on this release in the forums.<br />
<br />
{{OlderNewsNavigation}}<br />
<br />
[[Category:Announcements and News]]<br />
[[Category:Review on Release]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/fr&diff=67986MP CodeOfConduct/fr2021-05-24T08:46:06Z<p>Vasya: IRC freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
<br />
==Introduction==<br />
<div class="thumb tright"><div><br />
[http://pix.toile-libre.org/upload/original/1314467046.png http://pix.toile-libre.org/upload/thumb/1314467046.png]<br />
<div class="thumbcaption">Le vestibule multijoueurs</div></div><br />
</div><br />
<br />
Au commencement, il n'y avait qu'une [[HeirToTheThrone|campagne solo]]. Dorénavant, nous avons un serveur multijoueur capable d'accueillir plus de 1000 joueurs à la fois.<br />
<br />
Bien que Wesnoth soit un jeu libre et que le multijoueur est gratuit et librement accessible à tous, cela ne signifie pas qu'il n'y a pas de règles. Les règles suivantes ont été établies pour procurer une expérience de jeu multijoueur plaisante à tout le monde.<br />
<br />
==Général==<br />
* Soyez poli, spécialement envers les personnes que vous ne connaissez pas.<br />
* Appliquez les règles classiques de discussion sur Internet : pas de spam, pas d'écriture en LETTRES CAPITALES.<br />
* N'utilisez pas d'expression potentiellement offensante dans vos pseudos, titres de carte ou discussions. Cela comprend les jurons, offenses religieuses, racisme, homophobie ou sexisme.<br />
* N'utilisez pas le serveur pour faire la publicité de vos sites/projets commerciaux ou non-commerciaux. Ce n'est pas un service de diffusion publicitaire.<br />
<br />
:: ''Il y a souvent de jeunes enfants jouant sur le serveur, rendant d'autant plus importantes les règles mentionnées.''<br />
<br />
=== &nbsp;Dans le vestibule===<br />
* Le [[MP_Tutorial#The_lobby|vestibule]] est utilisé pour préparer les parties, évitez de l'utiliser pour des discussions d'ordre général ou privé. À la place, utilisez la discussion intégrée dans la partie ou bien les [[#command_head|messages privés]].<br />
* Lisez les titres des parties. Ils contiennent généralement des informations importantes (par exemple : « reserved » (réservé), « will take a long time » (partie longue), ...) qui peuvent vous aider à choisir la partie appropriée.<br />
* Ne rejoignez que les parties que vous comptez terminer.<br />
<br />
=== &nbsp;En tant que joueur===<br />
* Ne quittez pas une partie sans prévenir (nous savons que parfois vous voulez/devez partir, mais faites le savoir aux autres joueurs par avance).<br />
* Ne [[Competitive_Gaming#Cheating|trichez]] pas.<br />
<br />
=== &nbsp;En tant qu'observateur===<br />
* Respectez les joueurs. Si vous souhaitez parler, utilisez la discussion dédiée aux observateurs.<br />
* Ne donnez pas d'informations aux joueurs concernant la partie.<br />
<br />
==Exception==<br />
Il y a une seule exception aux règles présentées ci-dessus : ''si vous êtes absolument sûr que seules des personnes que vous connaissez vont devoir subir votre comportement/langage'' '''''et''''' ''vous savez que cela ne leur pose aucun problème, vous êtes libre de faire ce que vous voulez.''<br />
<br />
==Sanctions==<br />
* Tous les joueurs peuvent placer n'importe qui sur leur liste de personnes ignorées.<br />
* Tous les [[#moderator_list|modérateurs]] peuvent vous bannir du serveur jusqu'à ce que vous ayez prouvé que vous allez changer votre comportement.<br />
<br />
===&nbsp;Pendant le jeu===<br />
* [[MP_Tutorial#Hosts|L'hôte]] a la charge de résoudre les conflits et de renvoyer/bannir n'importe qui de sa partie. Cependant, cela ne l'autorise pas à renvoyer/bannir des joueurs au prétexte qu'il perd ou pour d'autres raisons abusives de ce genre.<br />
* Les modérateurs vérifient le vestibule mais n'interviennent en général pas dans les parties, sauf s'ils pensent que le problème ne se limite pas à une seule partie.<br />
<br />
''Pour ne plus être banni, vous devez contacter [[#moderator_list|le modérateur]] qui vous a banni en premier lieu, afin de lui expliquer pourquoi il devrait lever la sanction. Mais, s'il vous plaît, donnez-lui une bonne raison de le faire, soit en vous excusant, soit en montrant que vous ne répéterez pas les mêmes erreurs.''<br />
<br />
==Obtenir de l'aide==<br />
* Si vous avez besoin d'aide pour l'utilisation du serveur multijoueur, consultez notre [[MP_Tutorial|tutoriel multijoueur]].<br />
* Pour demandez de l'aide des modérateurs (ou rapporter un manquement aux règles) à partir du vestibule ou d'une partie, utilisez la commande « [[#command_head|/query]] adminmsg ».<br />
<br />
===Demandez sur IRC===<br />
Le canal #wesnoth-mp sur le serveur irc.libera.chat est le bon endroit pour demander de l'aide au sujet du jeu multijoueur.<br />
<br/>Pour de l'aide sur d'autres sujets, essayez le canal #wesnoth.<br/><br />
:: ''Pour une introduction à l'IRC, nous vous recommandons [http://www.irchelp.org/irchelp/misc/frnew2irc.html ce tutoriel]. Souvenez-vous que le serveur auquel se connecter est libera.chat et que les canaux utiles sont #wesnoth-mp et #wesnoth.''<br />
<br />
==Informations complémentaires==<br />
Cette section contient quelques informations liées au multijoueur qui pourraient vous intéresser.<br />
<br />
<div id="command_head"> </div><br />
===Commandes utiles===<br />
Le serveur multijoueur de Wesnoth supporte plusieurs commandes utiles à la gestion des parties et des joueurs que vous rencontrerez. Les plus utiles sont :<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Commande'''</div><br />
||'''Description''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;tapée dans la zone de texte, soit dans le vestibule soit en pressant 'm' pendant le jeu'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''texte<br />
|<span style="font-size:90%">envoie le message « texte » à tous les modérateurs disponibles</span>&nbsp;<span style="font-size:80%">(Voir [[ServerAdministration|cette page]] pour d'autre commandes de type /query)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''pseudo&nbsp;texte<br />
|<span style="font-size:90%">envoie le message privé «&nbsp;texte&nbsp;» à «&nbsp;pseudo&nbsp;»</span>&nbsp;<span style="font-size:80%">(identique à /msg ou /whisper).<br/>Vous pouvez aussi double cliquer sur le pseudo</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''pseudo<br />
|<span style="font-size:90%">ajoute «&nbsp;pseudo&nbsp;» à votre liste d'amis</span>&nbsp;<span style="font-size:80%">(ainsi «&nbsp;pseudo&nbsp;» sera en haut de la liste dans le vestibule)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''pseudo<br />
|<span style="font-size:90%">ajoute «&nbsp;pseudo&nbsp;» à la liste des personnes que vous ignorez</span>&nbsp;<span style="font-size:80%">(ainsi «&nbsp;pseudo&nbsp;» sera en bas de la liste dans le vestibule et vous ne verrez plus ses messages)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;tapée dans la zone de commandes en pressant « : » dans le jeu</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''place&nbsp;pseudo<br />
|<span style="font-size:90%">donne à «&nbsp;pseudo&nbsp;» le contrôle du joueur placé en «&nbsp;place&nbsp;»</span>&nbsp;<span style="font-size:80%">(ainsi ''/control 3 «&nbsp;pseudo&nbsp;»'' donnera à «&nbsp;pseudo&nbsp;» le contrôle du 3ème joueur)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''place on/off<br />
|<span style="font-size:90%">remplace le joueur placé en «&nbsp;place&nbsp;» par une intelligence artificielle&nbsp;(ou inversement)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''pseudo<br />
|<span style="font-size:90%">expulse le joueur « pseudo » de la partie</span><br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''pseudo<br />
|<span style="font-size:90%">expulse le joueur « pseudo » de la partie et l'empêche de revenir dans la partie</span>&nbsp;<span style="font-size:80%">(le bannissement se fait sur le pseudo)<br/>N'importe quel joueur présent sur le serveur peut être banni afin de l'empêcher d'accéder à la partie.</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|<span style="font-size:90%">désactive la fonction de sauvegarde automatique, cela peut aider à accélérer les grands scénarios.</span><br />
|}<br />
<br />
Pour une liste complète des commandes multijoueurs, consulter la page [[ChatCommands]] ou bien utilisez la commande /help en jeu ou dans le salon.<br />
<br/><br />
<div id="moderator_list"> </div><br />
<br />
===Liste des modérateurs===<br />
Vous pouvez contacter n'importe quel modérateur ou bien le groupe complet en utilisant [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 cette page du forum].<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Pages liées===<br />
<br />
* [[MP_Tutorial|Tutoriel multijoueur]]<br />
* [[Description/fr|Présentation de Wesnoth]]<br />
* [[Support]]<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Wesnoth forum - inscription]<br />
* [[Competitive_Gaming|Competitive Gaming]]<br />
<br />
<br />
[[Category:Playing Wesnoth]]<br />
[[Category:French]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/pt&diff=67985MP CodeOfConduct/pt2021-05-24T08:42:50Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
'''Atenção:''''' Esta página é uma tradução da [[MP_CodeOfConduct|página em inglês]]. Se você tem alguma dúvida sobre o significado de alguma coisa, por favor cheque a [[MP_CodeOfConduct|página original do Código de Conduta]] ou envie uma mensagem usando [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=101970 esta página].''<br />
<br />
==Introdução==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">O Lobby</div></div><br />
</div><br />
<br />
No início, não havia nada além de [[HeirToTheThrone|uma campanha single-player]]. Agora temos um servidor capaz de hospedar mais de 1000 jogadores ao mesmo tempo.<br />
<br />
Apesar de Wesnoth ser um jogo de código aberto, ou open-source, e de o servidor multiplayer ser livre para qualquer um que queira jogar online, não quer dizer que nós não precisamos de regras. As regras a seguir foram elaboradas para que todos tenham uma experiência online divertida.<br />
<br />
==Geral==<br />
<br />
* Seja educado, principalmente com as pessoas que você não conhece.<br />
* Siga as regras comuns aos chats: nada de spam ou escrever tudo <span style="font-size:108%">EM MAIÚSCULAS</span>.<br />
* Não escreva, use apelidos, títulos de partidas ou labels(função correspondente a Alt + L num jogo) que possam ser ofensivas a outros jogadores. Isso inclui palavrões, referências religiosas agressivas, racismo ou sexismo.<br />
* Não use o servidor para comprar ou vender o que quer que seja. O servidor não é para propagandas.<br />
:: ''Normalmente há crianças jogando no servidor, o que faz das regras acima as as mais importantes.''<br />
=== &nbsp;No lobby===<br />
* O [[MP_Tutorial#The_lobby|chat do lobby]] é feito para organizar partidas, então evite usá-lo para conversas. Se quiser conversar, crie uma partida ou use [[#command_head|mensagens privadas]].&nbsp;<br />
* Leia o título das partidas. Algumas vezes eles possuem informações valiosas (por exemplo: "reservado" ou "vai ser uma partida demorada", etc) que o ajudarão a decidir se você irá ou não entrar nela.<br />
* Só entre em partidas que você pretende terminar.<br />
<br />
=== &nbsp;Como jogador===<br />
* Não saia de um jogo sem avisar (sabemos que às vezes você precisa sair, mas deixe o outro jogador(a) saber o porquê).<br />
* Não [[Competitive_Gaming#Cheating|trapaceie]].<br />
<br />
=== &nbsp;Como espectador===<br />
* Respeite os outros jogadores. Se você quiser falar sobre o jogo, use o chat dos espectadores.<br />
* Não dê informações aos jogadores.<br />
<br />
==Exceção==<br />
<br />
Há apenas uma exceção às regras acima: &nbsp;''se você tem certeza absoluta de que somente pessoas que você conhece irão conhecer o seu ato'' '''''E''''' ''você tem certeza de que eles concordarão com ele, vá em frente...''<br />
<br />
==Sanções==<br />
<br />
* Todos os jogadores estão livres para colocar qualquer um em sua lista de ignorados.<br />
* Todos os [[#moderator_list|moderadores]] podem bani-lo do servidor até que você prove que não irá mais repetir um ato ofensivo.<br />
===<span style="font-size:95%">&nbsp;Em jogos</span>===<br />
* O [[MP_Tutorial#Hosts|host]] (aquele que criou a partida) é o responsável por julgar qualquer problema e pode expulsar/banir qualquer um de seus jogos. No entanto, isso não quer dizer que ele pode expulsar/banir jogadores por estar perdendo ou qualquer ato abusivo parecido.<br />
* Os moderadores policiam o lobby, mas normalmente não investigam problemas em partidas. Esse papel pertence ao host e, ao menos que eles considerem a ofensa muito séria, os moderadores não averiguarão denúncias em partidas.<br />
''Para ser desbanido você precisa contatar [[#moderator_list|o moderador]] que o baniu e explicá-lo por quê ele deve desbanir-lo, mas antes de pedir tenha certeza de que ele(a) tem um bom motivo para o ouvir, seja pedindo desculpas ou mostrando que você não irá repetir suas ações.''<br />
<br />
==Conseguindo ajuda==<br />
<br />
* Se você precisa de ajuda para usar o servidor multiplayer, dê uma olhada no nosso [[MP_Tutorial|tutorial]].<br />
* Para pedir ajuda a um moderador (ou denunciar alguém), use o comando [[#command_head|/query adminmsg]].<br />
===<span style="font-size:96%">&nbsp;Pedindo ajuda no IRC</span>===<br />
O canal #wesnoth-mp no site irc.libera.chat é um bom lugar para pedir ajuda relacionada ao servidor multiplayer.<br />
<br>Para conseguir ajuda relacionada a outros assuntos, tente o canal #wesnoth.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Para uma introdução ao IRC, sugerimos[http://www.irchelp.org/irchelp/irctutorial.html este tutorial]. Apenas lembre-se de que o servidor a se conectar é o libera.chat e que os canais úteis são #wesnoth-mp e #wesnoth.''<br />
<br />
==Para ler mais==<br />
Esta seção contém informações sobre o servidor multiplayer nas quais você pode estar interessado.<br />
<br />
===Comandos úteis===<br />
<br />
O servidor multiplayer possui comandos que podem ser úteis quando lidando com pessoas ou jogos.<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Comando'''</div><br />
||'''Descrição''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;quando digitados diretamente no lobby ou apertando 'm' em um jogo'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''texto<br />
|Envia uma mensagem 'texto' a todos os moderadores disponíveis.&nbsp;&nbsp; <span style="font-size:80%">(Veja [[ServerAdministration|esta página]] para conseguir mais comandos /query)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''apelido&nbsp;texto<br />
| Escreve uma mensagem privada 'texto' para o jogador 'apelido'&nbsp;&nbsp; <span style="font-size:80%">(idêntico aos comandos /msg ou /whisper) (funciona também se você der um clique duplo no apelido)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''apelido<br />
|Adiciona o jogador 'apelido' à sua lista de amigos &nbsp;<span style="font-size:90%">(assim, 'apelido' será listado no topo do lobby)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''apelido<br />
|Adiciona o jogador 'apelido' à sua lista de ignorados &nbsp;<span style="font-size:90%">(assim, 'apelido' será listado por último no lobby e você não verá as mensagens enviadas por ele)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;digitados na caixa de comando, apertando ':' duranto um jogo</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''lado&nbsp;apelido<br />
|Dá ao jogador 'apelido' o controle sobre o lado de número 'lado' <span style="font-size:90%">(por exemplo, control 2 David dará o controle do segundo lado ao jogador David)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''lado on<br />
|Dá o controle do lado de número 'lado' ao computador.<span style="font-size:83%">&nbsp;&nbsp;Se for usado '''''droid lado on''''', o controle irá para o computador, se for usado '''''droid lado off''''' o controle será removido do computador</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''apelido<br />
|Remove o jogador 'apelido' do jogo atual<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''apelido<br />
|Remove e impede que o jogador 'apelido' volte ao jogo atual&nbsp;<span style="font-size:90%">(o jogador não precisa estar necessariamente no jogo, apenas precisa estar online)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|Desliga a função de autosaves, o que pode ser útil em acelerar mapas maiores.<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Para uma lista dos comandos de chat multiplayer veja [[ChatCommands]] ou use o comando /help em um jogo online ou no lobby.<br><br />
&emsp;Para uma lista dos comandos de jogo veja [[CommandMode]] ou use o comando :help em um jogo<br><br />
</span><span style="font-size:1%">br> <br> <br> <br />
<hr></span><br />
<div id="moderator_list"> </div><br />
<br />
===Lista de moderadores===<br />
<br />
Você pode contatar qualquer moderador ou todos os moderadores usando esta [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 página do fórum].<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Páginas relacionadas===<br />
<br />
* [[MP_Tutorial|Multiplayer Tutorial]]<br />
* [[Support]]<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Wesnoth forum - registration]<br />
* [[Competitive_Gaming|Competitive Gaming]]<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/sv&diff=67984MP CodeOfConduct/sv2021-05-24T08:42:21Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''OBS: Den här sidan är en översättning av [[MP_CodeOfConduct|det engelska originalet]] och är till för att underlätta för svenska spelare. Om någon punkt är otydlig hänvisar vi till den ursprungliga "[[MP_CodeOfConduct|Code of Conduct]]"-sidan. Alternativt kan man fråga översättaren om ett förtydligande via [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=100779| den här sidan].''<br />
<br />
<br />
<br />
<div class="thumb tright"><div><br />
[http://www.wesnoth.org/images/sshots/wesnoth-1.11.7-3.jpg http://www.wesnoth.org/images/sshots/wesnoth-1.11.7-3-175.jpg]<br />
<div class="thumbcaption">Gruppspels-lobbyn</div></div><br />
</div><br />
<br />
I början fanns det bara [[HeirToTheThrone|en kampanj]] (engelsk länk) avsedd för en ensam spelare. Idag har vi en server för gruppspel som kan hantera över 1000 spelare åt gången, från hela världen.<br />
<br />
Även om Wesnoth är byggt på öppen källkod och gruppspels-servern är fri att använda för alla, betyder det inte att vi saknar regler. Reglerna som följer är till för alla ska kunna ha kul medan de spelar med varandra.<br />
<br />
==Generella regler==<br />
<br />
* Var artig, speciellt mot människor du inte känner.<br />
* Följ vett och etikett: Spamma inte och skriv inte med <span style="font-size:108%">ENBART STORA BOKSTÄVER</span>.<br />
* Använd inte stötande användarnamn, titlar på kartor, etiketter, eller chatspråk. Detta inkluderar svordomar, kränkande religiösa uttalanden, rasism, och sexism.<br />
* Missbruka inte servern för marknadsföring, inte ens för gratis produkter. Det är inte en annons-service.<br />
'''Det finns ofta barn på servern, vilket gör ovanstående regler desto viktigare'''<br />
=== &nbsp;I lobbyn===<br />
* [[MP_Tutorial#The_lobby|Lobby-chatten]] (engelsk länk) används för att arrangera spel, så undvik att använda den som en allmän chattkanal eller för diskussioner. Håll istället dessa samtal i spelen, eller använd [[#command_head|privata meddelanden]].&nbsp;<br />
* Läs speltitlarna. De innehåller ibland värdefull information (t.ex. "reserverad", "kommer ta lång tid", ...) och kan påverka ifall du väljer att gå med i en spelomgång eller inte.<br />
* Gå enbart med i spelomgångar du tänker spela klart.<br />
<br />
===Som spelare===<br />
* Lämna inte ett spel i förtid utan att ge övriga spelare förvarning (vi vet att man ibland måste/vill gå, men var snäll och ge de andra spelarna förvarning).<br />
* [[Competitive_Gaming#Cheating|Fuska]] (engelsk länk) inte.<br />
<br />
===Som åskådare===<br />
* Respektera de som spelar. Om du vill prata om det pågående spelet, använd åskådarlagets chat-kanal. <br />
* Avslöja inte information för spelarna.<br />
<br />
====Undantag====<br />
<br />
Det finns ett enda undantag för de ovanstående reglerna: ''om du är absolut säker att enbart människor du känner kommer se ditt beteende'' '''''och''''' ''du vet att de är ok med det, varsågod...''<br />
<br />
==Åtgärder==<br />
<br />
* Alla spelare är välkomna att sätta vem de vill på deras lista över ignorerade spelare.<br />
* Alla [[#moderator_list|moderatorer]] på servern kan bannlysa dig från servern tills du har bevisat att du inte kommer begå samma regelbrott igen.<br />
===I spel===<br />
* [[MP_Tutorial#Hosts|Värden]] (engelsk länk) är ansvarig för att hantera alla uppkomna problem och kan slänga ut eller bannlysa vem som helst från spelet. Detta betyder dock inte att de får slänga ut eller bannlysa spelare för att de är på väg att förlora eller utöva liknande maktmissbruk.<br />
* Serverns moderatorer patrullerar lobbyn men undersöker vanligtvis inte problem i spel såvida de inte är övertygade att regelbrottet sträcker sig över mer än ett enskilt spel.<br />
''För att upphäva en bannlysning behöver du kontakta [[#moderator_list|moderatorn]] som bannlyste dig och förklara varför han/hon borde upphäva bannlysningen. Se till att han/hon verkligen har anledning att göra det, antingen med en ursäkt och/eller genom att visa att du inte kommer upprepa ditt övertramp.''<br />
<br />
==Skaffa hjälp==<br />
<br />
*Om du behöver instruktioner i hur du använder gruppspels-servern, läs vår [[MP_Tutorial|guide till gruppspel]] (engelsk länk).<br />
*För att be om hjälp från en moderator (eller för att rapportera någon) i lobbyn eller spelet, använd kommandot [[#command_head|/query adminmsg]].<br />
===Hjälp via IRC===<br />
Chatt-rummet #wesnoth-mp på irc.libera.chat är en bra plats för frågor angående gruppspel och gruppspels-servern.<br />
För hjälp med andra Wesnoth-ämnen, pröva istället #wesnoth.<br />
''För en introduktion till IRC, föreslår vi [http://www.irchelp.org/irchelp/irctutorial.html den här guiden](engelsk länk). Kom bara ihåg att ansluta till libera.chat-nätverket och att de relevanta chat-rummen är #wesnoth-mp och #wesnoth''<br />
<br />
==Användbara kommandon==<br />
<br />
Wesnoths gruppspels-server stöder flertalet kommandon som kan vara nyttiga när du hanterar både spel och människor du möter på servern. De mest relevanta är:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Kommando'''</div><br />
||'''Beskrivning''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;skrivs antingen i en meddelanderuta, direkt i lobbyn eller genom att trycka 'm' inne i ett spel'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''text<br />
|skickar ett meddelande med 'text' till alla tillgängliga server-moderatorer.&nbsp;&nbsp; <span style="font-size:80%">(Se [[ServerAdministration|denna sida]](engelsk länk) för fler /query kommandon.)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''användarnamn&nbsp;text<br />
|skicka ett privat meddelande med 'text' till 'användarnamn'&nbsp;&nbsp; <span style="font-size:80%">(identiskt med /msg eller /whisper) (du kan också dubbelklicka på användarnamnet)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''användarnamn<br />
|lägg till 'användarnamn' i din vän-lista &nbsp;<span style="font-size:90%">(så 'användarnamn' syns högst upp i listan i lobbyn)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''användarnamn<br />
|lägg till 'användarnamn' i din lista över ignorerade spelare &nbsp;<span style="font-size:90%">(så 'användarnamn' hamnar i botten av listan i lobbyn och du slipper se meddelanden skrivna av 'användarnamn')</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;skrivs i en kommando-ruta, genom att trycka ':' i ett spel</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''sida&nbsp;användarnamn<br />
|ge 'användarnamn' kontrol över 'sida' (anges med ordningsnummer)<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''sida on<br />
|ge kontrol över 'sida' (nummer) till datorn.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''sida''&nbsp;&nbsp;växlar mellan AI och spelarens kontrol</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''användarnamn<br />
|släng ut spelaren med 'användarnamn' från det pågående spelet<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''användarnamn<br />
|släng ut spelaren med 'användarnamn' från det pågående spelet och förbjud honom/henne från att gå med igen &nbsp;<span style="font-size:90%">(spelaren måste inte vara med i spelet för att kommandot ska verka, men måste vara på servern)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|Stäng av de automatiska sparningarna. Kan hjälpa till att snabba på spelet i stora scenarion<br />
|}<br />
<br />
<span style="font-size:95%"><br />
För en lista över generella gruppspels-kommandon se [[ChatCommands]](engelsk länk) eller använd kommandot /help i ett gruppspel eller i lobbyn.<br />
<br />
För en lista över kommandon att använda i ett spel, se [[CommandMode]](engelsk länk) eller använd kommandot :help i en spelomgång.<br />
</span><br />
<div id="moderator_list"> </div><br />
==Lista över moderatorer för servrarna==<br />
<br />
Du kan kontakta valfri moderator eller hela moderator-gruppen via [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 den här forum-sidan] (på engelska).<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
==Se även==<br />
<br />
* [[MP_Tutorial|Multiplayer Tutorial]](engelsk länk)<br />
* [[Support]](engelsk länk)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Wesnoth forum - registrering](engelsk länk)<br />
* [[Competitive_Gaming|Competitive Gaming]](engelsk länk)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/vi&diff=67983MP CodeOfConduct/vi2021-05-24T08:41:55Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''Đây không phải là bản Code of Conduct (Quy định về cách ứng xử) nguyên gốc mà là bản dịch tiếng Việt của nó. Nếu bạn cảm thấy khó hiểu về bất cứ quy định nào dưới đây, xin hãy tham khảo trang [http://wiki.wesnoth.org/MP_CodeOfConduct Code of Conduct nguyên gốc] hoặc đưa ra câu hỏi [http://forums.wesnoth.org/viewtopic.php?f=7&t=33523 ở đây].<br />
Mọi ý kiến/đóng góp liên quan đến bản dịch tiếng Việt này xin hãy gửi đến cho [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=117382 hhyloc]''<br />
<br />
==Giới thiệu==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">Phòng đợi nhiều người chơi</div></div><br />
</div><br />
<br />
Ban đầu, chẳng có gì khác ngoài [[HeirToTheThrone|một chiến dịch một người chơi]]. Giờ thì chúng tôi đã có một máy chủ có thể hổ trợ cùng lúc hơn 1000 người chơi.<br />
Mặc dù Wesnoth là một trò chơi nguồn mở và mọi người chơi đều được sử dụng máy chủ, điều đó không có nghĩa là chúng tôi không cần quy định nào cả. Vì thế những quy định dưới đây được đưa ra nhằm đảm bảo mọi người có được sự thoải mái khi chơi qua mạng.<br />
<br />
==Quy định chung==<br />
<br />
* Hãy lịch sự, đặc biệt là với những người bạn không biết.<br />
* Tuân theo quy định chung khi chat: Không spam hãy viết nội dung chat toàn bằng <span style="font-size:108%">CHỮ HOA</span>.<br />
* Không sử dụng những tên nick, tên bản đồ, nhãn, hay những nội dung chat xúc phạm: Bao gồm nội dung thô tục/chửi thề, ý kiến công kích tôn giáo, phân biệt chủng tộc, phân biệt giới tính.<br />
* Không sử dụng máy chủ vào mục đích buôn bán hay quảng cáo. Đây không phải là dịch vụ quảng cáo.<br />
:: ''thường xuyên có trẻ em chơi trên máy chủ, vì thế những quy định trên là rất quan trọng''<br />
=== &nbsp;Trong phòng đợi===<br />
* [[MP_Tutorial#The_lobby|Khu vực chat của phòng đợi]] được sử dụng để sắp xếp các trò chơi, vì vậy hãy tránh sử dụng nó cho mục đích chat chung chung hoặc cá nhân. Thay vào đó, chat trong game hoặc dùng chức năng [[#command_head|tin nhắn cá nhân]].&nbsp;<br />
* Đọc kỹ tiêu đề của mỗi trò chơi. Đôi khi chúng chứa những thông tin quan trọng (vd: "dành riêng cho", "sẽ tốn rất nhiều thời gian", ...) và có thể ảnh hưởng đến quyết định của bạn liệu có nên tham gia trò chơi đó hay không.<br />
* Chỉ tham gia trò chơi mà bạn muốn chơi hết.<br />
<br />
=== &nbsp;Đối với người chơi===<br />
* Không bỏ chơi giữa chừng mà không báo trước (chúng tôi biết rằng đôi khi bạn muốn/cần rời đi, nhưng xin hãy báo trước cho những người chơi khác).<br />
* Không [[Competitive_Gaming#Cheating|gian lận]].<br />
<br />
=== &nbsp;Đối với người quan sát===<br />
* Tôn trọng người chơi. Nếu bạn muốn nói về trò chơi, sử dụng chức năng chat riêng với từng đội. <br />
* Đừng để lộ thông tin của người chơi.<br />
<br />
==Ngoại lệ==<br />
<br />
Có một ngoại lệ đối với những điều trên: &nbsp;''nếu bạn chắc chắn rằng chỉ những người bạn biết mới sẽ gặp kiểu ứng xử của bạn'' '''''và''''' ''bạn biết họ sẽ không phàn nàn gì, vậy thì không cần ngại...''<br />
<br />
==Quyền lợi==<br />
<br />
* Mọi người chơi đều có quyển đưa bất kỳ ai vào danh sách từ chối của mình<br />
* Tất cả [[#Danh%20s%C3%A1ch%20qu%E1%BA%A3n%20tr%E1%BB%8B%20vi%C3%AAn%20m%C3%A1y%20ch%E1%BB%A7|điều hành viên]] có thể cấm bạn vào chơi trên máy chủ cho đến khi bạn chứng tỏ rằng mình sẽ không lặp lại cách ứng xử xúc phạm một lần nửa.<br />
===<span style="font-size:95%">&nbsp;Trong trò chơi</span>===<br />
* [[MP_Tutorial#Hosts|Người chủ trò chơi]] có trách nhiệm giải quyết những vấn đề nảy sinh và có thể đuổi/cấm bất cứ ai trong trò chơi của mình. Tuy nhiên không được đuổi/cấm ai chỉ vì họ đang thua hoặc đuổi/cấm họ mà không có lý do thỏa đáng.<br />
* Các điều hành viên giữ trật tự cho phòng đợi nhưng thường thì không kiểm tra các trò chơi trừ khi họ tin rằng những hành vi xúc phạm vượt quá mức độ trong một trò chơi.<br />
''Để được dỡ bỏ hình phạt bị cấm thì bạn phải liên lạc [[#Danh%20s%C3%A1ch%20qu%E1%BA%A3n%20tr%E1%BB%8B%20vi%C3%AAn%20m%C3%A1y%20ch%E1%BB%A7|quản trị viên]] mà đã cấm bạn và giải thích tại sao người ấy nên dỡ bỏ hình phạt cấm đối với bạn, nhưng hãy đảm bảo rằng người ấy có lý do để làm vậy, bằng cách xin lỗi hoặc thể hiện rằng bạn sẽ không lặp lại lỗi đã gây ra.''<br />
<br />
<br />
==Trợ giúp==<br />
<br />
*Nếu bạn cần trợ giúp trong việc chơi mạng trên máy chủ, hãy thử đọc [[MP_Tutorial|hướng dẫn chơi mạng]] (Tiếng Anh).<br />
*Để nhờ quản trị viên giúp đỡ (hay báo cáo một người chơi gây rối) trong phòng đợi/trò chơi, sử dụng lệnh [[#command_head|/query adminmsg]].<br />
===<span style="font-size:96%">&nbsp;Hỏi trên IRC</span>===<br />
Kênh #wesnoth-mp trêm irc.libera.chat là một nơi thích hợp để đưa ra câu hỏi liên quan đến máy chủ nhiều người chơi.<br />
<br>Để nhờ trợ giúp về các vấn đề khác, hãy vào #wesnoth channel.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Để làm quen với IRC, chúng tôi khuyên bạn nên đọc [http://www.irchelp.org/irchelp/irctutorial.html hướng dẫn này] (Tiếng Anh). Hãy nhớ rằng bạn cần phải kết nối vào máy chủ libera.chat và kênh là #wesnoth-mp và #wesnoth''<br />
<br />
==Thông tin bổ sung==<br />
Dưới đây chứa một số thông tin liên quan đến chế độ nhiều người chơi mà có thể hữu ích cho bạn.<br />
<br />
===Các lệnh hữu ích===<br />
<br />
Máy chủ nhiều người chơi hỗ trợ một số lệnh hữu ích để sử dụng trong trò chơi hoặc đối với những người chơi khác. Những lệnh hữu ích nhất là:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Lệnh'''</div><br />
||'''Mô tả''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;gõ nội dung vào hộp thoại, bằng cách gõ nội dung trực tiếp trong phòng đợi hoặc nhấn phím 'm' trong trò chơi'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''nội dung<br />
|gửi một tin nhắn với mang nội dung là 'nội dung' tới tất cả quản trị viên máy chủ.&nbsp;&nbsp; <span style="font-size:80%">(Xem [[ServerAdministration|trang này]] (Tiếng Anh) để tìm hiểu hơn về các lệnh /query .)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''tên người chơi&nbsp;nội dung<br />
|viết một tin nhắn cá nhân có nội dung là 'nội dung' đến 'tên người chơi'&nbsp;&nbsp; <span style="font-size:80%">(tương tự như /msg hay /whisper) (cũng có thể nhấp đôi vào tên người chơi)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''tên người chơi<br />
|đưa 'tên người chơi' vào danh sách bạn bè &nbsp;<span style="font-size:90%">(làm vậy để 'tên người chơi luôn đứng đầu trong danh sách người chơi trong phòng đợi)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''tên người chơi<br />
|đưa 'tên người chơi' vào danh sách từ chối &nbsp;<span style="font-size:90%">(làm vậy để 'tên người chơi luôn nằm dưới cùng của danh sách người chơi trong phòng đợi và bạn sẽ không thấy những thông điệp do 'tên người chơi' viết)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;gõ vào hộp lệnh hay nhấn phím ':' trong trò chơi</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''phe&nbsp;tên người chơi<br />
|giao quyền điều khiển cho 'tên người chơi' đối với 'phe'<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''phe on<br />
|giao quyền điều khiển cho máy đối với 'phe'.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''phe''&nbsp;&nbsp;chuyển đổi giữa người chơi điều khiển hay máy điều khiển</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''tên người chơi<br />
|đuổi 'tên người chơi' khỏi trò chơi hiện tại<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''tên người chơi<br />
|đuổi và cấm 'tên người chơi' tham gia lại vào trò chơi hiện tại &nbsp;<span style="font-size:90%">(người chơi không nhất thiết phải đang ở trong trò chơi mà cũng có thể đang ở trên máy chủ)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|tắt chức năng lưu tự động, có thể hữu ích trong những màn chơi dài<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Để xem danh sách những lệnh dùng trong chế độ nhiều người chơi xin hãy xem [[CommandMode]] hay dùng lệnh /help trong trò chơi hay trong phòng đợi.<br><br />
&emsp;Để xem danh sách những lệnh dùng trong trò chơi xin hãy xem [[CommandMode]] hay dùng lệnh :help trong trò chơi.<br><br />
<br />
</span><br />
<br />
<br />
----<br />
===Danh sách quản trị viên máy chủ===<br />
<br />
Bạn có thể liên lạc bất kỳ quản trị viên nào hay cả nhóm quản trị viên bằng cách dùng [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 chức năng này] (Tiếng Anh).<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Các trang liên quan===<br />
<br />
* [[MP_Tutorial|Hướng dẫn chơi mạng]] (Tiếng Anh)<br />
* [[Support|Hỗ trợ]] (Tiếng Anh)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Đăng ký trên diễn đàn Wesnoth] (Tiếng Anh)<br />
* [[Competitive_Gaming|Chơi đối kháng]] (Tiếng Anh)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/la&diff=67982MP CodeOfConduct/la2021-05-24T08:41:37Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''Haec pagina translatio versionis Anglice est. Si incertus de sententia es, amabo vide Leges primas aut mitte nuntium ad [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=116812 Deusiten]''<br />
<br />
==Prooemium==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">Atrium Pluribus Lusoribus</div></div><br />
</div><br />
<br />
Fuit principio tantum [[HeirToTheThrone|una militia uno lusore]]. Nunc servatrum pluribus lusoribus nobis est quod simul plus quam mille lusores servire potest.<br />
<br />
Quamquam Vesnotes ludus cum fonte aperta et servatro pluribus lusoribus publicum est etiam necesse est leges habere. Hae leges stant ut omnes ludo fruantur.<br />
<br />
==Omnino==<br />
<br />
* Esto humanus, praesertim erga homines ignotos.<br />
* Pareto legibus publicis loquendi: nolito effutire neve scribere <span style="font-size:108%">CUM LITTERIS QUADRATIS</span>.<br />
* Nolito uti nomen capax iniuriarum, neve titulos chartae, neve titulos, neve verba. Maledictiones, rationes rebus religiosis, et odium nationis aut sexus.<br />
* Nolito abutere servatro causa divulgandi rerum aut negotii aut otii. Non est facultas venditandi.<br />
:: ''adsunt saepe pueri ludentes in servatro, igitur leges eaedem graviores sunt''<br />
=== &nbsp;In Atrio===<br />
* [[MP_Tutorial#The_lobby|Colloquium atrii]] utitur causa instruendi ludi, ita curato vitandum colloquium publicum privatumve. Moveto colloquium in ludum, vel utitor [[#command_head|nuntios privatos]].&nbsp;<br />
* Legito titulos ludorum. Qui aliquando pretiosa continent (e.g. "adsignatus", "diu", ...) et te afficiat ne in ludo convenias.<br />
* Convenito modo in ludis quos in animo finire habes.<br />
<br />
=== &nbsp;Ut Lusor===<br />
* Nolito a ludo abire sine nuntio (scimus te aliquando linquere debere/velle, sed amabo lusores(em) prius certiorem facito).<br />
* Nolito [[Competitive_Gaming#Cheating|decipere]].<br />
<br />
=== &nbsp;Ut Spectator===<br />
* Observato lusores. Si de ludo loqui vis, utitor colloquium manibus spectatorum. <br />
* Nolito dare lusoribus indicium.<br />
<br />
==Exceptio==<br />
<br />
Est exceptio una: &nbsp;''Si pro certo habes homines notos modo morem tuum inventuros esse atque scis illos laturos esse, fas est...''<br />
<br />
==Auctoritas==<br />
<br />
* Omnibus lusoribus alium in tabulas neglegentium ponere licet.<br />
* Omnibus [[#moderator_list|moderatoribus servatri]] te e servatro exportare licet dum demonstres te non nefas iteraturum esse.<br />
===<span style="font-size:95%">&nbsp;In ludo</span>===<br />
* [[MP_Tutorial#Hosts|Hospes]] curando rebus praeest et aliquid e ludo fugare/deportare potest. Sibi tamen lusores non licet fugare/deportare sine ratione bona.<br />
* Moderatores servatri lictores atrii sunt sed non in ludo investigare solent nisi pro certo habent iniuriam fines ludi soli praeterire.<br />
''Ut deportatus resistueris tibi adloqui [[#moderator_list|moderatorem]] deportantem opus est et rationem qua te restituere debet exponere, sed amabo fac ut ratio sit sibi; aut te paenitere aut te ostendere te facta non iteraturum esse.''<br />
<br />
==Auxilium Petere==<br />
<br />
*Si subsidio de servatro pluribus lusoribus egeas, vide [[MP_Tutorial|rudimentum]] nostrum.<br />
*Ut auxilium a moderatore (vel nefas nunties) in atrio ludove petas, utitor imperium [[#command_head|/query adminmsg]].<br />
===<span style="font-size:96%">&nbsp;Petere in IRC</span>===<br />
Canalis #wesnoth-mp in irc.libera.chat locus bonus est auxilio de servatro pluribus lusoribus petendo.<br />
<br>Ut auxilium de materiis aliis invenias, utitor canalem #wesnoth nomine.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [http://www.irchelp.org/irchelp/irctutorial.html hunc rudimentum] probamus ut prooemium IRC invenias. Sed memora rete servatri "libera.chat" esse et canales rectos #wesnoth-mp et #wesnoth esse<br />
<br />
==Plures==<br />
Hoc capitulum plures lusores pertinet ut tua intersit.<br />
<br />
===Imperia Utilia===<br />
<br />
Servatrum Vesnotei pluribus lusoribus plures imperiorum sustinet, qua utilissima sit, cum ludum et homines obvios curas. Sunt optima: <br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Imperium'''</div><br />
||'''Descriptio''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;in colloquio sciptum, sive recte in atrio sive in ludo 'm' premendo'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''verba<br />
|mittere nuntium 'verba' ad omnes moderatores servatri qui adsunt.&nbsp;&nbsp; <span style="font-size:80%">(Ecce [[ServerAdministration|hanc paginam]] ut plures imperiorum "/query" videas.)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''nomen&nbsp;verba<br />
|scribere 'verba' nuntium privatum 'nomini'&nbsp;&nbsp; <span style="font-size:80%">(et idem /msg vel /whisper) (quoque bis nomine premendo)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''nomen<br />
|imponere 'nomen' in tabula amicorum&nbsp;<span style="font-size:90%">(ut 'nomen' in summo atrio adsit)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''nomen<br />
|imponere 'nomen' in tabula neglectorum &nbsp;<span style="font-size:90%">(ut 'nomen' in imo atrio adsit et nuntios a 'nomine' sciptos non videas)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;in spatio imperiorum in ludo ':' premendo sciptum</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''manum&nbsp;nomen<br />
|dare 'nomini' imperium manus 'side'<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''manum<br />
|dare IA ordinatrale imperium manus.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''manus''&nbsp;&nbsp;imperium IA hominisve inter se mutare</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''nomen<br />
|auferre a ludo illo lusorem 'nomen'<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''nomen<br />
|lusorem 'nomen' a ludo movere et se prohibere quominus iterum conveniat &nbsp;<span style="font-size:90%">(non est necesse lusori in ludo esse sed in servatro)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|sistere officium sua sponte servandi quod magno scaenario accelerando usui sit<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Ut tabulam imperiorum communium videas, ecce [[ChatCommands]] aut utere in ludo plusoribus atriove imperium "/help".<br> nomine <br />
&emsp;Ut tabulam imperiorum qui in ludo uti potes videas, ecce [[CommandMode]] aut utere in ludo imperium ":help" nomine.<br><br />
</span><span style="font-size:1%"><br> <br> <br> <br />
<hr></span><br />
<div id="moderator_list"> </div><br />
<br />
===Tabula moderatorum servatro===<br />
<br />
Moderatorem ullum vel totum manum utendo [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 hac pagina fori] adloqui potes.<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Paginae similes===<br />
<br />
* [[MP_Tutorial|Rudimentum Pluribus Lusoribus]]<br />
* [[Support|Auxilium]]<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Forum Vesnotei - nomen dare]<br />
* [[Competitive_Gaming|Ludere Certamen]]<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/ru&diff=67981MP CodeOfConduct/ru2021-05-24T08:41:11Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
'''Note:'''''This page is a translation of the [[MP_CodeOfConduct|English origina]]l. If you are uncertain about the meaning of something, please refer to [[MP_CodeOfConduct|the original Code of Conduct page]] or send a message using [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=101970 this page].''<br />
<br />
==Вступление==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">Холл мультиплеера</div></div><br />
</div><br />
<br />
Вначале, в игре не было ничего кроме [[HeirToTheThrone|единственной однопользовательской кампании]]. Сейчас у нас есть мультиплеерный сервер, на котором могут одновременно находиться более 1000 игроков.<br />
<br />
Хотя Веснот и является игрой с открытым исходным кодом и мультиплеерный сервер может использоваться каждым желающим, это не значит что нам не нужны правила. Следующие правила помогут обеспечить приятное времяпровождение в мультиплеере.<br />
<br />
==Основные Правила==<br />
<br />
* Будьте вежливы, особенно с людьми, которых вы не знаете.<br />
* Соблюдайте общепринятые правила чата: Не спамьте и не пишите всё полностью <span style="font-size:108%">В ВЕРХНЕМ РЕГИСТРЕ</span>.<br />
* Не используйте потенциально оскорбительные ники, названия карт, лейблы или речь. В это входят<br />
нецензурная лексика, религиозные оскорбления, расизм или половую дискриминацию.<br />
* Не используйте сервер для рекламирования коммерческих и некоммерческих предприятий. Это не рекламная служба.<br />
:: ''дети часто играют на сервере, вышеупомянутые правила имеют наибольшее значение''<br />
=== &nbsp;В Холле===<br />
* [[MP_Tutorial#The_lobby|Чат в холле]] используется для организации игр, поэтому пытайтесь избегать использования его для простого общения. Вместо этого, перенесите беседу в игру, или используйте [[#command_head|личные сообщения]].&nbsp;<br />
* Читайте названия игр. Иногда они содержат полезную информацию(например: "зарезервировано(reserved)", "займёт много времени", ...) и может оказать влияние на ваше решение присоединиться или не присоединиться.<br />
* Присоединяйтесь только к тем играм, которые вы намерены доиграть до конца.<br />
<br />
=== &nbsp;Как Игрок===<br />
* Не покидайте игру без предварительного предупреждения(мы знаем, что иногда вы хотите/вам нужно уйти, но, пожалуйста, позвольте другим игрокам узнать об этом заранее).<br />
* Не [[Competitive_Gaming#Cheating|жульничайте]].<br />
<br />
=== &nbsp;Как Наблюдатель===<br />
* Уважайте игроков. Если вы ходите обсудить игру, используйте чат для наблюдающих. <br />
* Не выдавайте информацию игрокам.<br />
<br />
==Исключение==<br />
<br />
Из вышеперечисленного есть исключение: &nbsp;''если вы полностью уверены, что только люди которых вы знаете будут затронуты вашим поведением'' '''''и''''' ''вы знаете, что для них это будет нормально, продолжайте...''<br />
<br />
==Меры Воздействия==<br />
<br />
* Все игроки имеют право записать любого в список игнорируемых.<br />
* Все [[#moderator_list|модераторы сервера]] могут забанить вас до тех пор, пока вы не докажете, что вы больше не повторите оскорбительное поведение.<br />
===<span style="font-size:95%">&nbsp;В Играх</span>===<br />
* [[MP_Tutorial#Hosts|Хост]] отвечает за решение проблем и может выкинуть из игры/забанить любого участника. Однако, это не значит, что ему позволено выкидывать/помещать в бан игроков, потому что они проигрывают или совершать другие оскорбительные действия.<br />
* Модераторы сервера контролируют холл, но, обычно, не наблюдают за играми, если только они не убеждены в том, что нарушение выходит за рамки отдельной игры.<br />
''Чтобы вас разбанили, свяжитесь с [[#moderator_list|модератором]], забанившим вас, и объясните почему ему/ей следует разбанить вас, но, пожалуйста, убедитесь в том, что у него/неё есть причина сделать это(либо с помощью извинений, либо показав, что вы больше не повторите своих действий).''<br />
<br />
==Получение Помощи==<br />
<br />
*Если вам нужно руководство по использованию мультиплеерного сервера, проверьте наше [[MP_Tutorial|мультиплеерное обучение]].<br />
*Чтобы попросить модератора о помощи (или сообщить о правонарушителе) в холле/игре - используйте команду [[#command_head|/query adminmsg]].<br />
===<span style="font-size:96%">&nbsp;Обращение с Вопросом на IRC</span>===<br />
Канал #wesnoth-mp на irc.libera.chat является хорошим местом, чтобы попросить о помощи, связанной с мультиплеерным сервером.<br />
<br>Для помощи касательно других вопросов, попробуйте канал #wesnoth.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Для введения в IRC, мы предлагаем [http://www.irchelp.org/irchelp/irctutorial.html данное обучение]. Просто помните, что сетью для подключения является libera.chat и соответствующие каналы это #wesnoth-mp и #wesnoth''<br />
<br />
==Дополнительные Материалы==<br />
Эта секция содержит некоторую информацию, связанную с мультиплеером, которая может вас заинтересовать.<br />
<br />
===Полезные Команды===<br />
<br />
Мультиплеер Веснота поддерживает несколько команд, которые могут быть полезными при решении вопросов с играми и людьми, которых вы можете встретить. Самыми полезными являются следующие:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Команда'''</div><br />
||'''Описание''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;пишется в окне сообщения, либо прямо в холле, либо с помощью нажатия 'm' в игре'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''текст<br />
|отправить сообщение 'текст' всем доступным модераторам сервера.&nbsp;&nbsp; <span style="font-size:80%">(Смотрите [[ServerAdministration|эту страницу]] для дальнейших /query команд.)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''ник&nbsp;текст<br />
|отправить личное сообщение 'текст' пользователю 'ник'&nbsp;&nbsp; <span style="font-size:80%">(индентично командам /msg или /whisper) (также при помощи двойного щелчка мышью по нику)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''ник<br />
|добавить пользователя 'ник' в ваш список друзей &nbsp;<span style="font-size:90%">(тогда пользователь 'ник' будет отображаться в начале списка в холле)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''ник<br />
|добавить пользователя 'ник' в ваш список игнорируемых &nbsp;<span style="font-size:90%">(тогда пользователь 'ник' будет отображаться в конце списка в холле, и вы не будете видеть сообщений, написанных пользователем 'ник')</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;пишется в окне команд с помощью нажатия ':' в игре</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''сторона&nbsp;ник<br />
|передать пользователю 'ник' контроль над стороной номер 'сторона'<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''сторона on<br />
|передать контроль над стороной номер 'сторона' ИИ компьютера.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''сторона''&nbsp;&nbsp;переключает управление между ИИ и человеком</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''ник<br />
|удалить игрока с ником 'ник' из текущей игры<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''ник<br />
|удалить из игры и предотвратить дальнейшее присоединение игрока с ником 'ник' к текущей игре &nbsp;<span style="font-size:90%">(игрок не обязан присутствовать в игре, но должен быть на сервере)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|отключить функцию автосохранения, может быть полезно для ускорения процесса в больших сценариях<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Для списка универсальных мультиплеерных команд смотрите [[ChatCommands|Команды Чата]] или используйте команду /help в мультиплеерной игре или холле.<br><br />
&emsp;Для списка внутриигровых команд смотрите [[CommandMode|Режим Команд]] или используйте команду :help в игре.<br><br />
</span><span style="font-size:1%">br> <br> <br> <br />
<hr></span><br />
<div id="moderator_list"> </div><br />
===Список Модераторов===<br />
<br />
Вы можете связаться с любым модератором или со всей группой модераторов используя [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 эту страницу форумов].<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Связанные Страницы===<br />
<br />
* [[MP_Tutorial|Мультиплеерное Обучение]]<br />
* [[Support|Поддержка]]<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Форум Веснота - регистрация]<br />
* [[Competitive_Gaming|Соревновательные Игры]]<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/de&diff=67980MP CodeOfConduct/de2021-05-24T08:40:52Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
'''''Anmerkung:''' Dies ist eine Übersetzung aus dem Englischen. Wenn du dir unsicher über etwas bist, ziehe das [[MP_CodeOfConduct|englische Original]] zu Rate oder sende über das Forum eine Nachricht an den [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=123590| momentanen Betreuer] dieser Seite ('''Ceres''').''<br />
<br />
==Einführung==<br />
<br />
<div class="thumb tright"><div><br />
[http://pix.toile-libre.org/upload/original/1314467046.png http://pix.toile-libre.org/upload/thumb/1314467046.png]<br />
<div class="thumbcaption">Die Mehrspielerlobby</div></div><br />
</div><br />
<br />
Am Anfang gab es nichts außer [[HeirToTheThrone|einer Einzelspieler-Kampagne]]. Jetzt haben wir einen Mehrspieler-Server, der bis zu 1000 Spieler auf einmal hosten kann.<br />
<br />
Obwohl Wesnoth ein Open-Source-Spiel ist und der Mehrspieler-Server von jedem genutzt werden kann, bedeutet das noch lange nicht, dass wir keine Regeln brauchen. Die folgenden Regeln sind dazu gedacht, den Aufenthalt im Mehrspieler-Server so angenehm wie möglich zu machen.<br><br />
<br />
==Allgemein==<br />
<br />
* Sei höflich, insbesondere zu Leuten, die du nicht kennst.<br />
* Halte dich an die allgemeinen Chatregeln: Nicht spammen oder <span style="font-size:108%">IN GROßBUCHSTABEN</span> schreiben.<br />
* Benutze keine potentiell beleidigenden Namen, Kartentitel, Beschriftungen, oder Nachrichten. Das beinhaltet auch Flüche/Verwünschungen, beleidigende religiöse Kommentare, Rassismus, oder Sexismus.<br />
* Missbrauche den Server nicht, um (nicht-)kommerzielle Unternehmungen zu vermarkten. Er ist nicht für Werbung gedacht.<br />
:: ''Es sind häufig Kinder auf dem Server, was die oben genannten Regeln noch wichtiger macht.''<br />
=== &nbsp;In der Lobby===<br />
* Der [[MP_Tutorial#The_lobby|Chat in der Lobby]] wird zum Arrangieren von Spielen verwendet, also versuche, ihn nicht für allgemeines/persönliches Chatten zu verwenden. Dafür solltest du den Chat während eines Spiels oder [[#command_head|persönliche Nachrichten]] benutzen.&nbsp;<br />
* Lies die Titel von Spielen. Sie enthalten manchmal wichtige Informationen (z.B. "reserviert", "wird sehr lange dauern", ...) und könnten deine Entscheidung, ob du einem Spiel beitrittst oder nicht, beeinflussen.<br />
* Tritt nur Spielen bei, die du auch beenden willst.<br />
<br />
=== &nbsp;Als Mitspieler===<br />
* Verlasse Spiele nicht ohne Vorwarnung/Begründung (es kann passieren, dass man während eines Spiels manchmal aufhören will/muss, aber bitte lass das die anderen Spieler vorher wissen).<br />
* [[Competitive_Gaming#Cheating|Cheate]] nicht.<br />
=== &nbsp;Als Beobachter===<br />
* Respektiere die Spieler. Wenn du über die Partie reden möchtest, benutze den Chat für Beobachter. <br />
* Gib keine Informationen an die anderen Spieler weiter.<br />
<br />
==Ausnahme==<br />
<br />
Eins ist vom oben Genannten ausgenommen: &nbsp;''wenn du hundertprozentig sicher bist, dass du dieses Verhalten nur bei Leuten an den Tag legst, die du kennst'' '''''und''''' ''du weißt, dass es sie nicht stören wird, lass dich nicht aufhalten...''<br />
==Sanktionen==<br />
<br />
* Alle Spieler dürfen andere Spieler auf ihre Liste der Leute setzen, die sie ignorieren.<br />
* Alle [[#Liste der Server-Moderatoren|Server-Moderatoren]] können dich vom Server verbannen, bis du bewiesen hast, dass du dein beleidigendes Verhalten nicht wiederholen wirst.<br />
===<span style="font-size:95%">&nbsp;In Spielen</span>===<br />
* Der [[MP_Tutorial#Hosts|Host]] hat die Verantwortung über sein Spiel und kann jeden daraus hinauswerfen/verbannen. Das bedeutet aber nicht, dass er Spieler hinauswerfen darf, bloß weil er verloren hat oder ähnliches.<br />
* Die Server-Moderatoren sind die Polizei der Lobby, aber sie moderieren normalerweise nicht in einzelnen Partien, solange sie nicht überzeugt sind, dass der Verstoß über ein einzelnes Spiel hinausgeht.<br />
''Um entbannt zu werden, musst du [[#Liste der Server-Moderatoren|den Moderator]], der dich verbannt hat, als erstes benachrichtigen und erklären, warum er/sie dich entbannen sollte. Aber bitte versichere, dass er/sie einen Grund dazu hat: Entweder, indem du dich entschuldigst, oder, indem du zeigst, dass du es nicht wieder tun wirst.''<br />
<br />
==Hilfe==<br />
<br />
* Wenn du bei der Benutzung des Mehrspieler-Servers Beratung benötigst, wirf mal ein Auge auf unsere [[MP_Tutorial|Mehrspieler-Einführung]].<br />
* Um in der Lobby/im Spiel um den Beistand eines Moderators zu bitten (oder jemanden zu melden, der ausfallend/beleidigend wird), benutze das [[#command_head|/query adminmsg]]-Kommando.<br />
===<span style="font-size:96%">&nbsp;Hilfe auf IRC</span>===<br />
Der #wesnoth-mp-Kanal auf irc.libera.chat ist ein guter Platz, um Fragen rund um den Multiplayer-Server zu stellen.<br />
<br>Für Hilfe bei anderen Themen frage nach im #wesnoth-Kanal.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Als Einführung in IRC empfehlen wir [http://www.irchelp.org/irchelp/irctutorial.html diese Anleitung]. Merk dir einfach, dass das Server-Netzwerk, mit dem du dich verbinden musst, libera.chat ist, und, dass die wichtigen Kanäle #wesnoth-mp und #wesnoth sind.''<br />
<br />
==Weiterführend==<br />
Dieser Abschnitt enthält einige Mehrspieler-verwandte Themen, die dich interessieren könnten.<br />
<br />
===Nützliche Kommandos===<br />
<br />
Der Mehrspieler-Server von Wesnoth unterstützt einige nützliche Befehle, die bei Spielen oder Personen hilfreich sein können. Die nützlichsten sind:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Befehl'''</div><br />
||'''Beschreibung''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;in ein Nachrichtenfeld, entweder direkt in der Lobby oder durch drücken von 'm' in einer Partie, geschrieben'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''Text<br />
|Sendet die Nachricht 'Text' an alle verfügbaren Server-Moderatoren.&nbsp;&nbsp; <span style="font-size:80%">(Siehe [[ServerAdministration|hier]] für mehr /query-Kommandos.)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''Name&nbsp;Text<br />
|Schreibt die persönliche Nachricht 'Text' an 'Name'&nbsp;&nbsp; <span style="font-size:80%">(identisch mit /msg oder /whisper bzw. Doppelklick auf einen Namen)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''Name<br />
|Fügt 'Name' deiner Freundesliste hinzu &nbsp;<span style="font-size:90%">(so wird 'Name' oben in der Namensliste angezeigt)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''Name<br />
|Fügt 'Name' zur Liste derer hinzu, die du ignorierst &nbsp;<span style="font-size:90%">(so wird 'Name' ganz unten in der Namensliste angegeben, und du kannst Nachrichten, die von 'Name' geschrieben wurden, nicht sehen)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;in einer Kommandozeile, erreichbar durch drücken von ':' in einer Partie</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''Seite&nbsp;Name<br />
|Gibt 'Name' die Kontrolle über Seite 'Seite'.<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''Seite on<br />
|Gibt die Kontrolle über Seite 'Seite' an einen KI-Spieler.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''Seite''&nbsp;&nbsp;wechselt zwischen KI-Kontrolle und Kontrolle durch einen menschlichen Spieler hin und her.</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''Name<br />
|Entfernt 'Name' aus der momentanen Partie.<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''Name<br />
|Verbannt 'Name' aus dem Spiel, so dass 'Name' dieses Spiel solange die Verbannung dauert, nicht mehr betreten kann.&nbsp;<span style="font-size:90%">(der betreffende Spieler muss nicht im Spiel, aber auf dem Server sein)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|Schaltet das automatische Speichern aus. Kann bei großen Szenarien die Programmgeschwindigkeit verbessern.<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Für eine Liste von allgemeinen Mehrspieler-Kommandos siehe [[ChatCommands]] oder benutze den /help-Befehl in einer Partie oder der Lobby.<br><br />
&emsp;Für eine Liste von Spielkommandos siehe [[CommandMode]] oder benutze den :help-Befehl in einer Partie.<br><br />
<br />
</span><br />
<br />
<br />
----<br />
<br />
===Liste der Server-Moderatoren===<br />
<br />
Du kannst einzelne Moderatoren (oder alle zusammen) [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 über diese Forenseite] kontaktieren.<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Verwandte Seiten===<br />
<br />
* [[MP_Tutorial|Mehrspieler-Einführung]] (englisch)<br />
* [[Support|Betreuung]] (englisch)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Registrierung im Wesnoth-Forum] (englisch)<br />
* [[Competitive_Gaming/de|konkurrenzbasiertes Spielen]] (deutsch)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/pl&diff=67979MP CodeOfConduct/pl2021-05-24T08:40:33Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''Uwaga: Ta strona jest tłumaczeniem [[MP_CodeOfConduct|wersji angielskiej]], z którą należy się konsultować w razie niejasności.''<br />
<br />
==Wstęp==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">Poczekalnia gry wieloosobowej</div></div><br />
</div><br />
<br />
Na początku była tylko [[HeirToTheThrone|jedna kampania jednoosobowa]]. Obecnie mamy do dyspozycji serwer gry wieloosobowej, na którym może grać nawet 1000 graczy naraz.<br />
<br />
Choć Wesnoth jest grą dostępną na zasadach open-source, a serwer gry wieloosobowej jest dostępny bezpłatnie dla wszystkich, mimo wszystko potrzebne są pewne zasady. Przestrzeganie zasad podanych na tej stronie pozwoli wszystkim cieszyć się grą wieloosobową.<br />
<br />
==Zasady ogólne==<br />
<br />
* Bądź uprzejmy, szczególnie dla nieznajomych.<br />
* Przestrzegaj ogólnie przyjętych zasad zachowania na czatach, a więc nie spamuj innych wiadomościami ani nie pisz samymi <span style="font-size:108%">WIELKIMI LITERAMI</span>.<br />
* Nie używaj obraźliwych wyrazów w pseudonimach, tytułach map, etykietach ani rozmowach na czacie. Dotyczy to między innymi wulgaryzmów, obraźliwych odniesień religijnych oraz wyrażeń rasistowskich i seksistowskich.<br />
* Nie wykorzystuj serwera do promowania zewnętrznych przedsięwzięć komercyjnych ani niekomercyjnych. Serwer nie jest serwisem reklamowym.<br />
:: ''Na serwerze często grają również dzieci, przez co powyższe zasady są szczególnie istotne.''<br />
=== &nbsp;W poczekalni===<br />
* [[MP_Tutorial#The_lobby|Czat w poczekalni]] służy do umawiania się na grę, więc nie należy go używać do rozmów ogólnych lub prywatnych. Pogawędki można prowadzić podczas rozgrywki lub poprzez [[#command_head|wiadomości prywatne]].&nbsp;<br />
* Uważnie czytaj tytuły gier. Często zawierają one ważne informacje (np. „zarezerwowana” lub „będzie długo trwać”) i mogą wpłynąć na Twoją decyzję o dołączeniu się do danej gry.<br />
* Dołączaj się tylko do tych gier, w których zamierzasz uczestniczyć do końca.<br />
<br />
=== &nbsp;Jako gracz===<br />
* Nie opuszczaj gry bez uprzedzenia. Oczywiście każdemu może się zdarzyć, że musi lub chce opuścić grę, ale koniecznie trzeba o tym wcześniej powiadomić pozostałych graczy.<br />
* Nie [[Competitive_Gaming#Cheating|oszukuj]].<br />
<br />
=== &nbsp;Jako obserwator===<br />
* Okazuj grającym szacunek. Jeśli chcesz porozmawiać o grze, skorzystaj z czatu grupowego dla obserwatorów. <br />
* Nie wyjawiaj graczom żadnych informacji.<br />
<br />
==Wyjątek==<br />
<br />
Istnieje jeden wyjątek od powyższych zasad: ''jeśli masz całkowitą pewność, że Twoje zachowanie będzie widoczne wyłącznie dla znanych Ci osób'' '''''oraz''''' ''że te osoby nie będą miały do niego zastrzeżeń.''<br />
<br />
==Sankcje==<br />
<br />
* Każdy gracz może dodać każdego innego gracza do listy ignorowanych.<br />
* Każdy [[#List_of_server_moderators|moderator serwera]] ma prawo zbanować Cię z serwera, dopóki nie udowodnisz, że problematyczne zachowania się nie powtórzą.<br />
===<span style="font-size:95%">&nbsp;W trakcie rozgrywki</span>===<br />
* [[MP_Tutorial#Hosts|Gospodarz]] gry odpowiada za rozwiązywanie problemów i ma prawo wyrzucić lub zbanować dowolnego gracza ze swojej gry. Oczywiście dotyczy to tylko poważnych przewinień &mdash; graczy nie można wyrzucać ani banować np. za beznadziejną grę.<br />
* Moderatorzy serwera odpowiadają za porządek w poczekalni, ale zazwyczaj nie ingerują w zachowania graczy podczas rozgrywki, chyba że przewinienie ma charakter bardziej ogólny i wykracza poza zakres konkretnej gry.<br />
''Aby cofnąć otrzymanego bana, skontaktuj się z [[#List_of_server_moderators|moderatorem]], który Cię zbanował i wyjaśnij, dlaczego powinien Ci przywrócić dostęp. Pamiętaj, aby uzasadnić swoją prośbę, np. przepraszając lub wykazując, że takie zachowanie się nie powtórzy.''<br />
<br />
==Pomoc==<br />
<br />
*Jeśli potrzebujesz pomocy w korzystaniu z serwera gry wieloosobowej, zapoznaj się z [[MP_Tutorial|samouczkiem gry wieloosobowej]].<br />
*Aby poprosić moderatora o pomoc lub zgłosić przewinienie, skorzystaj z polecenia [[#command_head|/query adminmsg]] w poczekalni lub podczas gry.<br />
===<span style="font-size:96%">&nbsp;Zapytaj na IRC-u</span>===<br />
Kanał IRC #wesnoth-mp na serwerze irc.libera.chat to dobre miejsce do uzyskania pomocy dotyczącej serwera gry wieloosobowej.<br />
<br>Pomoc na inne tematy można uzyskać na kanale #wesnoth.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wprowadzenie do usługi IRC można znaleźć [http://www.irchelp.org/irchelp/irctutorial.html w tym samouczku]. Pamiętaj, że należy się połączyć z siecią serwerów libera.chat, a odpowiednie kanały to #wesnoth-mp i #wesnoth.''<br />
<br />
==Informacje dodatkowe==<br />
Ta sekcja zawiera dalsze informacje na temat gry wieloosobowej, które mogą się okazać przydatne.<br />
<br />
===Przydatne polecenia===<br />
<br />
Serwer gry wieloosobowej wesnoth obsługuje kilka poleceń, które przydają się do obsługi gier i kontaktów ze spotykanymi osobami. Najczęściej używane polecenia to:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Polecenie'''</div><br />
||'''Opis''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;wpisywane w polu wiadomości bezpośrednio w poczekalni lub po naciśnięciu „m” podczas gry'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''tekst<br />
|wysyła wiadomość o treści „tekst” do wszystkich dostępnych moderatorów serwera<br><span style="font-size:80%">(więcej poleceń /query znajdziesz na [[ServerAdministration|tej stronie]])</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''pseudonim&nbsp;tekst<br />
|wysyła wiadomość prywatną o treści „tekst” do użytkownika „pseudonim”<br><span style="font-size:80%">(synonim poleceń /msg i /whisper; można też dwukrotnie kliknąć pseudonim)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''pseudonim<br />
|dodaje użytkownika „pseudonim” do Twojej listy przyjaciół<br><span style="font-size:80%">(użytkownik „pseudonim” będzie wyświetlany na górze listy w poczekalni)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''pseudonim<br />
|dodaje użytkownika „pseudonim” do Twojej listy ignorowanych<br><span style="font-size:80%">(użytkownik „pseudonim” będzie wyświetlany na dole listy w poczekalni i nie będziesz widzieć jego wiadomości)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;wpisywane w polu poleceń po naciśnięciu „:” podczas gry</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''strona&nbsp;pseudonim<br />
|przekazuje kontrolę nad stroną numer „strona” użytkownikowi „pseudonim”<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''strona on<br />
|przekazuje kontrolę nad stroną numer „strona” komputerowi<br><span style="font-size:80%">&nbsp;&nbsp;'''''droid''''' ''strona''&nbsp;&nbsp;powoduje przełączanie między kontrolą przez człowieka i komputer</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''pseudonim<br />
|usuwa gracza „pseudonim” z bieżącej gry<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''pseudonim<br />
|usuwa gracza „pseudonim” z bieżącej gry i uniemożliwia mu ponowne dołączenie do niej<br><span style="font-size:80%">(gracz musi się znajdować na serwerze, ale niekoniecznie w grze)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|wyłącza funkcję automatycznego zapisu, co czasami przyspiesza grę na dużych mapach<br />
|}<br />
<br />
<span style="font-size:95%"><br />
Listę poleceń serwera gry wieloosobowej zawiera temat [[ChatCommands]]. Możesz też skorzystać z polecenia /help w poczekalni lub w polu czatu podczas gry.<br><br />
Listę poleceń podczas gry zawiera temat [[CommandMode]]. Możesz też skorzystać z polecenia :help podczas gry.<br><br />
<br />
</span><br />
<br />
<br />
----<br />
<br />
===Lista moderatorów serwera===<br />
<br />
Z poszczególnymi moderatorami lub całą grupą moderatorów możesz się skontaktować poprzez [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 tę stronę forum].<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Strony pokrewne===<br />
<br />
* [[MP_Tutorial|Samouczek gry wieloosobowej]] (po angielsku)<br />
* [[Support|Zasoby pomocy]] (po angielsku)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Forum Wesnoth &mdash; rejestracja]<br />
* [[Competitive_Gaming|Zasady gry sportowej]] (po angielsku)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/it&diff=67978MP CodeOfConduct/it2021-05-24T08:40:15Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''Questa pagina è una traduzione in italiano dell'originale [[MP_CodeOfConduct|inglese]]. Se sei insicuro su qualche punto, sei pregato di fare riferimento alla [[MP_CodeOfConduct|versione originale]] o [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=110788 inviare un messaggio] al manutentore attuale di questa traduzione ('''mich''') nel forum.''<br />
<br />
==Introduzione==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">La lobby multigiocatore</div></div><br />
</div><br />
<br />
Inizialmente non esisteva altro che un'unica campagna per giocatore singolo. Ora invece abbiamo a disposizione un server multigiocatore capace di ospitare più di 1000 giocatori contemporaneamente.<br />
<br />
Sebbene Wesnoth sia un gioco open-source e chiunque possa utilizzare il server liberamente, ciò non significa che non ci sia bisogno di alcune regole. Le seguenti regole servono per garantire ad ognuno una piacevole esperienza di gioco multigiocatore.<br />
<br />
==Regole Generali==<br />
<br />
* Sii educato, specialmente con persone che non conosci.<br />
* Rispetta le normali regole delle chat: evita lo spam e non scrivere tutto <span style="font-size:108%">IN MAIUSCOLO</span>.<br />
* Non utilizzare i nick, i titoli delle partite, le etichette o la chat in modo potenzialmente offensivo. Questo include maledire/imprecare, fare offensivi riferimenti religiosi, fare discriminazioni di razza o genere.<br />
* Non abusare del server per pubblicizzare imprese commerciali o non-commerciali. Non è uno strumento pubblicitario.<br />
:: ''ci sono sempre molti bambini che giocano sul server, quindi presta sempre grande attenzione alle regole sopra menzionate.''<br />
=== &nbsp;Nella Lobby===<br />
* L'[[MP_Tutorial#The_lobby|area di chat della lobby]] serve per organizzare partite, quindi cerca di evitare di usarla per conversazioni generali o private. Puoi fare queste conversazioni dentro le partite, o usare i [[#command_head|messaggi privati]].&nbsp;<br />
* Leggi i titoli delle partite. A volte contengono informazioni utili (ad es. "riservata", "richiede molto tempo", ...) e questo può modificare la tua decisione di partecipare oppure no.<br />
* Entra solo nelle partite che intendi giocare fino alla fine.<br />
<br />
=== &nbsp;Come Giocatore===<br />
* Non abbandonare una partita senza prima avvisare (sappiamo che a volte vuoi/hai necessità di uscire, ma per favore fai in modo che gli altri giocatori lo sappiano in anticipo).<br />
* Non [[Competitive_Gaming#Cheating|barare]].<br />
<br />
=== &nbsp;Come osservatore===<br />
* Rispetta i giocatori. Se vuoi parlare della partita, usa la chat privata degli osservatori.<br />
* Non fornire informazioni ai giocatori.<br />
<br />
==Eccezioni==<br />
<br />
C'è un'eccezione alle regole menzionate: &nbsp;''se sei assolutamente sicuro che solo persone che conosci avranno a che fare col tuo comportamento'' '''''e''''' ''sai per certo che a loro sta bene, allora fai pure...''<br />
<br />
==Sanzioni==<br />
<br />
* Tutti i giocatori possono metterne altri nella loro lista degli utenti da ignorare.<br />
* Tutti i [[#Lista_dei_moderatori_del_server|moderatori del server]] possono bannarti dal server fino a che non avrai provato che non ripeterai più il comportamento offensivo.<br />
===<span style="font-size:95%">&nbsp;In gioco</span>===<br />
* Il giocatore che ospita la partita ([[MP_Tutorial#Hosts|host]]) è incaricato di mantenere l'ordine e può espellere/bannare chiunque dalla partita. In ogni caso questo non vuol dire che gli sia consentito espellere/bannare giocatori perché sta perdendo o simili atti di abuso delle sue prerogative.<br />
* I moderatori del server controllano la lobby ma solitamente non controllano le partite a meno che non vengano convinti che l'offesa vada oltre lo scopo della singola partita.<br />
''Per far rimuovere il tuo ban devi contattare [[#Lista_dei_moderatori_del_server|il moderatore]] che ti ha bannato e spiegargli perché dovrebbe toglierti il ban, ma sei pregato di avere una motivazione valida, sia questa il fornire delle scuse o mostrare che non ripeterai più le tue azioni.''<br />
<br />
==Ricevere aiuto==<br />
<br />
*Se hai bisogno di una guida su come usare il server multigiocatore, potrebbe interessarti la nostra [[MP_Tutorial|guida alla partita multigiocatore]].<br />
*Per chiedere assistenza ad un moderatore (o riportare un trasgressore del regolamento) nella lobby/partita, usa il comando[[#command_head|/query adminmsg]].<br />
===<span style="font-size:96%">&nbsp;Chiedere su IRC</span>===<br />
Il canale #wesnoth-mp sulla rete irc.libera.chat è un buon posto dove chiedere aiuto ed informazioni riguardo al server multigiocatore.<br />
<br>Per avere aiuto su altri aspetti del gioco, prova il canale #wesnoth.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Per una guida introduttiva all'utilizzo di IRC, suggeriamo [http://www.irchelp.org/irchelp/irctutorial.html questa guida]. Ricorda solo che la rete di server a cui connettersi è libera.chat ed i canali #wesnoth-mp e #wesnoth.''<br />
<br />
==Informazioni ulteriori==<br />
Questa sezione contiene altre informazioni riguardanti il gioco multigiocatore che potrebbero interessarti.<br />
<br />
===Comandi utili===<br />
<br />
Il server multigiocatore di wesnoth supporta parecchi comandi che possono esserti di aiuto.<br />
I più utili sono:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Comando'''</div><br />
||'''Descrizione''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;scritto direttamente in un riquadro di immissione testo, sia direttamente in lobby o premendo 'm' durante una partita'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''testo<br />
|manda il messaggio 'testo' a tutti i moderatori disponibili.&nbsp;&nbsp; <span style="font-size:80%">(leggi [[ServerAdministration|questa pagina]] per maggiori informazioni sul comando /query.)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''nick&nbsp;testo<br />
|invia un messaggio privato 'testo' a 'nick'&nbsp;&nbsp; <span style="font-size:80%">(identico ad utilizzare /msg o /whisper) (puoi anche fare doppio click sul nick)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''nick<br />
|aggiunge 'nick' alla tua lista degli amici &nbsp;<span style="font-size:90%">(in modo che 'nick' verrà visualizzato in cima alla lista dei giocatori presenti in lobby)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''nick<br />
|aggiunge 'nick' alla tua lista delle persone da ignorare &nbsp;<span style="font-size:90%">(così che 'nick' sia mostrato al termine della lista di persone presenti in lobby e tu non veda i messaggi scritti da 'nick')</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;scritto in un riquadro di immissione comandi, aperto premendo ':' durante una partita</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''side&nbsp;nick<br />
|dai a 'nick' il controllo del side numero 'side'<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''side on<br />
|dai il controllo del side numero 'side' all'AI.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''side''&nbsp;&nbsp;passa il controllo da AI a umano e viceversa a seconda di chi ha attualmente il controllo</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''nick<br />
|rimuovi il giocatore 'nick' dalla partita corrente<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''nick<br />
|rimuovi e previeni che rientri nella partita in corso il giocatore 'nick' &nbsp;<span style="font-size:90%">(non è necessario che il giocatore sia nella partita, ma basta sia collegato al server)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|disabilita la funzione di salvataggio automatico, può essere utile per velocizzare il gioco nel caso di grandi scenari<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Per una lista completa dei comandi multigiocatore puoi leggere [[ChatCommands]] o usare il comando /help durante una partita o nella lobby.<br><br />
&emsp;Per una lista di comandi puoi leggere [[CommandMode]] o usare il comando :help durante una partita.<br><br />
<br />
</span><br />
<br />
<br />
----<br />
<br />
===Lista dei moderatori del server===<br />
<br />
Puoi contattare un qualsiasi moderatore o l'intero gruppo dei moderatori usando [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 questa pagina del forum].<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Collegamenti===<br />
<br />
* [[MP_Tutorial|Guida partite multigiocatore]] (inglese)<br />
* [[Support|Supporto]] (inglese)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Forum ufficiale di wesnoth - registrazione] (inglese)<br />
* [[Competitive_Gaming|Gioco Competitivo]] (inglese)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/pl&diff=67977MP CodeOfConduct/pl2021-05-24T08:39:55Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''Uwaga: Ta strona jest tłumaczeniem [[MP_CodeOfConduct|wersji angielskiej]], z którą należy się konsultować w razie niejasności.''<br />
<br />
==Wstęp==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">Poczekalnia gry wieloosobowej</div></div><br />
</div><br />
<br />
Na początku była tylko [[HeirToTheThrone|jedna kampania jednoosobowa]]. Obecnie mamy do dyspozycji serwer gry wieloosobowej, na którym może grać nawet 1000 graczy naraz.<br />
<br />
Choć Wesnoth jest grą dostępną na zasadach open-source, a serwer gry wieloosobowej jest dostępny bezpłatnie dla wszystkich, mimo wszystko potrzebne są pewne zasady. Przestrzeganie zasad podanych na tej stronie pozwoli wszystkim cieszyć się grą wieloosobową.<br />
<br />
==Zasady ogólne==<br />
<br />
* Bądź uprzejmy, szczególnie dla nieznajomych.<br />
* Przestrzegaj ogólnie przyjętych zasad zachowania na czatach, a więc nie spamuj innych wiadomościami ani nie pisz samymi <span style="font-size:108%">WIELKIMI LITERAMI</span>.<br />
* Nie używaj obraźliwych wyrazów w pseudonimach, tytułach map, etykietach ani rozmowach na czacie. Dotyczy to między innymi wulgaryzmów, obraźliwych odniesień religijnych oraz wyrażeń rasistowskich i seksistowskich.<br />
* Nie wykorzystuj serwera do promowania zewnętrznych przedsięwzięć komercyjnych ani niekomercyjnych. Serwer nie jest serwisem reklamowym.<br />
:: ''Na serwerze często grają również dzieci, przez co powyższe zasady są szczególnie istotne.''<br />
=== &nbsp;W poczekalni===<br />
* [[MP_Tutorial#The_lobby|Czat w poczekalni]] służy do umawiania się na grę, więc nie należy go używać do rozmów ogólnych lub prywatnych. Pogawędki można prowadzić podczas rozgrywki lub poprzez [[#command_head|wiadomości prywatne]].&nbsp;<br />
* Uważnie czytaj tytuły gier. Często zawierają one ważne informacje (np. „zarezerwowana” lub „będzie długo trwać”) i mogą wpłynąć na Twoją decyzję o dołączeniu się do danej gry.<br />
* Dołączaj się tylko do tych gier, w których zamierzasz uczestniczyć do końca.<br />
<br />
=== &nbsp;Jako gracz===<br />
* Nie opuszczaj gry bez uprzedzenia. Oczywiście każdemu może się zdarzyć, że musi lub chce opuścić grę, ale koniecznie trzeba o tym wcześniej powiadomić pozostałych graczy.<br />
* Nie [[Competitive_Gaming#Cheating|oszukuj]].<br />
<br />
=== &nbsp;Jako obserwator===<br />
* Okazuj grającym szacunek. Jeśli chcesz porozmawiać o grze, skorzystaj z czatu grupowego dla obserwatorów. <br />
* Nie wyjawiaj graczom żadnych informacji.<br />
<br />
==Wyjątek==<br />
<br />
Istnieje jeden wyjątek od powyższych zasad: ''jeśli masz całkowitą pewność, że Twoje zachowanie będzie widoczne wyłącznie dla znanych Ci osób'' '''''oraz''''' ''że te osoby nie będą miały do niego zastrzeżeń.''<br />
<br />
==Sankcje==<br />
<br />
* Każdy gracz może dodać każdego innego gracza do listy ignorowanych.<br />
* Każdy [[#List_of_server_moderators|moderator serwera]] ma prawo zbanować Cię z serwera, dopóki nie udowodnisz, że problematyczne zachowania się nie powtórzą.<br />
===<span style="font-size:95%">&nbsp;W trakcie rozgrywki</span>===<br />
* [[MP_Tutorial#Hosts|Gospodarz]] gry odpowiada za rozwiązywanie problemów i ma prawo wyrzucić lub zbanować dowolnego gracza ze swojej gry. Oczywiście dotyczy to tylko poważnych przewinień &mdash; graczy nie można wyrzucać ani banować np. za beznadziejną grę.<br />
* Moderatorzy serwera odpowiadają za porządek w poczekalni, ale zazwyczaj nie ingerują w zachowania graczy podczas rozgrywki, chyba że przewinienie ma charakter bardziej ogólny i wykracza poza zakres konkretnej gry.<br />
''Aby cofnąć otrzymanego bana, skontaktuj się z [[#List_of_server_moderators|moderatorem]], który Cię zbanował i wyjaśnij, dlaczego powinien Ci przywrócić dostęp. Pamiętaj, aby uzasadnić swoją prośbę, np. przepraszając lub wykazując, że takie zachowanie się nie powtórzy.''<br />
<br />
==Pomoc==<br />
<br />
*Jeśli potrzebujesz pomocy w korzystaniu z serwera gry wieloosobowej, zapoznaj się z [[MP_Tutorial|samouczkiem gry wieloosobowej]].<br />
*Aby poprosić moderatora o pomoc lub zgłosić przewinienie, skorzystaj z polecenia [[#command_head|/query adminmsg]] w poczekalni lub podczas gry.<br />
===<span style="font-size:96%">&nbsp;Zapytaj na IRC-u</span>===<br />
Kanał IRC #wesnoth-mp na serwerze irc.libera.chat to dobre miejsce do uzyskania pomocy dotyczącej serwera gry wieloosobowej.<br />
<br>Pomoc na inne tematy można uzyskać na kanale #wesnoth.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wprowadzenie do usługi IRC można znaleźć [http://www.irchelp.org/irchelp/irctutorial.html w tym samouczku]. Pamiętaj, że należy się połączyć z siecią serwerów freenode, a odpowiednie kanały to #wesnoth-mp i #wesnoth.''<br />
<br />
==Informacje dodatkowe==<br />
Ta sekcja zawiera dalsze informacje na temat gry wieloosobowej, które mogą się okazać przydatne.<br />
<br />
===Przydatne polecenia===<br />
<br />
Serwer gry wieloosobowej wesnoth obsługuje kilka poleceń, które przydają się do obsługi gier i kontaktów ze spotykanymi osobami. Najczęściej używane polecenia to:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Polecenie'''</div><br />
||'''Opis''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;wpisywane w polu wiadomości bezpośrednio w poczekalni lub po naciśnięciu „m” podczas gry'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''tekst<br />
|wysyła wiadomość o treści „tekst” do wszystkich dostępnych moderatorów serwera<br><span style="font-size:80%">(więcej poleceń /query znajdziesz na [[ServerAdministration|tej stronie]])</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''pseudonim&nbsp;tekst<br />
|wysyła wiadomość prywatną o treści „tekst” do użytkownika „pseudonim”<br><span style="font-size:80%">(synonim poleceń /msg i /whisper; można też dwukrotnie kliknąć pseudonim)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''pseudonim<br />
|dodaje użytkownika „pseudonim” do Twojej listy przyjaciół<br><span style="font-size:80%">(użytkownik „pseudonim” będzie wyświetlany na górze listy w poczekalni)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''pseudonim<br />
|dodaje użytkownika „pseudonim” do Twojej listy ignorowanych<br><span style="font-size:80%">(użytkownik „pseudonim” będzie wyświetlany na dole listy w poczekalni i nie będziesz widzieć jego wiadomości)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;wpisywane w polu poleceń po naciśnięciu „:” podczas gry</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''strona&nbsp;pseudonim<br />
|przekazuje kontrolę nad stroną numer „strona” użytkownikowi „pseudonim”<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''strona on<br />
|przekazuje kontrolę nad stroną numer „strona” komputerowi<br><span style="font-size:80%">&nbsp;&nbsp;'''''droid''''' ''strona''&nbsp;&nbsp;powoduje przełączanie między kontrolą przez człowieka i komputer</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''pseudonim<br />
|usuwa gracza „pseudonim” z bieżącej gry<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''pseudonim<br />
|usuwa gracza „pseudonim” z bieżącej gry i uniemożliwia mu ponowne dołączenie do niej<br><span style="font-size:80%">(gracz musi się znajdować na serwerze, ale niekoniecznie w grze)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|wyłącza funkcję automatycznego zapisu, co czasami przyspiesza grę na dużych mapach<br />
|}<br />
<br />
<span style="font-size:95%"><br />
Listę poleceń serwera gry wieloosobowej zawiera temat [[ChatCommands]]. Możesz też skorzystać z polecenia /help w poczekalni lub w polu czatu podczas gry.<br><br />
Listę poleceń podczas gry zawiera temat [[CommandMode]]. Możesz też skorzystać z polecenia :help podczas gry.<br><br />
<br />
</span><br />
<br />
<br />
----<br />
<br />
===Lista moderatorów serwera===<br />
<br />
Z poszczególnymi moderatorami lub całą grupą moderatorów możesz się skontaktować poprzez [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 tę stronę forum].<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Strony pokrewne===<br />
<br />
* [[MP_Tutorial|Samouczek gry wieloosobowej]] (po angielsku)<br />
* [[Support|Zasoby pomocy]] (po angielsku)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Forum Wesnoth &mdash; rejestracja]<br />
* [[Competitive_Gaming|Zasady gry sportowej]] (po angielsku)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct/vi&diff=67976MP CodeOfConduct/vi2021-05-24T08:39:34Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>{{Translations}}<br />
''Đây không phải là bản Code of Conduct (Quy định về cách ứng xử) nguyên gốc mà là bản dịch tiếng Việt của nó. Nếu bạn cảm thấy khó hiểu về bất cứ quy định nào dưới đây, xin hãy tham khảo trang [http://wiki.wesnoth.org/MP_CodeOfConduct Code of Conduct nguyên gốc] hoặc đưa ra câu hỏi [http://forums.wesnoth.org/viewtopic.php?f=7&t=33523 ở đây].<br />
Mọi ý kiến/đóng góp liên quan đến bản dịch tiếng Việt này xin hãy gửi đến cho [http://forums.wesnoth.org/ucp.php?i=pm&mode=compose&u=117382 hhyloc]''<br />
<br />
==Giới thiệu==<br />
<br />
<div class="thumb tright"><div><br />
[http://hdvirtual.freewebhostx.com/files/battleforwesnothmultijogador004.png http://hdvirtual.freewebhostx.com/files/180px-Battleforwesnothmultijogador011.png]<br />
<div class="thumbcaption">Phòng đợi nhiều người chơi</div></div><br />
</div><br />
<br />
Ban đầu, chẳng có gì khác ngoài [[HeirToTheThrone|một chiến dịch một người chơi]]. Giờ thì chúng tôi đã có một máy chủ có thể hổ trợ cùng lúc hơn 1000 người chơi.<br />
Mặc dù Wesnoth là một trò chơi nguồn mở và mọi người chơi đều được sử dụng máy chủ, điều đó không có nghĩa là chúng tôi không cần quy định nào cả. Vì thế những quy định dưới đây được đưa ra nhằm đảm bảo mọi người có được sự thoải mái khi chơi qua mạng.<br />
<br />
==Quy định chung==<br />
<br />
* Hãy lịch sự, đặc biệt là với những người bạn không biết.<br />
* Tuân theo quy định chung khi chat: Không spam hãy viết nội dung chat toàn bằng <span style="font-size:108%">CHỮ HOA</span>.<br />
* Không sử dụng những tên nick, tên bản đồ, nhãn, hay những nội dung chat xúc phạm: Bao gồm nội dung thô tục/chửi thề, ý kiến công kích tôn giáo, phân biệt chủng tộc, phân biệt giới tính.<br />
* Không sử dụng máy chủ vào mục đích buôn bán hay quảng cáo. Đây không phải là dịch vụ quảng cáo.<br />
:: ''thường xuyên có trẻ em chơi trên máy chủ, vì thế những quy định trên là rất quan trọng''<br />
=== &nbsp;Trong phòng đợi===<br />
* [[MP_Tutorial#The_lobby|Khu vực chat của phòng đợi]] được sử dụng để sắp xếp các trò chơi, vì vậy hãy tránh sử dụng nó cho mục đích chat chung chung hoặc cá nhân. Thay vào đó, chat trong game hoặc dùng chức năng [[#command_head|tin nhắn cá nhân]].&nbsp;<br />
* Đọc kỹ tiêu đề của mỗi trò chơi. Đôi khi chúng chứa những thông tin quan trọng (vd: "dành riêng cho", "sẽ tốn rất nhiều thời gian", ...) và có thể ảnh hưởng đến quyết định của bạn liệu có nên tham gia trò chơi đó hay không.<br />
* Chỉ tham gia trò chơi mà bạn muốn chơi hết.<br />
<br />
=== &nbsp;Đối với người chơi===<br />
* Không bỏ chơi giữa chừng mà không báo trước (chúng tôi biết rằng đôi khi bạn muốn/cần rời đi, nhưng xin hãy báo trước cho những người chơi khác).<br />
* Không [[Competitive_Gaming#Cheating|gian lận]].<br />
<br />
=== &nbsp;Đối với người quan sát===<br />
* Tôn trọng người chơi. Nếu bạn muốn nói về trò chơi, sử dụng chức năng chat riêng với từng đội. <br />
* Đừng để lộ thông tin của người chơi.<br />
<br />
==Ngoại lệ==<br />
<br />
Có một ngoại lệ đối với những điều trên: &nbsp;''nếu bạn chắc chắn rằng chỉ những người bạn biết mới sẽ gặp kiểu ứng xử của bạn'' '''''và''''' ''bạn biết họ sẽ không phàn nàn gì, vậy thì không cần ngại...''<br />
<br />
==Quyền lợi==<br />
<br />
* Mọi người chơi đều có quyển đưa bất kỳ ai vào danh sách từ chối của mình<br />
* Tất cả [[#Danh%20s%C3%A1ch%20qu%E1%BA%A3n%20tr%E1%BB%8B%20vi%C3%AAn%20m%C3%A1y%20ch%E1%BB%A7|điều hành viên]] có thể cấm bạn vào chơi trên máy chủ cho đến khi bạn chứng tỏ rằng mình sẽ không lặp lại cách ứng xử xúc phạm một lần nửa.<br />
===<span style="font-size:95%">&nbsp;Trong trò chơi</span>===<br />
* [[MP_Tutorial#Hosts|Người chủ trò chơi]] có trách nhiệm giải quyết những vấn đề nảy sinh và có thể đuổi/cấm bất cứ ai trong trò chơi của mình. Tuy nhiên không được đuổi/cấm ai chỉ vì họ đang thua hoặc đuổi/cấm họ mà không có lý do thỏa đáng.<br />
* Các điều hành viên giữ trật tự cho phòng đợi nhưng thường thì không kiểm tra các trò chơi trừ khi họ tin rằng những hành vi xúc phạm vượt quá mức độ trong một trò chơi.<br />
''Để được dỡ bỏ hình phạt bị cấm thì bạn phải liên lạc [[#Danh%20s%C3%A1ch%20qu%E1%BA%A3n%20tr%E1%BB%8B%20vi%C3%AAn%20m%C3%A1y%20ch%E1%BB%A7|quản trị viên]] mà đã cấm bạn và giải thích tại sao người ấy nên dỡ bỏ hình phạt cấm đối với bạn, nhưng hãy đảm bảo rằng người ấy có lý do để làm vậy, bằng cách xin lỗi hoặc thể hiện rằng bạn sẽ không lặp lại lỗi đã gây ra.''<br />
<br />
<br />
==Trợ giúp==<br />
<br />
*Nếu bạn cần trợ giúp trong việc chơi mạng trên máy chủ, hãy thử đọc [[MP_Tutorial|hướng dẫn chơi mạng]] (Tiếng Anh).<br />
*Để nhờ quản trị viên giúp đỡ (hay báo cáo một người chơi gây rối) trong phòng đợi/trò chơi, sử dụng lệnh [[#command_head|/query adminmsg]].<br />
===<span style="font-size:96%">&nbsp;Hỏi trên IRC</span>===<br />
Kênh #wesnoth-mp trêm irc.libera.chat là một nơi thích hợp để đưa ra câu hỏi liên quan đến máy chủ nhiều người chơi.<br />
<br>Để nhờ trợ giúp về các vấn đề khác, hãy vào #wesnoth channel.<br><br />
''&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Để làm quen với IRC, chúng tôi khuyên bạn nên đọc [http://www.irchelp.org/irchelp/irctutorial.html hướng dẫn này] (Tiếng Anh). Hãy nhớ rằng bạn cần phải kết nối vào máy chủ freenode và kênh là #wesnoth-mp và #wesnoth''<br />
<br />
==Thông tin bổ sung==<br />
Dưới đây chứa một số thông tin liên quan đến chế độ nhiều người chơi mà có thể hữu ích cho bạn.<br />
<br />
===Các lệnh hữu ích===<br />
<br />
Máy chủ nhiều người chơi hỗ trợ một số lệnh hữu ích để sử dụng trong trò chơi hoặc đối với những người chơi khác. Những lệnh hữu ích nhất là:<br />
<br />
{| align="center" {{Prettytable}}<br />
|-<br />
|style="background-color:#ffaf00;"|<div id="command_head">'''Lệnh'''</div><br />
||'''Mô tả''' <br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| '''&emsp;&emsp;&emsp;gõ nội dung vào hộp thoại, bằng cách gõ nội dung trực tiếp trong phòng đợi hoặc nhấn phím 'm' trong trò chơi'''<br />
|-<br />
|style="background-color:#ceecff;" |'''/query&nbsp;adminmsg&nbsp;'''nội dung<br />
|gửi một tin nhắn với mang nội dung là 'nội dung' tới tất cả quản trị viên máy chủ.&nbsp;&nbsp; <span style="font-size:80%">(Xem [[ServerAdministration|trang này]] (Tiếng Anh) để tìm hiểu hơn về các lệnh /query .)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/m&nbsp;'''tên người chơi&nbsp;nội dung<br />
|viết một tin nhắn cá nhân có nội dung là 'nội dung' đến 'tên người chơi'&nbsp;&nbsp; <span style="font-size:80%">(tương tự như /msg hay /whisper) (cũng có thể nhấp đôi vào tên người chơi)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/friend&nbsp;'''tên người chơi<br />
|đưa 'tên người chơi' vào danh sách bạn bè &nbsp;<span style="font-size:90%">(làm vậy để 'tên người chơi luôn đứng đầu trong danh sách người chơi trong phòng đợi)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''/ignore&nbsp;'''tên người chơi<br />
|đưa 'tên người chơi' vào danh sách từ chối &nbsp;<span style="font-size:90%">(làm vậy để 'tên người chơi luôn nằm dưới cùng của danh sách người chơi trong phòng đợi và bạn sẽ không thấy những thông điệp do 'tên người chơi' viết)</span><br />
|-<br />
| colspan="2" style="background-color:#ffeda9;"| <div id="command_type_2>'''&emsp;&emsp;&emsp;gõ vào hộp lệnh hay nhấn phím ':' trong trò chơi</div>'''<br />
|-<br />
|style="background-color:#ceecff;" |'''control&nbsp;'''phe&nbsp;tên người chơi<br />
|giao quyền điều khiển cho 'tên người chơi' đối với 'phe'<br />
|-<br />
|style="background-color:#ceecff;" |'''droid&nbsp;'''phe on<br />
|giao quyền điều khiển cho máy đối với 'phe'.<span style="font-size:83%">&nbsp;&nbsp;'''''droid''''' ''phe''&nbsp;&nbsp;chuyển đổi giữa người chơi điều khiển hay máy điều khiển</span><br />
|-<br />
|style="background-color:#ceecff;" |'''kick&nbsp;'''tên người chơi<br />
|đuổi 'tên người chơi' khỏi trò chơi hiện tại<br />
|-<br />
|style="background-color:#ceecff;" |'''ban&nbsp;'''tên người chơi<br />
|đuổi và cấm 'tên người chơi' tham gia lại vào trò chơi hiện tại &nbsp;<span style="font-size:90%">(người chơi không nhất thiết phải đang ở trong trò chơi mà cũng có thể đang ở trên máy chủ)</span><br />
|-<br />
|style="background-color:#ceecff;" |'''nosaves'''<br />
|tắt chức năng lưu tự động, có thể hữu ích trong những màn chơi dài<br />
|}<br />
<br />
<span style="font-size:95%"><br />
&emsp;Để xem danh sách những lệnh dùng trong chế độ nhiều người chơi xin hãy xem [[CommandMode]] hay dùng lệnh /help trong trò chơi hay trong phòng đợi.<br><br />
&emsp;Để xem danh sách những lệnh dùng trong trò chơi xin hãy xem [[CommandMode]] hay dùng lệnh :help trong trò chơi.<br><br />
<br />
</span><br />
<br />
<br />
----<br />
===Danh sách quản trị viên máy chủ===<br />
<br />
Bạn có thể liên lạc bất kỳ quản trị viên nào hay cả nhóm quản trị viên bằng cách dùng [http://forums.wesnoth.org/memberlist.php?mode=group&g=6651 chức năng này] (Tiếng Anh).<br />
<br />
{{:MP_CodeOfConduct/mods}}<br />
<br />
===Các trang liên quan===<br />
<br />
* [[MP_Tutorial|Hướng dẫn chơi mạng]] (Tiếng Anh)<br />
* [[Support|Hỗ trợ]] (Tiếng Anh)<br />
* [http://forum.wesnoth.org/ucp.php?mode=register Đăng ký trên diễn đàn Wesnoth] (Tiếng Anh)<br />
* [[Competitive_Gaming|Chơi đối kháng]] (Tiếng Anh)<br />
<br />
<br />
<br />
<br />
[[Category:Playing Wesnoth]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=GCI/Port_AI_WML_configuration_to_new_style_syntax&diff=67975GCI/Port AI WML configuration to new style syntax2021-05-24T08:38:39Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>=Use wesnoth 1.9.2 or work on trunk version.=<br />
You can download 1.9.2 from here: http://wiki.wesnoth.org/Download#Development_.281.9_branch.29 <br />
<br />
<br />
Wesnoth uses a custom markup language called WML, which can be edited by hand (it's similar to xml)<br />
<br />
AI configuration can be written using WML.<br />
<br />
In 2009, a new style syntax for writing AI configurations in Wesnoth was created.<br />
<br />
New syntax is described on http://wiki.wesnoth.org/Customizing_AI_in_Wesnoth_1.8<br />
<br />
Old syntax is described on http://wiki.wesnoth.org/AiWML<br />
<br />
We need to convert existing AI syntax to new style.<br />
<br />
The preferred way to do it is to teach wesnoth's custom WML conversion tool, wmllint, (written in python) to do it, or to write a helper script to do it. Or it can be done by hand. In any case, human review is required, to see that everything is ok.<br />
<br />
As an example of the conversion process, you can use the first scenario of Legend of Wesmere campaign:<br />
<br />
before, it contained:<br />
<br />
[ai]<br />
village_value=0<br />
leader_value=0<br />
protect_leader=0<br />
[avoid]<br />
x=1-30,1-30,1-3,7-30<br />
y=1-13,17-30,1-30,1-30<br />
[/avoid]<br />
[/ai]<br />
<br />
after:<br />
<br />
{ai/aliases/stable_singleplayer.cfg}<br />
[ai]<br />
{AI_SIMPLE_ALWAYS_ASPECT village_value 0}<br />
{AI_SIMPLE_ALWAYS_ASPECT leader_value 0}<br />
{AI_SIMPLE_ALWAYS_ASPECT_VALUE avoid (<br />
x=1-30,1-30,1-3,7-30<br />
y=1-13,17-30,1-30,1-30<br />
)}<br />
[/ai]<br />
<br />
Or, if we had separate config for 'night' time of day ( time_of_day=dusk,first_watch,second_watch)<br />
<br />
before:<br />
[ai]<br />
recruitment_pattern=scout,fighter,fighter,archer,mixed fighter<br />
[/ai]<br />
[ai]<br />
time_of_day=dusk,first_watch,second_watch<br />
aggression=0.75<br />
caution=0.0<br />
grouping=offensive<br />
[/ai]<br />
<br />
after:<br />
{ai/aliases/stable_singleplayer.cfg}<br />
[ai]<br />
{AI_SIMPLE_NIGHT_ASPECT aggression 0.75}<br />
{AI_SIMPLE_NIGHT_ASPECT caution 0}<br />
{AI_SIMPLE_NIGHT_ASPECT grouping offensive}<br />
{AI_SIMPLE_ALWAYS_ASPECT recruitment_pattern "scout,fighter,fighter,archer,mixed fighter"}<br />
[/ai]<br />
<br />
you might need to ask questions about how a particular tag should be converted, ask '''Crab_''' on #wesnoth-dev on libera.chat.<br />
<br />
= Conversion procedure =<br />
In general, we need to add {ai/aliases/stable_singleplayer.cfg} outside the ai tag.<br />
then, for each ai tag, we need to look if it's 'for all times or day' or for particular time of day.<br />
then, if it's an aspect, just use the appropriate form of<br />
{AI_SIMPLE_NIGHT_ASPECT aspect_name aspect_value}<br />
{AI_SIMPLE_DAY_ASPECT aspect_name aspect_value}<br />
{AI_SIMPLE_ALWAYS_ASPECT aspect_name aspect_value}<br />
==list of aspects which are converted that way==<br />
aggression<br />
<br />
attack_depth<br />
<br />
[avoid]<br />
<br />
caution<br />
<br />
grouping<br />
<br />
leader_aggression<br />
<br />
leader_goal<br />
<br />
leader_value<br />
<br />
number_of_possible_recruits_to_force_recruit<br />
<br />
passive_leader<br />
<br />
passive_leader_shares_keep<br />
<br />
recruitment_ignore_bad_combat<br />
<br />
recruitment_ignore_bad_movement<br />
<br />
recruitment_pattern<br />
<br />
scout_village_targeting<br />
<br />
simple_targeting<br />
<br />
support_villages<br />
<br />
village_value<br />
<br />
villages_per_scout<br />
<br />
[target]\[protect_..] tags are converted to [goal] tags, see the new-style docs for details.<br />
<br />
for other AI parameters, figure it out or ask Crab_ on #wesnoth-dev on IRC at libera.chat<br />
<br />
= Notes (23rd November) = <br />
everything should be converted. if it's unclear how to convert something, ask. <br />
<br />
for attack_depth, you can convert it in the same way as aggression or, in the specific case '3 for easy, 4 for medium, 5 for hard', use {AI_SCALE_ATTACK_DEPTH_BY_DIFFICULTY} macro<br />
<br />
ai goal syntax is at http://wiki.wesnoth.org/Customizing_AI_in_Wesnoth_1.8#AI_goals_.28_via_.5Bgoal.5D_tags_.29<br />
<br />
to test the changes, you don't have to recompile - hitting F5 from main menu or restarting should be enough to refresh the cache and pick up new changes to WML code.<br />
<br />
you can use :inspect - it allows you to see the ai configuration and you can compare the results of your changes vs the results of the 'upgrade' procedure written in c++ - by using :inspect two times, with and without your changes<br />
<br />
Also, you're welcome to show incomplete results for review (link to these in google's task tracker)<br />
<br />
If something varies by difficulty, or uses QUANTITY macro, e.g. {QUANTITY aggression 0.55 0.75 0.85} convert it using the ON_DIFFICULTY macro {AI_SIMPLE_ALWAYS_ASPECT aggression {ON_DIFFICULTY 0.55 0.75 0.85} }<br />
<br />
= Notes (24th November) = <br />
convert {NO_SCOUTS} to {AI_NO_SCOUTS}<br />
= Notes (25th November) =<br />
{ai/aliases/stable_singleplayer.cfg} should be given inside [side] tag, inside each [side] tag where there's at least one [ai] tag.<br />
<br />
please test your changes by loading every and each scenario from wesnoth to see if it loads without errors (use debug mode ':n' command to switch levels)<br />
<br />
protect_leader and protect_leader_radius<br />
<br />
are converted differently (see [[Customizing_AI_in_Wesnoth_1.8#protect_my_unit_.5Bgoal.5D]] )<br />
<br />
<br />
if the block includes '''turns=''', then this block is active only during the specific turns.<br />
<br />
To deal with them:<br />
<br />
1) write a wml event to change the AI on the turn where it changes.<br />
<br />
2) use more low-level macros (deal with [facet] tags ) to specify the active turns for each of the time periods.<br />
<br />
= Notes (29th November) =<br />
To convert [ai] blocks which have turns=, you can the [aspect] tag directly without the macros:<br />
<br />
[aspect]<br />
id=aggression<br />
[facet]<br />
value = 0.4<br />
time_of_day="dawn, morning, afternoon"<br />
turns=1-12<br />
[/facet]<br />
[facet]<br />
value = 0.7<br />
time_of_day="dusk,first_watch,second_watch"<br />
turns=1-12<br />
[/facet]<br />
[facet]<br />
value = 0.9<br />
turns=13-FOREVER<br />
[/facet]<br />
[/aspect]<br />
<br />
<br />
<br />
To handle adjacent '[avoid]' sections, combine them using the [or] filter<br />
<br />
converting:<br />
<br />
[avoid]<br />
x,y=1,11<br />
[/avoid]<br />
[avoid]<br />
x,y=21,31<br />
[/avoid]<br />
[avoid]<br />
x,y=41,51<br />
[/avoid]<br />
<br />
to<br />
<br />
{AI_SIMPLE_ALWAYS_ASPECT_VALUE avoid<br />
(<br />
x,y=1,11<br />
[or]<br />
x,y=21,31<br />
[/or]<br />
[or]<br />
x,y=41,51<br />
[/or]<br />
)}<br />
<br />
[[Category: GCI]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=FriulianTranslation&diff=67974FriulianTranslation2021-05-24T08:37:34Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>= Wesnoth par Furlan =<br />
<br />
In cheste pagjine wiki si puedin cjatâ informazions sore la traduzion par furlan dal zûc "La batae par Wesnoth".<br />
<br />
La traduzion je pene scomençade, zontiti al grop di traduzion! ^_^<br />
<br />
== Current translation team ==<br />
=== Tradutôrs atîfs ===<br />
Par cumò dome:<br />
* Michele Calligaris ([[User:MayBug]]) - mailto:michele.calligaris-CAIUT-gmail.com<br />
<br />
<br />
Statistichis sul stât de traduzion par furlan:<br />
[http://gettext.wesnoth.org/index.lang.php?lang=fur_IT&version=trunk Cjale]<br />
== Stât de traduzion ==<br />
[http://gettext.wesnoth.org/index.lang.php?lang=fur_IT&version=trunk Statistichis]<br />
<br />
== Dubis inte traduzion ==<br />
<br />
* Hit -> Bati ?<br />
* Strike -> Bati ?<br />
* Interact -> Interagjî?<br />
* Undead -> No-muart / Spirt muart ?<br />
<br />
=== Unitâts ===<br />
Liste des unitâts dal zuc:<br />
<br />
* Liste des [http://wesnoth.slack.it/units.cgi unitâts dal zuc]<br />
<br />
* lista des [[unitâts bielzà voltadis]]<br />
<br />
=== Carateristichis (Traits) ===<br />
<br />
{| align="center"<br />
! align="right" | Strong<br />
| fuart<br />
|-<br />
! align="right" | Quick<br />
| svelt<br />
|-<br />
! align="right" | Resilient<br />
| resistent<br />
|-<br />
! align="right" | Intelligent<br />
| inteligjent<br />
|-<br />
! align="right" | Loyal<br />
| leâl<br />
|-<br />
! align="right" | Dextrous<br />
| agjil<br />
|-<br />
! align="right" | Undead<br />
| no-muart<br />
|-<br />
! align="right" | Fearless<br />
| ardît<br />
|-<br />
! align="right" | Healty<br />
| san<br />
|}<br />
<br />
=== Tips di dam ===<br />
<br />
{| align="center"<br />
! align="right" | Blade<br />
| tai<br />
|-<br />
! align="right" | Piercing<br />
| sbusade<br />
|-<br />
! align="right" | Impact<br />
| bote<br />
|-<br />
! align="right" | Cold<br />
| frêt<br />
|-<br />
! align="right" | Fire<br />
| fûc<br />
|-<br />
! align="right" | Arcane<br />
| tenebre<br />
|}<br />
<br />
=== Armis speciâls ===<br />
<br />
{| align="center"<br />
! align="right" | Backstab <br />
|atac par daûr<br />
|-<br />
! align="right" | Berserk<br />
|furie<br />
|-<br />
! align="right" | Charge<br />
| cjarie<br />
|-<br />
! align="right" | Drain<br />
| supe<br />
|-<br />
! align="right" | Firststrike<br />
| atac di bot<br />
|-<br />
! align="right" | Magical<br />
| magjic<br />
|-<br />
! align="right" | Marksman<br />
| smicjade<br />
|-<br />
! align="right" | Plague<br />
| plaie<br />
|-<br />
! align="right" | Poison<br />
| velen<br />
|-<br />
! align="right" | Slow<br />
| intarde<br />
|-<br />
! align="right" | Stone<br />
| piere<br />
|-<br />
! align="right" | Swarm<br />
| scjap<br />
|}<br />
<br />
<br />
=== Abilitâts ===<br />
<br />
{| align="center"<br />
! align="right" | Ambush<br />
| vuaite<br />
|-<br />
! align="right" | Cures<br />
| cure<br />
|-<br />
! align="right" | Heals<br />
| medeâ<br />
|-<br />
! align="right" | Illuminates<br />
| ilumine<br />
|-<br />
! align="right" | Leadership<br />
| comant<br />
|-<br />
! align="right" | Nightstalk<br />
| vuaite noturne<br />
|-<br />
! align="right" | Regenerates<br />
| rinove<br />
|-<br />
! align="right" | Skirmisher<br />
| ladron<br />
|-<br />
! align="right" | Steadfast<br />
| fermece<br />
|-<br />
! align="right" | Submerge<br />
| somierzi<br />
|-<br />
! align="right" | Teleport<br />
| teletraspuart<br />
|-<br />
|}<br />
<br />
=== Corezions di fâ ===<br />
<br />
Se o volês judâ/segnalâ falis inte traduzione, o podês scrivi un mesaç culì opure dentri dal forum uficiâl. <br />
<br />
* Post de traduzion furlane dal Forum Uficiâl: [http://www.wesnoth.org/forum/viewtopic.php?f=7&t=21419 Wesnoth par Furlan]<br />
<br />
<br />
== Contats ==<br />
* E-mail: michele.calligaris -caiut - gmail.com<br />
* IRC: Canâl #wesnoth sul server irc.libera.chat<br />
* Ultim inzornament par cure di MayBug<br />
<br />
[[Category:Translations]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=CampaignEditor&diff=67973CampaignEditor2021-05-24T08:36:55Z<p>Vasya: freenode -> libera.chat</p>
<hr />
<div>== Me == <br />
<br />
Good day,<br />
<br />
My name is Jon Kivinen and I'm a freshman software engineering student at Lakehead University (http://www.lakeheadu.ca/) in Thunder Bay, ON, Canada (http://en.wikipedia.org/wiki/Thunder_Bay%2C_Ontario).<br />
<br />
I'm interested in Google Summer of Code and a big fan of Wesnoth (LAN party favourite).<br />
<br />
==== Languages (Tongue) ====<br />
<br />
* English (first)<br />
* French (use simple sentences in active voice with common objects)<br />
<br />
==== Languages (Bits) ====<br />
<br />
* Python (stuff with wxPython, Django)<br />
* C/C++<br />
<br />
==== Past Experience ====<br />
<br />
To learn Python and wxPython I tried to write a Gin Rummy game. It was neglected after I tried to add network support (after the fact -- /collar tug). It's been a while since I touched it and most of the original code is 2 years old: I've developed my trade since.<br />
<br />
http://rummy-py.sourceforge.net/<br />
<br />
=== Hours ===<br />
<br />
I'm usually up from 07:00 EST to 00:00 EST (12:00 UTC to 05:00 UTC) but this is subject to change in the summer months.<br />
<br />
=== Contact ===<br />
<br />
==== IM ====<br />
<br />
irc.libera.chat<br />
* jkiv<br />
<br />
==== Forum ====<br />
<br />
*jkiv <br />
<br />
==== Gna! ====<br />
<br />
*jkiv<br />
<br />
==== Website ====<br />
<br />
*Personal: http://jkiv.ca<br />
*Academic: http://flash.lakeheadu.ca/~jlkivine<br />
<br />
== Campaign Editor ==<br />
<br />
Being interested in Qt4, I'd like to try to write the UI in Qt4. Nevertheless, I'm open to discussing with those doing map editor improvements what would be the best choice if the two tools were to be merged in the future.<br />
<br />
=== Interface ===<br />
<br />
I picture the main interface consisting of three parts:<br />
<br />
* Campaign Flow Editor<br />
* Map<br />
* Action List<br />
<br />
===== Definitions =====<br />
<br />
* Campaign - a collection of ordered scenarios<br />
* Scenario - a map with an objective<br />
<br />
* Action -- aka. event<br />
* Path -- aka. branch<br />
* "Try agains" -- aka. game overs, you're deads<br />
<br />
==== Campaign Flow ====<br />
<br />
The campaign flow pane would be a flow chart representation of the scenarios of the campaign.<br />
<br />
Scenarios can be attached to other scenarios (or branches), allowing for conditional paths. More paths will be available if the leading scenario has more than one victory and/or defeat event associated with it. A path can be associated with any number of victory/defeat events.<br />
<br />
Unassociated defeats will be "try agains" by default.<br />
<br />
==== Map ====<br />
<br />
The map shows initial character placements, etc, for actions and scenario events. This panel is complementary to the next panel. This panel contains an overlay illustrating set actions will be present in this panel.<br />
<br />
==== Actions List ====<br />
<br />
This pane lists (in a tree?) actions you can add to the scenario. In a drag/drop fashion, one can drag actions onto the map to associate the tile or character on the tile (ambiguities will be handled through action context or dialog).<br />
<br />
ie, for characters,<br />
<br />
*Victory<br />
**Death of associated unit<br />
<br />
*Victory<br />
**Protect<br />
***No. Turns<br />
<br />
*Defeat<br />
**Death of associated unit<br />
<br />
ie, for land, <br />
*Victory<br />
**Hold<br />
***Radius<br />
***Unit<br />
****(of Class)<br />
****(of Type)<br />
***No. Turns<br />
<br />
Aside from unit/tile based actions, world actions can be defined. These include any action that isn't unit/tile specific.<br />
<br />
ie,<br />
*number of turns before defeat<br />
*preambles between characters<br />
<br />
I would aim for this list to be expandable/future-safe.<br />
<br />
=== Possible Features In Future ===<br />
<br />
Some features that would be nice to see included, but won't be priority include some of the following:<br />
<br />
* UMC server integration (package/upload)<br />
* class/unit editor<br />
** attributes, animations, etc.<br />
* map editor integration<br />
<br />
[[Category:Summer of Code]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=PortugueseContinentalTranslation&diff=67972PortugueseContinentalTranslation2021-05-24T08:36:19Z<p>Vasya: /* Contactos */</p>
<hr />
<div>==Bem-Vindo==<br />
<br />
Bem-vindo à página de apresentação da tradução para português europeu do jogo "A Batalha por Wesnoth".<br />
<br />
O esforço da tradução pretende oferecer aos utilizadores de "Wesnoth" a possibilidade de jogarem o jogo na sua língua nativa e numa versão localizada ao seu país. Desta forma pretende-se que a experiência de jogo seja melhor e que mais pessoas possam usufruir deste jogo.<br />
<br />
<br />
É com prazer que a equipa anuncia que a tradução portuguesa está completa a partir da versão 1.10.6 !<br />
<br />
Todos podem ajudar neste processo, seja oferecendo o seu tempo a trabalhar ativamente na tradução, seja através de sugestões, dicas e indicações de pequenos erros ou falhas existentes.<br />
<br />
===Equipa da tradução===<br />
<br />
====Ativos====<br />
<br />
* trewe (maintainer) [mailto:sjrs456ATyahooDOTfr]<br />
<br />
<br />
====Estado desconhecido====<br />
<br />
* knitter aka Sérgio Lopes [mailto:knitter.isATgmailDOTcom]<br />
* Carlos Sousa<br />
* Luís Passos<br />
* lokakuu<br />
* alfalb (tradutor/revisor de prova) [mailto:alfredoDOTsilvaATskyDOTcom]<br />
* Manuela Silva [mailto:manuelaPONTOsilvaAROBAskyPONTOcom]<br />
<br />
=== Contactos ===<br />
Para contactar a equipa de tradução basta enviarem um e-mail para o endereço acima ou através do IRC no servidor da libera.chat, canal #wesnoth (generalista) ou #wesnoth-pt.<br />
Alternativamente, pode-se utilizar a mailinglist do [http://sourceforge.net/projects/wesn-pt-trans/ sourceforge] (lento).<br />
<br />
== Regras para os Tradutores ==<br />
As seguintes regras pretendem introduzir futuros colaboradores no processo de tradução. São um ponto de partida a verificar, no entanto, qualquer dúvida pode ser colocada por e-mail ou na lista de discussão.<br />
<br />
=== Processo Geral ===<br />
<br />
[[WesnothTranslationsHowTo]]<br />
<br />
=== Processo da Equipa de Português ===<br />
<br />
A tradução portuguesa faz uso do sistema de controlo [http://git-scm.com/ Git] e os ficheiros atuais da tradução podem ser obtidos no repositório da [https://github.com/trewe/wesn-pt-trans Github].<br />
<br />
Após terem obtido o(s) ficheiro(s) *.po(s) estes podem ser abertos com o editor preferido para começar a traduzir, [http://www.poedit.net PoEdit] ou [http://translate.sourceforge.net/wiki/virtaal/index Virtaal], são bons exemplos de programas de código aberto e plataforma múltipla que poderão usar.<br />
<br />
Quando iniciarem a tradução dum ficheiro, embora não seja necessário, é aconselhável que notifiquem um dos membros aqui listados. Quando terminarem uma tradução basta que enviem o ''patch'' para o responsável pelo projeto, (trewe à data de escrita deste texto) para que os ficheiros sejam incluídos no repositório.<br />
<br />
O livre acesso ao repositório será fornecido após pedido e avaliação do trabalho feito.<br />
<br />
==Estilos e vocabulário==<br />
<br />
Como o jogo decorre num ambiente medieval será boa ideia utilizar um vocabulário e estilo pendente, especialmente na prosa para manter o espírito do jogo.<br />
<br />
Os objetivos dos cenários e dos comandos gerais são sempre dirigidos ao utilizador com o sujeito subentendido.<br />
<br />
Nomes próprios normalmente mantêm-se, ou então são aportuguesados. Exceções podem sempre existir dependo do contexto.<br />
<br />
A tradução existente das unidades pode ser encontrada na [http://units.wesnoth.org/trunk/mainline/pt_PT/mainline.html Lista das Unidades] que é automaticamente gerada periodicamente.<br />
<br />
===Discurso direto===<br />
<br />
Elfos - hipercorrectos e até algo «poético».<br />
<br />
Orcs - Normal mas com forte tendência pro-drop e utilização dos tempos compostos.<br />
<br />
Gnomos - Como os Orcs mas mais submissos.<br />
<br />
Trogloditas e Ogres - Sempre no infinitivo e na terceira pessoa (exceções confirmam a regra), evitam a passiva.<br />
<br />
Silvanos (Wose) - Forte adjetivação.<br />
<br />
Dragos - Metafóricos<br />
<br />
Répteis e Nagas - ênfase nos 'erres' e 'zês'.<br />
<br />
Anões - dialeto transmontano<br />
<br />
Humanos - Nada de especial (depende da posição social)<br />
<br />
Morto-Vivos - Nada de especial (como em vida), talvez algo submissos; os magos são humanos.<br />
<br />
===Datas do Jogo===<br />
<br />
{|<br />
| BW (Before Wesnoth)<br />
| AW (Antes do Reino de Wesnoth)<br />
|-<br />
| AW (After Wesnoth)<br />
| CW ([segundo a] Cronologia de Wesnoth / nas crónicas de Wesnoth)<br />
|-<br />
|}<br />
<br />
==Estado da tradução==<br />
<br />
=== Lista de Traduções ===<br />
<br />
A lista seguinte, pretende mostrar todas as traduções existentes ou futuras do jogo.<br />
<br />
[http://www.wesnoth.org/gettext/index.lang.php?version=master&package=&lang=pt Estatísticas da tradução]<br />
<br />
[[WesnothTranslations]]<br />
<br />
== Hiperligações Diversas ==<br />
<br />
[[Category:Translations]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=WhatArePlayersSaying_Old&diff=67970WhatArePlayersSaying Old2021-05-24T08:34:42Z<p>Vasya: </p>
<hr />
<div>"Lots of potential"<br />
<br />
"Now it's in development and its good, when it's done it'll be great. The team that work on this project (the coders,<br />
graphic artists, porters) are pretty passionate about this and that's part of what makes it so great, bugs are<br />
continually being worked out at a good pace and new features are implemented quickly, especially considering that they<br />
basically do this for free. Another reason why this is so great is that it's a free, open-source, multiplatform project."<br />
<br />
"At it's current state a lot of things could be better, the graphics, the GUI, and the documentation, although I found it<br />
to be pretty stable. All things considered though, especially that it's still a beta, the entire BoW team should be<br />
commended."<br />
<br />
-- Kishina about 0.7.8 at [[VersionTracker]].com<br />
<br />
<br />
"One to try!"<br />
<br />
"The numerous changes have improved virtually every area of the game. It is maturing into an extremely fine game."<br />
<br />
"This is definitely one to try."<br />
<br />
-- [[BornAgain]] about 0.7.7 at [[VersionTracker]].com<br />
<br />
<br />
"what's up with the game telling me i need v. .72 to play multiplayer when v. .72 doesn't *exist* yet?? how does v. .71<br />
of the game know v. .72's going to be able to play multiplayer??"<br />
<br />
"these folks are windoze developers - that much is clear."<br />
<br />
-- plaintiger about 0.7.2 at [[VersionTracker]].com<br />
<br />
"Maybe that is because..."<br />
<br />
"...the Mac OS X version lags a bit behind the Windoze and Linux versions? BoW 0.72 is available for Win and Linux since<br />
April 8th"<br />
<br />
-- haemophilus about 0.7.2 at [[VersionTracker]].com<br />
<br />
"Lots of improvements!"<br />
<br />
"Hey, the Mac version just jumped to 0.7.3 Multiplayer.. was that really such a long wait? Give the developer(s) a<br />
little slack geesh! It takes time to develope multiplatform."<br />
<br />
"With so many improvements it shoulda been v0.8"<br />
<br />
-- Xapplimatic about 0.7.3 at [[VersionTracker]].com<br />
<br />
<br />
"it is easy to play. i have ADD and don't deal well with games that require me to think about 17,000,000 things at once;<br />
this game makes commanding a whole bunch of units spread out over a map much easier and less harrowing than some others<br />
i've tried. the graphics aren't exactly cutting-edge, but they're not primitive either - quite fine, i think...and the<br />
gameplay's simple - you basically just generate units, move, and fight. BFW doesn't make you think about a lot of<br />
extraneous stuff - it just lets you relax and play. i'm not really even into this kind of game any more; i just try one<br />
once in a while to make sure i won't like it - and i like BFW. not everybody's tastes are the same, and i can't really<br />
know what you like in a game, but i recommend downloading this one - start the d/l before you go to bed or something and<br />
just let it go for however long it takes - and checking it out. it's quite likeable"<br />
<br />
-- [[AppleBeer]] about 0.6.99.5CVS at [[VersionTracker]].com<br />
<br />
<br />
"open source Master of Monsters"<br />
<br />
"There was a console game about 15 years ago called Master of Monsters. fantasy TBS. hex map with terrain tiles. You<br />
play a leader who summons critters (elves, wizards, trolls, etc) to fight for you. Critters gain experience and progress<br />
to stronger forms. If this sounds fun to you, Wesnoth does it quite well."<br />
<br />
-- fuy about 0.7.1 at [[VersionTracker]].com<br />
<br />
<br />
"Great fun"<br />
<br />
"The story is great and the depth involved with different units having certain strengths is admirable...i recomend it to<br />
anyone who can have fun without high polygon counts and eyecandy"<br />
<br />
-- Mavent04 about 0.6.99 at [[VersionTracker]].com<br />
<br />
<br />
"It is quite nice"<br />
<br />
"This is pretty impressive for a freeware game. It also runs without any problem in OSX 1.5. Any additional improvements<br />
from the author would only be icing on the cake"<br />
<br />
-- hkim about 0.6.1 at [[VersionTracker]].com<br />
<br />
<br />
"Nice little game, can't beat the price"<br />
<br />
"Cute turn-based tactical game in the tradition of Strategic Conquest, with quality comparable to [[FreeCiv]]"<br />
<br />
-- fuy about 0.5.2CVS at [[VersionTracker]].com<br />
<br />
<br />
"Way to go"<br />
<br />
"This fixes all the glitches that bugged me with the previous 0.5 version. The AI seems a bit tougher though, which<br />
isn't a bad thing. I love the unit experience level aspect. Keep up the good work, people"<br />
<br />
-- pdot about 0.5.2CVS at [[VersionTracker]].com<br />
<br />
<br />
"A lot of potential"<br />
<br />
"Some interface and performance issues aside, Wesnoth has the makings of a nice tactics game in the Ogre Battle genre.<br />
One of the better open source productions, with a nice-looking tileset and decent game dynamics already in place."<br />
<br />
-- [[EricWong]] about 0.5 at [[VersionTracker]].com<br />
<br />
<br />
"Cool game"<br />
<br />
"Ok, as for the game. For me - cool. Fast, stable, good entertainment. I was played it Yesterday and I like it. And its<br />
price - unbeatable :))) Keep up good work :)"<br />
<br />
-- mroczny about 0.4.9CVS2 at [[VersionTracker]].com<br />
<br />
<br />
"It took a little getting used to the 10 year old graphics, but in terms of fun, it's pretty good. It reminds me of a<br />
mix between Warlords and Warcraft. There are speed issues with the game. For instance, waiting for the AI enemies to<br />
move and attack takes way too long. It's helpful to see what the computer is doing, but a speed-up in that area would<br />
make the game more enjoyable. There's also a problem with responsiveness of the mouse. I find myself clicking the same<br />
unit or option more than once. As for stability, it ran fine the 2 times I played the tutorial, but it's stalling right<br />
now in the first campaign scenario. I switched to Firebird to write this review while it is the computer's turn and it's<br />
stalling. I was surfing the net earlier while the game was running so I guess it's just a random glitch. I look forward<br />
to playing the next version"<br />
<br />
-- pdot about 0.4.9CVS2 at [[VersionTracker]].com<br />
<br />
<br />
"Awesome game"<br />
<br />
-- Nice about 0.7.7 at [[MacGameFiles]].com<br />
<br />
<br />
"Simple, easy to learn, yet plenty of room for tactics. Multiplayer is also fun and easy, provided you get a friend on<br />
the server at the same time as you."<br />
<br />
-- Shadowdancer about 0.7.2 at [[MacGameFiles]].com<br />
<br />
<br />
"This bored the crap out of me. And there doesn't seem to be a way to move your units all at once. One at a time, one at<br />
a time. I mean, bravo for the open source effort, but, make it more fun... and make it with less fantasy dork-cheese<br />
(big punchline, "Elf: Humans are obviously less skilled." HAHAHAHA OH.. wait.. that's not funny.)"<br />
<br />
-- citric about 0.7.2 at [[MacGamefiles]].com<br />
<br />
"How do you propose to "make it more fun", citric? Multiplayer is a blast and single-player is good, too... This is one<br />
of the best turn-based strategy games out there."<br />
<br />
-- Ol'Sammy about 0.7.2 at [[MacGameFiles]].com<br />
<br />
<br />
"Great game. The pinnacle of open-source gaming."<br />
<br />
-- Gafgarion about 0.6.99.5 at [[MacGameFiles]].com<br />
<br />
<br />
"Absolutely love it. It had some visual glitches at first, but this version fixed them. Now that I can play in windowed<br />
mode, I find the game to be a great way to kill time, and the story so far has me wanting to see more."<br />
<br />
-- Naman about 0.6.99.4 at [[MacGameFiles]].com<br />
<br />
<br />
"It's a fantasy strategy game with rpg elements (units level and can be carried over into following missions (in<br />
campaigns)).. And it has elves! Bloody cool looking elves!"<br />
<br />
"And it's available for a lot of platforms. Mac, Windows, Linux.. and there's a multiplayer feature, too!"<br />
<br />
-- Na'enthos Telenin at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"Heh, not a bad game...reminds me of Ogre Tactics."<br />
<br />
-- Marn Skullstomp at World of Warcraft Roleplaying Association forum<br />
<br />
"looks alittle low tech dont it?"<br />
<br />
-- Larod at World of Warcraft Roleplaying Association forum<br />
<br />
"Yeah, but just because it's 2D and stuff doesn't mean it can't be fun."<br />
<br />
-- Marn Skullstomp at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"I have been playing it the whole day and I really enjoy it. It is fun and really hard to beat. I am in the orcish<br />
campaign. "<br />
<br />
-- Dharko at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"W3 wasn't all good of a RTS anyway. This game is better."<br />
<br />
-- Gothic-Shadow at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"I will be soon enough. I'm still learning and playing through some of the campaign. Damn this game is fun."<br />
<br />
-- Kazrak Heldenhammer at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"Fun game... although it sometimes gets pretty damn hard"<br />
<br />
-- Kaeldorn at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"Fun game, but orcs are a bit overpowered."<br />
<br />
-- Fenix Fireborn at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"Hey! I saw you on the wesnoth forums. How did you find this site? Let alone at the same time we were talking about<br />
wesnoth. Are you psychic?"<br />
<br />
-- Kazrak Heldenhammer at World of Warcraft Roleplaying Association forum<br />
<br />
"We have eyes and ears reporting to us... we are everywhere =)"<br />
<br />
-- Miyo at World of Warcraft Roleplaying Association forum<br />
<br />
<br />
"the best game I have ever played"<br />
<br />
"For a long time i've wanted to play a clever and original tactical game. Wesnoth is all of that... and it comes with a<br />
nice storyline too!! Well, what else can i say, i don't have time for this... i gotta play :-P"<br />
<br />
-- Onnellinen at The Linux Game Tome<br />
<br />
<br />
"Fabulous Game"<br />
<br />
"Most fun I have every had playing a turn based strategy game."<br />
<br />
-- lisap511 at The Linux Game Tome<br />
<br />
<br />
"Good fun!!!!!!!"<br />
<br />
"Very original and well done game. Excellent sound, graphics and gameplay. Hours of fun."<br />
<br />
-- mdhowe at The Linux Game Tome<br />
<br />
<br />
"Best free Linux game"<br />
<br />
"Great work ! That is the best free Linux game I've ever played."<br />
<br />
-- [[ScaChi]] at The Linux Game Tome<br />
<br />
<br />
"Impressive work!"<br />
<br />
"Awesome strategy game. A must-play for everyone who enjoys a turn-based challenge of exceptional quality! :)"<br />
<br />
-- Cironir at The Linux Game Tome<br />
<br />
<br />
"I am Impressed!!!!"<br />
<br />
"After more the a Year reading the Linux game tome, i finnaly created a account to rate this Game. It ist great!!! 5<br />
Stars from Austria for this masterpiece of Software. At last there are some Words that are not Translated to German. Do<br />
you need a Tranlater?"<br />
<br />
-- xeniac at The Linux Game Tome<br />
<br />
<br />
"Musics! Argh!"<br />
<br />
"An awesome game, but I can't play it, because the musics break my ears and nerves. The theme music is great, and some<br />
other musics are good too, but eg. wesnoth-3 wesnoth-4 and wesnoth-6 are awful! Please recompose them."<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"This is awesome"<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"This game is a stupendous achievement!"<br />
<br />
"This one is set to be your new favorite. I can't wait for some of the new campaign scenarios. Don't wait for the 1.0<br />
release, do yourself a favor and download and compile this one ASAP. Holy cow this game is great!"<br />
<br />
-- Dou9st3r at The Linux Game Tome<br />
<br />
<br />
"Great game - what more is to be said?"<br />
<br />
-- [[TomSauer]] at The Linux Game Tome<br />
<br />
<br />
"Wesnoth is one of the best fantasy turn-based strategy games I've ever played. Can't wait for it to reach 1.0!"<br />
<br />
-- jbmesserly at The Linux Game Tome<br />
<br />
<br />
"Awesome Game!!! Provides Linux with what it lacks... Quality gaming"<br />
<br />
-- z9484 at The Linux Game Tome<br />
<br />
<br />
"Great"<br />
<br />
"Wesnoth battle is A great game! I hope the guys to continoue their good job!"<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"just awesome and getting better :)"<br />
<br />
-- lynx_lupo at The Linux Game Tome<br />
<br />
<br />
"Best freeware game I've yet played"<br />
<br />
"The "easy" level could be a bit easier, however :) But by no means is the "easy" level outragously difficult, as it is<br />
in freeciv."<br />
<br />
-- mathandmetal at The Linux Game Tome<br />
<br />
<br />
"Great gameplay"<br />
<br />
"Simple rules, but many interesting tactics. Graphics are clear and pleasant and the game is very polished. This is my<br />
favorite hex-tactics game."<br />
<br />
-- karlb at The Linux Game Tome<br />
<br />
<br />
"Simple, but awesome"<br />
<br />
"I love it :) Pretty graphics for a free game."<br />
<br />
-- deline at The Linux Game Tome<br />
<br />
<br />
"excellent game, i loved it. Reminds me of old classics like the first warcraft mixed with a little Myth+Magic.kinda.<br />
anyhoo, xcellent game, with no unreasonable dependencys, in fact modern distros will have them already in most cases, or<br />
will be able get them through rpm/rpmdrake or apt-get. Install was pleasant also. If i had time i would love to create<br />
level sets for it:-)"<br />
<br />
-- rokknroll at The Linux Game Tome<br />
<br />
<br />
"excellent game"<br />
<br />
"Nice graphic and well developed scenarious. I love the game and played it to the end in two days. I like the level<br />
structure of the units. But it's a pity that there are max tree levels, five or seven will be O.K."<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"Great game!!"<br />
<br />
"Graphics are great and it is easy to get used to play. The interface can be translated to many languages. A must<br />
download game!"<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"This game has great playability - I keep returning to it. And it runs fine on my old Pentium 1."<br />
<br />
-- m487396 at The Linux Game Tome<br />
<br />
<br />
"KISS"<br />
<br />
"This game is exactly like I like games to be - rich, but still simply, lot of fun for beginners and advanced alike. The<br />
KISS principle makes this game almost perfect - and ideas, hard work etc. make it absolutely perfect :) Thank you."<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"Great game"<br />
<br />
"If you like this kind of game, it's a must-try."<br />
<br />
-- Errabes at The Linux Game Tome<br />
<br />
<br />
"I just can say that this is a great pice of work! Spent nights on playing the campaign!"<br />
<br />
-- mschmitt at The Linux Game Tome<br />
<br />
<br />
"Excellent, but need to improve"<br />
<br />
"Very nice, I spent some hours on the campaign. I'll collect some suggestions and send them to the authors. This game is<br />
well-designed and implemented. It just suffers for its small life-time (version number seems correct). I'm sure that<br />
once at version 1.0 this game will be one of the best around!"<br />
<br />
-- johnny at The Linux Game Tome<br />
<br />
<br />
"Unbelievable!"<br />
<br />
"Just download it and try it! Believe it: this game is the best of its class and its very very very much polished! Yes,<br />
it doesn't look like the average free software games! Excelent work guys!"<br />
<br />
-- terrible at The Linux Game Tome<br />
<br />
<br />
"cool!"<br />
<br />
"Amazingly polished.... much better that your average open-source game. Looking foward to 1.0 , although it's already<br />
loads of fun! :D"<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"Great game!!!"<br />
<br />
"Great work!!! One of the nicest Games (commercial or not) I have ever played - getting better by the minute ;)))<br />
Cheers, afa"<br />
<br />
-- afa at The Linux Game Tome<br />
<br />
<br />
"Excellent"<br />
<br />
"This is a great game. Good strategy concept, good graphics and sound. And most important: very addictive and playable.<br />
Keep up the good work."<br />
<br />
-- mbabuskov at The Linux Game Tome<br />
<br />
<br />
"Excellent as Bexcellent"<br />
<br />
"Keep up the good work! This game is truly appreciated. It is extremely qualatatious (meaning it is full of quality)."<br />
<br />
-- Anonymous at The Linux Game Tome<br />
<br />
<br />
"Really an excellent game - my choice for relax moment from work."<br />
<br />
-- Polaris at The Linux Game Tome<br />
<br />
<br />
"I need a game which could be played on my piii notebook. I need a game which could be played in Linux. And I found<br />
wesnoth. I like this game. Very Good."<br />
<br />
-- zhangyuan at The Linux Game Tome<br />
<br />
<br />
"Incredible"<br />
<br />
"This game has good graphics, excellent gameplay, nice single-player campaigns (which is a rarity for free games), the<br />
code and data infrastructure is great, and the community really pushes hard. This is the Next Big Thing, I'm pretty<br />
sure. Oh, and of course I'm addicted. Hey, this has something like 115 different units! And character development! And<br />
they're so damnably cute..."<br />
<br />
-- therealmawa at The Linux Game Tome<br />
<br />
<br />
"Very nice game"<br />
<br />
"I like the campaing mode of the game very much. It's the first game where I've encountered a campaing mode in which the<br />
result in one level defines the chances for next one. Only downside is that it consumes too much free time. ;-)"<br />
<br />
-- torangan at The Linux Game Tome<br />
<br />
<br />
"Absolutely addictive"<br />
<br />
"Installed it and played 10 hours straight, forgetting everything else around me."<br />
<br />
-- basramm at The Linux Game Tome<br />
<br />
<br />
"My whole family really enjoys this game, particularly the oldest three children, my 9yo boy, and 12 and 13yo girls. It<br />
fires up their imaginations -- my boy has started introducing Wesnoth characters into his sketches. Maybe some of his<br />
art will someday make it into the game. :)"<br />
<br />
"It would be a stretch to call this game "educational", but I do appreciate any game that makes the kids think. At<br />
first, I didn't think my 9yo was really "getting it", as he was struggling with the first scenario in the campaign even<br />
on "easy" play level. But after giving him some tips, now he has made quite a bit of progress through the campaign, and<br />
I am encouraged to see that he is continuing to learn what to pay attention to as he plays."<br />
<br />
"Also of particular benefit to our family is the multiplayer mode -- my 12yo lives in with her mom about an hour's drive<br />
away, and their cousins live too far away to visit, so we've been trying to get together to play whenever we can. We<br />
still have some issues here to work out (mostly with Windows, and likely OS-related, not problems with the game itself,<br />
as I know my brother in the US has an oldish version) but the developers have been quite responsive on the irc channel<br />
#wesnoth at irc.libera.chat whenever we have encountered problems."<br />
<br />
"I'm certainly going to include this in Debian Jr. now that I have seen that my kids love it."<br />
<br />
"Kudos to the whole Wesnoth community for helping make this game a tremendous success, especially the Debian guys I work<br />
with who have polished up the package, helped provide and maintain a woody backport, and have kept up with upstream<br />
releases, often releasing on the same day the release is announced."<br />
<br />
-- synrg at The Linux Game Tome<br />
<br />
<br />
"I've been looking for a decent turn-based tactical-strategy game for ages, and the other day someone pointed me at<br />
this. Hoorah - it's a decent turn-based tactical-strategy game. Still not the Lords Of Chaos or Laser Squad game I'm<br />
*really* looking for, but it's excellent all the same."<br />
<br />
-- [[RavenBlack]] at The Linux Game Tome<br />
<br />
<br />
"This is bye far the best free turn based fantasy ame i ever played.. it almost brings tears to my eyes."<br />
<br />
-- kerrigan at The Linux Game Tome<br />
<br />
<br />
posts 0-50 browsed through in The Linux Game Tome, 51-131 to go.<br />
<br />
[[Category:Showcase]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=FAQ&diff=67969FAQ2021-05-24T08:30:31Z<p>Vasya: /* How to find players for multiplayer game? */</p>
<hr />
<div>{{Translations}}<br />
== General ==<br />
<br />
===What is Battle for Wesnoth?===<br />
Battle for Wesnoth is a turn-based tactical strategy game with a high fantasy theme, featuring both single-player, and online/hotseat multiplayer combat.<br />
<br />
===What license is the game distributed under?===<br />
The project is distributed under the [http://www.fsf.org/copyleft/gpl.html GPL]. All contributors retain copyright on the portions of the project that they contribute. For more information, see [[Wesnoth:Copyrights]].<br />
<br />
===How to get informed about new releases?===<br />
Check the front page of the website.<br />
<br />
===A new version is out, but where is the download for [Windows, OS X, etc.]?===<br />
<br />
The packages provided, other than the source code tarball, are <strong>not</strong> part of the official project. The BfW team only releases the game's source code. Binary executables or applications are always contributed by community volunteers. If not for these volunteers, there would never be any downloads for us to enjoy. The volunteers compile the game and upload it on their own time, and sometimes they cannot do this in a timely fashion (or at all, at times). Although there are usual packagers designated for each operating system, there are times when other members of the community are asked to step in and contribute when the usual people cannot.<br />
<br />
Every time a new version is released, the usual volunteers are notified by the project leaders. <strong>Please refrain from making forum posts asking where your download is</strong> because it doesn't help anything - the packagers already know, and they will get to it as soon as they can. In the past, the Windows and Mac communities have come together to produce home-grown unofficial builds for the community to use, and the renewed interest in the community and learning how to compile is generally a good thing.<br />
<br />
===Why doesn't Wesnoth have my favorite feature?===<br />
The answer to this varies from case to case. Although it is not always readily evident, Wesnoth was designed with a few base goals present from the very start of the project. To give an example, the simple gameplay and pixel art style are part of Wesnoth's design and we will never replace them with overly complicated rules and 3D models. Some people may not like this or find it disappointing, but such is life.<br />
<br />
There are other cases where the community would like to see something implemented but we simply don't have the human resources to do it right now, primarily because we are unpaid volunteers with our own jobs and families to care for. That is where you come in. The beautiful thing about our game being open-source software is that, if you want a feature badly enough, you can take our game's source code and modify it yourself, and then [[PatchSubmissionGuidelines|submit your work]] to us. The same principle applies to art -- if there is something you feel is missing and have the required skills (or will to learn), you can submit it to our [http://forums.wesnoth.org/viewforum.php?f=9 Art Contributions forum] for review.<br />
<br />
===Do you want help making this game? How can I help?===<br />
Yes, we want your help. Whether you're a programmer, artist, musician, writer, translator, level designer, playtester, or just have some great suggestions, you're welcome to contribute. How? You can:<br />
* join the [http://www.wesnoth.org/wiki/Project project]<br />
* share your opinions at the [http://www.wesnoth.org/forum/ Forum]<br />
* talk with us on [[Support#IRC|IRC]]<br />
* [[ReportingBugs|report]] bugs you find with Wesnoth and its mainline content<br />
* update the wiki<br />
* play against other players via the [[GettingStarted#Multiplayer|Multiplayer]] menu<br />
* vote for Wesnoth at your favorite gaming web site<br />
* spread the word!<br />
<br />
=== What are the system requirements? ===<br />
'''outdated!'''<br />
We are not completely certain, but an x86 running at 400 MHz with 128 MB RAM should be adequate for versions 1.0.2 and below. For versions 1.1 and up we recommend a computer with at least 1 GHz and 512 MB RAM if you run KDE or Gnome as Windowmanager (The game itself needs about 100 MB RAM). Slower machines will have trouble scrolling large maps or processing AI turns with many units. See the [http://www.wesnoth.org/forum/viewtopic.php?t=7384 forum thread] about minimum and recommended system requirements.<br />
<br />
=== I'm bored; how do I speed the game up? ===<br />
<br />
There are several preferences you can change to shorten the time that the AI takes to make its moves. "Accelerated Speed" will make units move and fight faster. "Skip AI Moves" will not show the AI's units moving from hex to hex. Finally, you can turn off all combat animations via the "Show Combat" option on the Advanced tab.<br />
<br />
=== My computer is too slow; how do I speed the game up? ===<br />
<br />
First, turn off the music and sound effects. Turning off the color cursors will make your cursor respond faster. If scrolling the map is slow, run the game in "Full Screen" mode, not in a window. Turn off combat, map, and standing unit animations via the "Show Combat", "Animate Map" and "Unit Standing Animations" options on the Advanced tab in the game Preferences. You can try turning off halos and combat results, but this might make gameplay more difficult.<br />
<br />
== Gameplay and Controls ==<br />
<br />
=== How do I learn to play? ===<br />
<br />
If you just want to jump right in, start the game and play the tutorial. If you like reading documentation, see [[WesnothManual]]. At any time while playing, you can select help from the menu button (or hit F1). The online help is quite extensive and provides information on terrains, weapons, traits, abilities, units and a good overview of how to play.<br />
<br />
=== My unit leveled up but didn't improve. What happened? ===<br />
<br />
This is called "After Maximum Level Advancement" or AMLA for short. While most level 0, 1, and 2 units can advance, some cannot. However, some level 3 units can advance to level 4, or even 5. You can see whether a unit can advance further by right clicking and selecting "description."<br />
<br />
After a unit reaches the highest level it can get, every time it reaches a new experience threshold (which increases with each advancement) it gains 3 hitpoints and is restored to a state of full health. This is a minor bonus so that experience gained by maxed out units is not altogether wasted. It is generally better to give experience to lower level units, rather than continue to advance units that have reached their maximum level.<br />
<br />
=== I tried to trap an enemy with several weak units, but it still escaped. What happened? ===<br />
<br />
Most units exert a zone of control (or ZoC). If an enemy moves into one of the six adjacent hexes, the zone of control will prevent it from moving any farther. However some weak units are level 0, meaning they are so weak that they do not have a ZoC. You can still surround an enemy unit entirely with level 0 units to keep it from escaping, but if there is any gap in your ranks, it could escape.<br />
<br />
Also, some units have the "skirmish" ability, which allows them to ignore ZoCs.<br />
<br />
=== How can I see where an enemy unit can move next turn? ===<br />
<br />
During your turn you can click on an enemy unit. Wesnoth will highlight all the hexes the unit can move to in the next turn. This is useful when trying to arrange your units to block an enemy's movement.<br />
<br />
=== There's too much luck in this game! ===<br />
<br />
Sooner or later, you will become frustrated when your archmage with four 70% attacks misses all four times. This does not mean that the AI is cheating or the random number generator is futzed. It means you are noticing random negative events more than positive ones. During the development of the game, many mathematicians have done sophisticated statistical analysis of the combat system. Likewise, programmers have examined the random number generator. No flaws have been found, so streaks of "bad" and "good" luck should just be accepted as part of having randomness in Wesnoth. A more detailed rational and discussion of the role that randomness plays in Wesnoth can be found [http://www.wesnoth.org/forum/viewtopic.php?f=6&t=21317&start=0&st=0&sk=t&sd=a here].<br />
<br />
Since Wesnoth is GPLed, it is possible that a new development team will someday "fork" the source and produce a version more like Heroes of Might & Magic, with less or no randomness. Until then, don't charge with your horsemen against troll rocklobbers at night...<br />
<br />
=== The (random unit) is overpowered/underpowered! ===<br />
<br />
The development team has spent years tweaking the units in the game. Each unit has had its gold cost, attack types, combat damage, defensive values, resistances, upgrade paths, and other stats carefully scrutinized and loudly discussed in the forum. However, the game code and the units were being modified right up until the 1.0 release, so some unbalanced units may have slipped through.<br />
<br />
If you have evidence to back up your claim, search the forum for past discussions about this unit, and then try posting.<br />
<br />
=== The (random scenario) is too hard/easy! ===<br />
<br />
See above answer about random units.<br />
<br />
=== What do the different difficulty levels do? ===<br />
<br />
That depends on the scenario. Usually, the opponent will get more money and be able to recruit higher-level units at higher difficulty levels, and you will have fewer turns available.<br />
<br />
== Maps, Scenarios and Campaigns ==<br />
<br />
=== How do I beat scenario _______ ? ===<br />
<br />
If you are stuck on a scenario in a campaign, you'll probably find a walkthrough at [[MainlineCampaigns]]. Or check out the "Strategies and Tips" forum at http://www.wesnoth.org/forum/viewforum.php?f=3<br />
<br />
=== How do I download user campaigns? ===<br />
Choose "Campaigns" in the main Wesnoth menu. Then scroll down to the bottom and choose "Get More Campaigns..." or since 1.1.5 there is a "Get add-ons" button in the main menu. This connects you to the campaign server. In the campaign server you can view a list of all available campaigns and download them, as well as posting or deleting your own campaigns.<br />
<br />
If you are behind a firewall you may not be able to connect to the campaign server. In this case try to download the campaign directly from the campaign server at http://addons.wesnoth.org/. If you know how to change your firewall settings, then you should open port 15003 (version 1.1.1 and up) or port 15002 (versions 1.1.0 and lower). For added security, you can restrict traffic over those ports to the campaign server's IP address (currently 88.191.12.200).<br />
<br />
=== Are there any tools to help me create maps and scenarios? ===<br />
Yes, the game includes a built-in map editor, that you can use to build the terrain maps for your scenarios.<br />
<br />
Unfortunately, there's no simple solution for creating the rest of what constitutes a complete scenario or campaign, which is the [[ReferenceWML|WML]] code. There have been some abandoned attempts at creating complete scenario editors such as [[CampGen]], but they are no longer maintained, nor do they work with the latest stable versions of the game.<br />
<br />
You should take a look at the [[Create]] section for information and guides that can help you build your own scenario or campaign. Taking a look at how existing content works is also a good idea.<br />
<br />
=== What are the .cfg files and how can I edit them? ===<br />
<br />
The .cfg files are plain text files, saved with the file extension ".cfg". You can create and edit them using normal text editors; just save the files in correct format.<br />
<br />
Please note that some Windows programs like to add a ".txt" extension, so the file is instead of "my_scenario.cfg" saved as "my_scenario.cfg.txt". And then the Windows Explorer will hide the ".txt" extension by default, so you may not notice it.<br />
<br />
'''Notepad''': After you create a document, click "File", "Save as..." and select "Save as type: All files". To open the document, click "File", "Open..." and select "Files of type: All files (*.*)". If you open someone else's document, and the end-of-line symbols are displayed as small rectangles, you have to use another editor.<br />
<br />
'''WordPad''': After you create a document, click "File", "Save as..." and select "Save as type: Text Document". After the document is saved, close WordPad and remove the ".txt" extension from file. To open the document, click "File", "Open..." and select "Files of type: All documents (*.*)".<br />
<br />
There are also some additional editors with plugins offering support for WML [https://forums.wesnoth.org/viewtopic.php?f=21&t=13799 here].<br />
<br />
=== I already created an add-on and published it on the server. How can I get translations for the campaign? ===<br />
Just have a look at [[WesCamp]]. This project is the easiest way to get translations for your campaign. All the info you need you can find at [[WesCamp]].<br />
<br />
===How do I place an object or unit on my map with the map editor?===<br />
You can't. You need to make a scenario file. There are more details on the [[BuildingMaps|maps]] page.<br />
<br />
== Multiplayer ==<br />
<br />
===How do I connect to a multiplayer server, when I sit behind a restrictive firewall?===<br />
<br />
You have to open outgoing TCP port 15000 - 14997 (depending on the version you use) to play multiplayer games over the internet on the official servers.<br />
<br />
===How to find players for multiplayer game?===<br />
Hang around for a while on multiplayer servers and you might find someone to play with. If you observe other people playing you will get informed when someone joins the servers. Maybe you find someone willing to play in the [[Support#IRC|IRC]] channel dedicated to Wesnoth, #wesnoth at irc.libera.chat.<br />
<br />
===How to save and load a multiplayer game===<br />
<br />
Save the game. Give it a good name, so that you can find it among the other saved games.<br />
<br />
Create new game. (Give it a name like "private game for X and Y", so that other players will not try joining it, and you do not have to explain or kick them.) The first item in the map/scenario list is "Saved games", select this. Choose the saved game. Wait for the other player(s) to connect. Start the game.<br />
<br />
===How can I make my computer into a dedicated Wesnoth server?===<br />
<br />
To setup a dedicated Wesnoth server, you have to compile the game with the "--enable-server" flag, and after you install, simply run wesnothd from the console. This will start the server, listening on TCP port 15000. To compile the server only you can use the flags "--disable-game --enable-server". If you aren't using a linux or mac operating system, there are a few ways you can compile on Windows... [[CompilingWesnoth/CrossCompiling|here is one way]].<br />
<br />
'''Note:''' Packages for Wesnoth 1.4 and later include wesnothd by default since it's required by the "Host a network game" option from the Multiplayer menu, which is the preferred option for temporarily hosting a server instance to play in a LAN or privately through the Internet.<br />
<br />
===Which versions of Wesnoth can play together?===<br />
<br />
You only need to make sure you are using the same minor version number (6 in "1.6.x", 8 in "1.8.x" and so on) corresponding to stable branch releases. If you are using a development release (odd minor version numbers), you must be using exactly the same version number as other clients, to avoid out-of-sync (OOS) issues in multiplayer.<br />
<br />
If you are using user-made eras or MP scenarios, all players should make sure they are using the same, latest version of the add-on.<br />
<br />
== Translations ==<br />
<br />
===Where can I find more information about translating Wesnoth?===<br />
See [[WesnothTranslations]] for a list of currently maintained projects, and methods for contacting their maintainers and volunteering for help, and instructions for starting your own translation if it isn't included in the game already. [http://gettext.wesnoth.org] shows the current progress translations for different game development and stable branches, mainline campaigns and user-made add-ons.<br />
<br />
== Other Questions You Have ==<br />
<br />
The best way to get answers to less-frequently asked questions is by visiting the official [http://forums.wesnoth.org Battle for Wesnoth forums]. There are plenty of people willing to help. Make sure you read ALL of the forum sticky notes and announcements before posting!<br />
<br />
[[Category:Troubleshooting and Bugs]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=ServerAdministration_FromIRC&diff=67968ServerAdministration FromIRC2021-05-24T08:29:55Z<p>Vasya: </p>
<hr />
<div>== Overview ==<br />
<br />
The official Wesnoth servers can be moderated via IRC from the moderator IRC channel - which you know the location of if you are a moderator.<br />
<br />
Lobby chat, games, and other statistics are echoed at [irc://irc.libera.chat/wesnoth-mp-lobby-stable #wesnoth-mp-lobby-stable] and [irc://irc.libera.chat/wesnoth-mp-lobby-dev #wesnoth-mp-lobby-dev].<br />
<br />
== Administration via IRC ==<br />
<br />
Server administration commands are accessed via IRC by directing them to the lobby bot rather than using "/query" as is done on the server. For an action on the stable server direct commands to "lobby: ", and for the development server "lobby: !dev: " and for the previous stable server "lobby: !oldstable: "<br />
<br />
For example:<br />
lobby: /kick <mask> [<reason>]<br />
kicks a user from the stable server.<br />
<br />
== Message commands ==<br />
all commands are prefixed by "lobby: " or "lobby: !dev: "<br />
<br />
<text> sends a message to all server admins on the server (same as the adminmsg command).<br />
<br />
/msg <text> sends a message to all users on the server, even if they are in a game.<br />
<br />
/lobbymsg <text> sends a message to all users in the lobby.<br />
<br />
/pm <nick> <text> sends a private message to a user.<br />
<br />
== Links ==<br />
<br />
* [[ServerAdministration]] for admin commands<br />
<br />
[[Category:Troubleshooting_and_Bugs]]<br />
[[Category:Server Documentation]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=DeveloperGuide&diff=67967DeveloperGuide2021-05-24T07:31:34Z<p>Vasya: update IRC to libera.chat (from the old freenode)</p>
<hr />
<div>This page describes guidelines developers with push access to the Wesnoth repository should follow. Most items apply to prospective contributors as well, in addition to the [[PatchSubmissionGuidelines|patch submission guidelines]].<br />
<br />
__TOC__<br />
<br />
== General ==<br />
<br />
{{NewDevsGoHereSidebox}}<br />
<br />
* [[WesnothRepository#Push_access|Set up developer access to the repository]], if applicable.<br />
* Subscribe to the [https://mailman.wesnoth.org/listinfo/dev wesnoth-dev mailing list], wherein major announcements are made and project-changing discussions take place.<br />
* Participate in the #development channel on [https://discord.gg/battleforwesnoth Discord] as well as #wesnoth-dev IRC channel on irc.libera.chat to coordinate with other developers. Bots report commits and regression testing status, and other developers may ask you questions or provide feedback.<br />
<br />
== Commits ==<br />
<br />
* Any given branch should <b>compile without warnings</b> and run after every commit -- we use Github Actions, which will report any build failures on master and maintenance branches (1.12, 1.14, etc.) to the #development Discord channel.<br />
* All <b>unit tests</b> should pass after commit -- the CI will also test this. To run the C++ unit tests on your own machine, compile the "boost_unit_tests" executable and run it. To run the WML unit tests, run <code>run_wml_tests -u</code> in the checkout root. <br />
* Do <b>not</b> disable or ignore unit tests without a very good reason!<br />
* A few small commits are better than a single large commit (which is hard to review), so when possible split it in working parts with info about where you are going<br />
* <b>Always</b> review your changes, both before committing locally and before pushing upstream (see [[WesnothRepository#Reviewing your changes]]).<br />
* <b>Never</b> use the "force" option when pushing to the upstream Wesnoth repositories (see [[WesnothRepository#Force-pushing_policy]]).<br />
<br />
=== Changelog and release notes ===<br />
<br />
We provide a <b>changelog</b> at the root of the Wesnoth distribution and Git checkouts. It contains all changes, except for those that are only relevant to mainline developers and which are not expected to impact players or creators in any way.<br />
<br />
It is your responsibility to update the changelog as you see fit for every commit. For large changes spread over long series of commits, you will probably prefer to commit your changelog additions in a separate last commit to avoid or mitigate conflicts when merging upstream.<br />
<br />
Important changes that might be expected to inconvenience or confuse players (including those building from source) or content creators, major bug fixes, and noteworthy feature additions for a future release should be mentioned and explained in <b>RELEASE_NOTES</b> as well, so that the release team can include this information in official announcements. See the contents of the file for instructions.<br />
<br />
=== Commit messages ===<br />
<br />
A good commit should not only contain good changes, but also include a helpful description of them for other developers, people tracking regressions, project maintainers, and even yourself in the future. There are many style guides on the Web describing best practices for documenting your Git commits.<br />
<br />
For Wesnoth in particular, the general consensus is that contributors should adhere to the following rules:<br />
<br />
* Every commit message should begin with a self-contained <b>summary/subject line</b> no more than 72 characters long. This is the first (and often the only) line someone using browsing tools will see. Like with email subjects, this line should not have a trailing stop.<br />
* If your message needs more than a leading summary line, separate it from the rest with a blank line.<br />
* Subsequent lines should also be no more than 72 characters long. Use blank lines to separate paragraphs and list items.<br />
* When working on a mainline campaign/scenario, start the commit message with its acronym. For example <code>HttT: </code> when working on HttT in general and <code>HttT S03: </code> if the commit only applies to the third scenario of HttT (see below).<br />
* Likewise, if you work on the code of a specific component, you may want to use it as a prefix. That is e.g., <code>gui2: </code> or <code>wesnothd: </code>.<br />
* If you are performing branch merges, Git may include a list of conflicted paths in the commit message template. Edit this out; it ceases to be interesting after the conflicts have been resolved.<br />
* If you need to mention commit SHA1 hashes (e.g. in revert messages), make sure to use hashes from the upstream repository that are unlikely to change due to a future local or remote merge or rebase operation.<br />
<br />
There are a few additional points to keep in mind for the wording of the contents:<br />
<br />
* Include "bug #1234" somewhere in your commit message if it addresses a bug or feature request from the Wesnoth bug tracker.<br />
* Use the project's [[Glossary#Wesnothian_Acronyms|standard abbreviations]] for campaigns and gameplay concepts, like HttT for <cite>Heir to the Throne</cite>, ZoC for "Zone of Control", etc. If referring to a particular campaign or scenario in your commit subject, you should use this convention: "HttT S01: Made Galdrad less suicidal"<br />
<br />
== Dependencies ==<br />
* Any changes to Wesnoth's build and run-time dependencies must be discussed on the developers mailing list first.<br />
* Update the CMake and SCons recipes accordingly.<br />
* Changes must be mentioned in the RELEASE_NOTES file, so they can be included in the forum announcement for the next release, and in the emails to packagers.<br />
<br />
== Bugs management ==<br />
* Change Status field of fixed bugs to "Fixed" after pushing upstream<br />
* Change Open/Closed field of fixed bugs to "Closed" after a release including the relevant commits has been published. See [[ReportingBugs#Bug_protocol]] for details.<br />
* Check regularly if there are new bugs relevant to your code and, if any, assign them to you.<br />
<br />
== See also ==<br />
* [[WesnothRepository]]<br />
* [[PatchSubmissionGuidelines]]<br />
* [[SoftwareTesting]]<br />
* [[Project]]<br />
* [[CompatibilityStandards#Deprecation_levels_-_When_to_remove_deprecated_features|DeprecationLevels]]<br />
[[Category:Development]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=MP_CodeOfConduct&diff=67209MP CodeOfConduct2021-03-19T11:17:57Z<p>Vasya: Created page with "This page has been moved to the Forums, see: https://forums.wesnoth.org/viewtopic.php?t=24277#w0mp"</p>
<hr />
<div>This page has been moved to the Forums, see: https://forums.wesnoth.org/viewtopic.php?t=24277#w0mp</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&diff=66647LuaWML/Tiles2021-02-18T20:50:28Z<p>Vasya: /* wesnoth.map.get_adjacent_tiles */</p>
<hr />
<div>{{Template:LuaMove}}<br />
<br />
This page describes the [[LuaWML]] functions for handling terrains and tiles. The ''items'' library can be loaded by<br />
<br />
<syntaxhighlight lang=lua><br />
items = wesnoth.require "lua/wml/items.lua"<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_map_size ====<br />
<br />
* '''wesnoth.get_map_size()'''<br />
<br />
Returns the width, the height, and the border size of the map.<br />
<br />
<syntaxhighlight lang=lua><br />
local w,h,b = wesnoth.get_map_size()<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_terrain ====<br />
<br />
* '''wesnoth.get_terrain(''x'', ''y'')'''<br />
<br />
Returns the terrain code for the given location.<br />
<br />
<syntaxhighlight lang=lua><br />
local is_grassland = wesnoth.get_terrain(12, 15) == "Gg"<br />
</syntaxhighlight><br />
<br />
==== wesnoth.set_terrain ====<br />
<br />
* '''wesnoth.set_terrain(''x'', ''y'', ''terrain_code'', [''layer''], [''replace_if_failed''])'''<br />
<br />
Modifies the terrain at the given location.<br />
<br />
<syntaxhighlight lang=lua><br />
function create_village(x, y)<br />
wesnoth.set_terrain(x, y, "Gg^Vh")<br />
end<br />
</syntaxhighlight><br />
<br />
An optional 4th parameter can be passed (layer): overlay, base or both, default both: Change the specified layer only.<br />
<br />
An optional 5th boolean parameter (replace_if_failed) can be passed, see the documentation of the [terrain] tag. To pass the 5th parameter but not the 4th, pass nil for the 4th.<br />
<br />
==== wesnoth.get_terrain_info ====<br />
<br />
* '''wesnoth.get_terrain_info(''terrain_code'')'''<br />
<br />
Returns the terrain details for the given terrain code.<br />
<br />
<syntaxhighlight lang=lua><br />
local is_keep = wesnoth.get_terrain_info(wesnoth.get_terrain(12, 15)).keep<br />
</syntaxhighlight><br />
<br />
Terrain info is a plain table with the following fields:<br />
* '''id''': string<br />
* '''name''', '''description''', '''editor_name''': translatable strings<br />
* '''castle''', '''keep''', '''village''': booleans<br />
* '''healing''': integer<br />
<br />
==== wesnoth.get_selected_tile ====<br />
<br />
* '''wesnoth.get_selected_tile()'''<br />
<br />
Returns the two coordinates of the currently selected tile. This is mostly useful for defining command-mode helpers.<br />
<br />
<syntaxhighlight lang=lua><br />
function chg_unit(attr, val)<br />
local x, y = wesnoth.get_selected_tile()<br />
if not x then wesnoth.message("Error", "No unit selected."); return end<br />
helper.modify_unit({ x = x, y = y }, { [attr] = val })<br />
end<br />
-- Function chg_unit can be used in command mode to modify unit attributes on the fly:<br />
-- :lua chg_unit("status.poisoned", true)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_locations ====<br />
<br />
* '''wesnoth.get_locations(''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_locations(''filter'' [, ''reference_unit''])'''<br />
<br />
Returns a table containing all the locations matching the given filter. Locations are stored as pairs: tables of two elements. See [[StandardLocationFilter]] for details about location filters. If a unit is passed, it can be referenced from the filter via the $teleport_unit variable, as well as in WFL formulas used in the filter.<br />
<br />
<syntaxhighlight lang=lua><br />
-- replace all grass terrains by roads<br />
for i,loc in ipairs(wesnoth.get_locations { terrain = "Gg" }) do<br />
wesnoth.set_terrain(loc[1], loc[2], "Rr")<br />
end<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_villages ====<br />
<br />
* '''wesnoth.get_villages([''filter''])'''<br />
<br />
This function, when called without arguments, returns a table containing all the villages present on the map (as tables of two elements). If it's called with a WML table as argument, a table containing only the villages matching the supplied [[StandardLocationFilter]] is returned.<br />
<br />
<syntaxhighlight lang=lua><br />
-- How many villages do we have on our map?<br />
v = #wesnoth.get_villages()<br />
</syntaxhighlight><br />
<br />
==== wesnoth.match_location ====<br />
<br />
* '''wesnoth.match_location(''x'', ''y'', ''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.match_location(''x'', ''y'', ''filter'' [, ''reference_unit''])'''<br />
<br />
Returns true if the given location passes the filter. If a unit is passed, it can be referenced from the filter via the $teleport_unit variable, as well as in WFL formulas used in the filter.<br />
<br />
<syntaxhighlight lang=lua><br />
bool b = wesnoth.match_location(x, y, { terrain = "Ww", { "filter_adjacent_location", terrain = "Ds,*^Bw*" } })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_tile_overlay ====<br />
<br />
* '''wesnoth.add_tile_overlay(''x'', ''y'', ''item_wml'')'''<br />
<br />
Places a tile overlay (either an image or a halo) at a given location. The overlay is described by a table supporting the same fields as [[InterfaceActionsWML|[item]]]. Note that the overlay is not kept over save/load cycles.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.add_tile_overlay(17, 42, { image = "items/orcish-flag.png" })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.remove_tile_overlay ====<br />
<br />
* '''wesnoth.remove_tile_overlay(''x'', ''y'', [''filename''])'''<br />
<br />
Removes all the overlays at the given location. If a filename is passed as a third argument, only this overlay (either image or halo) is removed.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.remove_tile_overlay(17, 42, "items/orcish-flag.png")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_fog ====<br />
<br />
* '''wesnoth.add_fog([''sides''], ''locations'', [''permanent''])'''<br />
<br />
{{DevFeature1.13|5}} Fogs over the specified locations for the specified sides (or all sides, if no sides are specified). You can specify sides either as a single integer or a list of integers. The ''permanent'' argument defaults to false, causing temporary fog overrides to be cleared; if true, it affects the team's permanent fog as well.<br />
<br />
==== wesnoth.remove_fog ====<br />
<br />
* '''wesnoth.remove_fog([''sides''], ''locations'', [''permanent''])'''<br />
<br />
{{DevFeature1.13|5}} Unfogs the specified locations for the specified sides (or all sides, if no sides are specified). You can specify sides either as a single integer or a list of integers. The ''permanent'' argument defaults to false, creating temporary fog overrides that disappear at the end of the turn; if true, it affects the team's permanent fog as well.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.remove_fog(1, { {5, 5}, {5, 6} }) --removes fog on 5,5 and 5,6 for side 1<br />
wesnoth.remove_fog(wesnoth.sides[1].side, { {5, 5} }) -- removes fog for first side on 5,5<br />
wesnoth.remove_fog(1, wesnoth.get_locations{ x = 5, y = 5 }) --removes fog on 5,5<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_sound_source ====<br />
<br />
* '''wesnoth.add_sound_source(''cfg'')'''<br />
<br />
{{DevFeature1.13|5}} Adds a sound source. Input parameters are the same as for the [add_sound_source] tag. If a sound source with the same ID already exists, it is replaced.<br />
<br />
==== wesnoth.remove_sound_source ====<br />
<br />
* '''wesnoth.remove_sound_source(''id'')'''<br />
<br />
{{DevFeature1.13|5}} Removes a sound source.<br />
<br />
==== wesnoth.get_sound_source ====<br />
<br />
* '''wesnoth.get_sound_source(''id'')'''<br />
<br />
{{DevFeature1.13|5}} Retrieves the parameters of an existing sound source. The result of this function is suitable for feeding back to add_sound_source. The table returned by this function is a copy of the sound source's parameters, so if you change any of them, you must call add_sound_source to update the source.<br />
<br />
<br />
==== wesnoth.map.get_direction ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.get_direction(''from'', ''dir'', [''count''])'''<br />
<br />
Calculates the hex reached by travelling in the specified direction, which should be a string such as "ne" or "s". The optional third parameter ''count'' is number of steps to travel to specified direction. Negative ''count'' is supported to travel opposite direction.<br />
<br />
==== wesnoth.map.get_relative_dir ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.get_relative_dir(''from'', ''to'')'''<br />
<br />
Calculates the direction from one hex to another. Possible returns are strings "n", "ne", "nw", "s", "se", "sw" or "". The empty string means no direction which happens if ''from'' and ''to'' are same.<br />
<br />
==== wesnoth.map.rotate_right_around_center ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.rotate_right_around_center(''loc'', ''center'', ''angle'')'''<br />
<br />
Calculates the hex obtained from rotating the specified location around the specified center by the specified angle. The angle is an integer in the range 1..6.<br />
<br />
==== wesnoth.map.get_adjacent_tiles ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.get_adjacent_tiles(''loc'')'''<br />
<br />
Return all hexes adjacent to the specified hex, as six separate return values.<br />
<br />
<syntaxhighlight lang=lua><br />
local a, b, c, d, e, f = wesnoth.map.get_adjacent_tiles({3, 3})<br />
local a_x = a[1]<br />
local a_y = a[2]<br />
</syntaxhighlight><br />
<br />
See also [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]] if you want to iterate over the hexes.<br />
<br />
==== wesnoth.map.tiles_adjacent ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.tiles_adjacent(''loc1'', ''loc2'')'''<br />
<br />
Tests if two hexes are adjacent.<br />
<br />
==== wesnoth.map.distance_between ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.distance_between(''loc1'', ''loc2'')'''<br />
<br />
Calculates the distance between two hexes.<br />
<br />
<syntaxhighlight lang=lua><br />
local my_distance = wesnoth.map.distance_between({10, 10}, {20, 20})<br />
</syntaxhighlight><br />
<br />
==== wesnoth.label====<br />
{{DevFeature1.13|0}}<br />
<br />
* '''wesnoth.label(''cfg'')'''<br />
<br />
Sets label of cfg.x, cfg.y to cfg.text. More supported keys https://wiki.wesnoth.org/InterfaceActionsWML#.5Blabel.5D<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.label {x=10,y=10,text="a",color={255,255,255,255}}<br />
</syntaxhighlight><br />
<br />
==== wesnoth.special_locations ====<br />
<br />
{{DevFeature1.13|12}}<br />
<br />
This is a table containing all the special locations set in the map data, including side starting locations, indexed by their key. (Side starting locations are indexed by the side number.)<br />
<br />
<syntaxhighlight lang=lua><br />
-- Get the starting position of side 3<br />
local enemy_start = wesnoth.special_locations[3]<br />
-- Get a named location, "spire", from the map data<br />
local destination = wesnoth.special_locations.spire<br />
</syntaxhighlight><br />
<br />
==== items.place_image ====<br />
<br />
* '''items.place_image(''x'', ''y'', ''filename'')'''<br />
<br />
Places an image at a given location and registers it as a WML ''[item]'' would do, so that it can be restored after save/load.<br />
<br />
<syntaxhighlight lang=lua><br />
local items = wesnoth.require "lua/wml/items.lua"<br />
items.place_image(17, 42, "items/orcish-flag.png")<br />
</syntaxhighlight><br />
<br />
==== items.place_halo ====<br />
<br />
* '''items.place_halo(''x'', ''y'', ''filename'')'''<br />
<br />
Behaves the same as [[#items.place_image]] but for halos.<br />
<br />
==== items.remove ====<br />
<br />
* '''items.remove(''x'', ''x'', [''filename''])'''<br />
<br />
Removes an overlay set by [[#items.place_image]] or [[#items.place_halo]]. If no filename is provided, all the overlays on a given tile are removed.<br />
<br />
<syntaxhighlight lang=lua><br />
items.remove(17, 42, "items/orcish-flag.png")<br />
</syntaxhighlight><br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=Replays&diff=66431Replays2021-01-03T21:36:00Z<p>Vasya: /* How to Watch a Replay */</p>
<hr />
<div>A '''Replay''' is a savegame which includes all the history of a game since the beginning. Replays can be used, for example, to analyze a game for possible improvement, or to watch other games from the past, or for any other purpose. In order to observe a replay, one must have wesnoth version equal to the savegame's version, or a compatible version.<br />
<br />
===Multiplayer Replays archive===<br />
Multiplayer replays are stored in [https://replays.wesnoth.org/ replays.wesnoth.org]. It's a collection of all public games played on the main multiplayer server. This archive is generated and updated automatically.<br />
<br />
===How to Watch a Replay===<br />
If you've made a savegame yourself, you can just Load/Open the game and check the "Show Replay" checkbox. If you've downloaded a replay, you need to place it in your saves folder first. This folder can be opened by clicking the "i" icon in the lower left corner of Wesnoth's main menu screen then clicking the folder icon to the right of the "User data" row.<br />
<br />
To watch the replay:<br />
<ol><br />
<li>Open Wesnoth</li><br />
<li>Press load</li><br />
<li>Select the right replay</li><br />
<li>Press OK</li><br />
<li>Enjoy</li><br />
</ol><br />
<br />
[[Category:Replays]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=Replays&diff=66430Replays2021-01-03T21:35:26Z<p>Vasya: /* How to Watch a Replay */</p>
<hr />
<div>A '''Replay''' is a savegame which includes all the history of a game since the beginning. Replays can be used, for example, to analyze a game for possible improvement, or to watch other games from the past, or for any other purpose. In order to observe a replay, one must have wesnoth version equal to the savegame's version, or a compatible version.<br />
<br />
===Multiplayer Replays archive===<br />
Multiplayer replays are stored in [https://replays.wesnoth.org/ replays.wesnoth.org]. It's a collection of all public games played on the main multiplayer server. This archive is generated and updated automatically.<br />
<br />
===How to Watch a Replay===<br />
If you've made a savegame yourself, you can just Load/Open the game and check the "Show Replay" checkbox. If you've downloaded a replay, you need to place it in your saves folder. This folder can be opened by clicking the "i" icon in the lower left corner of Wesnoth's main menu screen then clicking the folder icon to the right of the "User data" row.<br />
<br />
To watch the replay:<br />
<ol><br />
<li>Open Wesnoth</li><br />
<li>Press load</li><br />
<li>Select the right replay</li><br />
<li>Press OK</li><br />
<li>Enjoy</li><br />
</ol><br />
<br />
[[Category:Replays]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=Replays&diff=66429Replays2021-01-03T21:35:00Z<p>Vasya: explain local savegame replay</p>
<hr />
<div>A '''Replay''' is a savegame which includes all the history of a game since the beginning. Replays can be used, for example, to analyze a game for possible improvement, or to watch other games from the past, or for any other purpose. In order to observe a replay, one must have wesnoth version equal to the savegame's version, or a compatible version.<br />
<br />
===Multiplayer Replays archive===<br />
Multiplayer replays are stored in [https://replays.wesnoth.org/ replays.wesnoth.org]. It's a collection of all public games played on the main multiplayer server. This archive is generated and updated automatically.<br />
<br />
===How to Watch a Replay===<br />
If you made a savegame yourself, you can just Load/Open the game and check the "Show Replay" checkbox. If you've downloaded a replay, you need to place it in your saves folder. This folder can be opened by clicking the "i" icon in the lower left corner of Wesnoth's main menu screen then clicking the folder icon to the right of the "User data" row.<br />
<br />
To watch the replay:<br />
<ol><br />
<li>Open Wesnoth</li><br />
<li>Press load</li><br />
<li>Select the right replay</li><br />
<li>Press OK</li><br />
<li>Enjoy</li><br />
</ol><br />
<br />
[[Category:Replays]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=Replays&diff=66425Replays2021-01-03T09:15:42Z<p>Vasya: add replays.wesnoth.org info, re-word hand-picked archive in a more "outdated" fashion</p>
<hr />
<div>A '''Replay''' is a savegame which includes all the history of a game since the beginning. Replays can be used, for example, to analyze a game for possible improvement, or to watch other games from the past, or for any other purpose. In order to observe a replay, one must have wesnoth version equal to the savegame's version, or a compatible version.<br />
<br />
<br />
===Multiplayer Replays archive===<br />
Multiplayer replays are stored in [https://replays.wesnoth.org/ replays.wesnoth.org]. It's a collection of all public games played on the main multiplayer server. This archive is generated and updated automatically.<br />
<br />
===How to Watch a Replay===<br />
After you download a replay you need to place it in your saves folder.<br />
<br />
<b>On Mac OS X:</b> <br><br />
~/Library/Application Support/Wesnoth<version>/Saves<br />
<br />
<b>On Windows:</b> <br><br />
C:/Program Files/Wesnoth/userdata/saves<br />
<br />
<b>On Windows 7 and later:</b> <br><br />
C:/Users/<user>/appData/Local/Battle for Wesnoth <version>/userdata/saves <b>OR</b> <br><br />
C:/Users/<user>/Documents/My Games/Wesnoth<version>/saves<br />
<br />
<b>On GNU/Linux:</b> <br><br />
~/.local/share/wesnoth/<version>/saves<br />
<br />
To watch the replay:<br />
<ol><br />
<li>Open Wesnoth</li><br />
<li>Press load</li><br />
<li>Select the right replay</li><br />
<li>Check Watch Replay</li><br />
<li>Press OK</li><br />
<li>Enjoy</li><br />
</ol><br />
<br />
===Old Default Era===<br />
Some replays for older wesnoth versions were hand-picked and shared on this page for archival as well. If you have a compatible (older) wesnoth version, access the archives by clicking on the icon of the [[faction]] you want to see winning replays of.<br />
<br />
{| style="width:100%;border:solid 0px #FFFFFF;background-color:transparent;align:center;padding:0px;padding-top:1em;" cellspacing="0px;"<br />
|-<br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Drake_Replays http://units.wesnoth.org/1.4/pics/00004_blademaster.png]</div><br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Rebel_Replays http://units.wesnoth.org/1.4/pics/00193_wose-elder.png]</div><br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Loyalist_Replays http://units.wesnoth.org/1.4/pics/00109_marshal.png]</div><br />
|-<br />
! style="text-align:center;width:33%"|'''[[Drake Replays|Drakes]]'''<br />
! style="text-align:center;width:33%"|'''[[Rebel Replays|Rebels]]'''<br />
| style="text-align:center;"|'''[[Loyalist Replays|Loyalists]]'''<br />
|-<br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Northerner_Replays http://units.wesnoth.org/1.4/pics/00167_sovereign.png]</div><br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Undead_Replays http://units.wesnoth.org/1.4/pics/00070_necromancer.png]</div><br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Knalgan_Replays http://units.wesnoth.org/1.4/pics/00020_lord.png]</div><br />
|- style="padding:0px;" cellspacing="0px;"<br />
! style="text-align:center;width:33%"|'''[[Northerner Replays|Northerners]]'''<br />
! style="text-align:center;width:33%"|'''[[Undead Replays|Undead]]'''<br />
! style="text-align:center;width:33%"|'''[[Knalgan Replays|Knalgan Alliance]]'''<br />
|-<br />
| style="text-align:center;width:33%"|<br />
| style="width:33%;align:center;" |<br />
<div align="center">[http://www.wesnoth.org/wiki/Hodor_Replays http://units.wesnoth.org/1.4/pics/00151_yeti.png]</div><br />
| style="text-align:center;width:33%"|<br />
|-<br />
| style="text-align:center;width:33%"|<br />
! style="text-align:center;width:33%"|'''[[Hodor Replays|Hodor]]'''<br />
| style="text-align:center;width:33%"|'''<br />
|}<br />
<br />
===See Also===<br />
*[http://www.wesnoth.org/forum/viewtopic.php?t=6471 1v1 Replay Archive (forums)]<br />
*[http://www.wesnoth.org/forum/viewtopic.php?t=6601 2v2 Replay Archive (forums)]<br />
<br />
[[Category:Replays]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=EffectWML&diff=66095EffectWML2020-10-05T07:16:42Z<p>Vasya: link the [specials] tag</p>
<hr />
<div>{{WML Tags}}<br />
<br />
The tag [effect] is used to describe one modification to a unit. Any number of [effect] tags can be used to describe a complete modification. Modifications are permanent changes to a unit; currently there is no way of removing a modification.<br />
<br />
The following keys and subtags are always recognized:<br />
* '''[filter]''': only apply this effect if the affected unit matches. See [[StandardUnitFilter]] for details.<br />
* '''times''': describes how many times the effect is applied. The default is to apply the effect once. Other possible value : "per level" which means that the effect is applied level times, where level is the unit level. {{DevFeature1.13|5}} Integers are now supported for ''times''.<br />
* '''apply_to''': describes what the effect actually affects. New effect types can be added with [[LuaWML/Units#wesnoth.effects]].<br />
[effect] uses different keys depending on the value of '''apply_to'''. '''apply_to''' can take the following values:<br />
* '''new_attack''': will use all other keys and tags as the description of an attack that will be added to the unit. See [attack] in [[UnitTypeWML#Attacks|UnitTypeWML]].<br />
* '''remove_attacks''': remove the matching attacks. All tags from the attack filter construct will be used to match the attack; see [[FilterWML#Filtering Weapons|FilterWML]]. Do not use a [filter] tag otherwise it will not work properly.<br />
* '''attack''': find an attack and modify it. All tags from the attack filter construct will be used to match the attack; see [[FilterWML#Filtering Weapons|FilterWML]]. After that, the following keys and tags can be used to modify the attack. Note: do not use a [filter] tag. Just put the keys you want to filter on inside the [effect] tag.<br />
** '''set_name''': change the attack's name (ie identifier).<br />
** '''set_description''': change the attack's description (ie displayed name). <br />
** '''set_type''': change the attack type. The standard values are '''blade''', '''pierce''', '''impact''', '''fire''', '''cold''', and '''arcane'''.<br />
** '''set_icon''': change the attack's icon.<br />
** '''[set_specials]''': change the attack's specials. The specials to add are given exactly as in the [[AbilitiesWML#The_.5Bspecials.5D_tag|[specials]]] tag.<br />
*** '''mode''': if '''append''', adds the given specials to the attack. If '''replace''', replaces the existing specials with the given ones. Default '''replace'''.<br />
**** {{DevFeature1.15|3}} A deprecation warning is triggered unless the '''mode''' attribute is set, although the effect will still be '''replace'''. This is to allow the default to change in the 1.17.x series.<br />
** '''remove_specials''': remove the listed specials. The value of this key is the coma-separated list of the id of the specials to remove. This key is always evaluated before a [set_specials] tags in the same [effect]<br />
** '''increase_damage''': increases the attack's damage. This can be positive or negative, so you can use it to decrease damage as well. If it ends in a percent(''''%''''), the change in damage will be a percentage ratio of the attack's original damage.<br />
** '''increase_attacks''': increases the number of attack strikes. Like '''increase_damage''', it can be positive or negative, or a percentage.<br />
** '''increase_accuracy''': increases the attack accuracy; can be positive or negative, or a percentage<br />
** '''increase_parry''': increases the attack parry bonus; can be positive or negative, or a percentage<br />
** '''increase_movement_used''': {{DevFeature1.13|2}} increases the movement points used by the attack; can be positive or negative, or a percentage<br />
** '''set_damage''' {{DevFeature1.13|2}} like increase_damage, but sets the damage to a specific value instead of setting it relative to its original value<br />
** '''set_attacks''' {{DevFeature1.13|2}} like increase_attacks, but sets the attacks to a specific value instead of setting it relative to its original value<br />
** '''set_accuracy''' {{DevFeature1.13|2}} like increase_accuracy, but sets the accuracy to a specific value instead of setting it relative to its original value<br />
** '''set_parry''' {{DevFeature1.13|2}} like increase_parry, but sets the parry to a specific value instead of setting it relative to its original value<br />
** '''set_movement_used''' {{DevFeature1.13|2}} like increase_movement_used, but sets the movement used to a specific value instead of setting it relative to its original value<br />
** '''attack_weight''': change the attack's attack_weight. See [attack] in [[UnitTypeWML#Attacks|UnitTypeWML]] for explanations about attack_weight.<br />
** '''defense_weight''': change the attack's defense_weight. See [attack] in [[UnitTypeWML#Attacks|UnitTypeWML]] for explanations about defense_weight.<br />
* '''max_attacks''': {{DevFeature1.13|2}} change the unit's maximum attacks per turn<br />
** '''increase''': how much to increase by; can be positive or negative, or a percentage<br />
* '''hitpoints''': modifies the unit's HP and/or max HP.<br />
** '''increase''': the amount to increase the unit's HP.<br />
** '''heal_full''': if present and not set to "no" the unit will be put back to full HP.<br />
** '''increase_total''': will increase the total HP of the unit. Can be specified either as a negative or a positive value. It can also be specified as a percentage of the current total; i.e. "-50%" will cut max HP in half.<br />
** '''violate_maximum''': it the unit ends up with more than its max HP after these modifications, and this key is present (set to any non-null value, ex. '''yes'''), the unit's HP won't be lowered to its max HP.<br />
* '''movement''': modifies the unit's movement points.<br />
** '''increase''': maximum movement is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': maximum movement is set to a specific value.<br />
* '''vision''': {{DevFeature1.13|2}} modifies the unit's vision points. Note: this has side effects described in [[#Movement_and_Vision|Movement and Vision]].<br />
** '''increase''': maximum vision is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': maximum vision is set to a specific value. <br />
* '''jamming''': {{DevFeature1.13|2}} modifies the unit's jamming points.<br />
** '''increase''': maximum jamming is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': maximum jamming is set to a specific value.<br />
* '''experience''': affects the unit's current XP.<br />
** '''increase''': current XP is increased by this amount. It can be positive, negative, or specified as a percentage.<br />
** '''set''': current XP is set to a specific value.<br />
* '''max_experience''': affects the amount of XP the unit needs for the next level.<br />
** '''increase''': how to change the xp; again it can be negative, positive or a percentage.<br />
* '''loyal''': no keys associated. The affected unit will be loyal i.e have an upkeep of 0.<br />
* '''movement_costs''': speed through specific terrain is modified<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).<br />
** '''[movement_costs]''': a subtag that describes the new movement costs just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''vision_costs''': vision through specific terrain is modified<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).<br />
** '''[vision_costs]''': a subtag that describes the new vision costs just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''jamming_costs''': jamming through specific terrain is modified<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).<br />
** '''[jamming_costs]''': a subtag that describes the new jamming costs just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''defense''': Sets the unit's chance to be hit in specific terrain (100 - the unit's defense as shown in-game). <br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values. In most cases, adding a positive number makes the unit easier to hit, while adding a negative number makes the unit harder to hit. The new value is added to the absolute value of the old, and the sign of the old value is preserved.<br />
** '''[defense]''': a subtag that describes the new defense just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''resistance''': Sets percent damage taken from combat (100 - the unit's resistance as shown in-game)<br />
** '''replace''': If set to "yes", any new values replace the old ones. Otherwise, new values are added to old values. Adding a positive number makes the unit take more damage, while adding a negative number makes the unit take less damage.<br />
** '''[resistance]''': a subtag that describes the new resistance just like in [[UnitsWML#.5Bmovetype.5D|UnitsWML]]<br />
* '''variation''': switches the unit into one of its variations. Similar to the '''type''' effect below, this might not behave properly outside of [advancement], and cannot be combined with '''type''' in the same object due to a bug.<br />
** '''name''': the id of the variation to invoke. <br />
* '''type''': transforms the unit into a new unit_type. This does not work in [trait]; in ActionWML it's recommended to use [transform_unit] instead of an [object] with this effect. This effect cannot be undone with [remove_object].<br />
** '''name''': the id of the unit_type to invoke.<br />
* '''status''': modifies the status affecting the unit.<br />
** '''add''': a list of status modifications to add. Beware, these may be reapplied later, such as when the unit is recalled or levels up; if in an event, you can use [[InternalActionsWML|[store_unit]]] and [[DirectActionsWML|[unstore_unit]]], modifying unit.status.name directly, to avoid this, or if you are creating the unit, you can just add it to the unit's [status] tag in the [unit] tag. These are listed in [status], [[SingleUnitWML]].<br />
** '''remove''': a list of status modifications to remove.<br />
* '''zoc''': toggle the zone of control.<br />
** '''value''': new value for zoc (boolean).<br />
* '''profile''': customize the profile of the unit. See [[UnitTypeWML]].<br />
** '''portrait''': new image to display when the unit speaks.<br />
** '''small_portrait''': new image to display in unit reports.<br />
** '''description''': sets the text to display when hovering over the unit's type in the righthand pane.<br />
** '''[special_note]''': {{DevFeature1.15|2}} Adds or removes a special note in the unit's description.<br />
*** '''remove''': A boolean value specifying whether to add or remove a note. Defaults to '''no'''.<br />
*** '''note''' (translatable): The text of the note you want to add or remove. If removing a note, this must be an exact match, character-for-character, for the note you want to remove, and must also be in the same textdomain.<br />
*** Since the tag name is the same, notes can also be added using the standard special note macros, eg '''{NOTE_HEALS}'''.<br />
*** To remove a note, you can simply suffix '''{NOTE_REMOVE}''' to the regular note macro, eg '''{NOTE_HEALS}{NOTE_REMOVE}'''.<br />
* '''new_ability''': Adds one or more abilities to a unit.<br />
** '''[abilities]''': A subtag that contains the ability definitions.<br />
* '''remove_ability''': Removes one or more abilities from a unit. Abilities are not reference counted: added, added, removed = gone.<br />
** '''[abilities]''': A subtag that contains the ability definitions. Strictly speaking, all that is needed is the id= inside some tag.<br />
* '''new_animation''': contain animations that will be added to the unit, it can contain multiple animation blocks, and a single "id=" line. That Id should be unique for each effect block and is used by the engine to reuse WML parsing, making the loading faster. <br />
* '''image_mod''': modify the image path function ([[ImagePathFunctions]]) of all the unit's frames.<br />
** '''replace''': replaces the image path function(s) to be used, e.g. "RC(magenta>red)"<br />
** '''add''': adds an image path function without removing any existing ones.<br />
** If needed, you can also define new [[GameConfigWML#Color_Palettes|color palettes]] here.<br />
* '''ellipse''': Change the image used for the unit's ellipse.<br />
** '''ellipse''' : the new image to use. Can be set to "none" to disable the ellipse.<br />
* '''halo''': Change the image used for the unit's halo.<br />
** '''halo''': the new image to use.<br />
* '''overlay''': Change the unit's overlays.<br />
**'''add''': the specified overlay will be added to the unit's overlays. It can be a comma separated list with multiple overlays. ''Note: overlays added in this way cannot be removed by [remove_unit_overlay] until the effect's duration is over.''<br />
**'''replace''': all the unit's overlays will be removed and replaced with the specified one. Again, it can be a comma separated list. ''Note: overlays replaced in this way cannot be modified by [unit_overlay] or [remove_unit_overlay] until the effect's duration is over.''<br />
**'''remove''': {{DevFeature1.15|0}} the specified overlay will be removed from the unit's overlays. It can be a comma separated list with multiple overlays.<br />
** {{DevFeature1.15|0}} [unit_overlay] and [remove_unit_overlay] are now equivalent to adding a permanent object with this effect, after checking if the unit already has / already doesn't have the overlay (effects with temporary durations will cause false positives / false negatives in this check).<br />
* '''recall_cost''': {{DevFeature1.13|2}} change a unit's recall cost<br />
** '''set''': set recall cost to a specific value, or a percentage of original value<br />
** '''increase''': alter recall cost relative to original value; can be positive or negative, or a percentage<br />
* '''alignment''': {{DevFeature1.13|2}} change a unit's alignment<br />
** '''set''': the new alignment (one of chaotic, lawful, neutral, liminal)<br />
* '''new_advancement''': {{DevFeature1.13|2}} add new advancement choices to the unit<br />
** '''replace''': whether to replace existing advancement choices; if this key is set to yes, existing advancement choices are cleared only if you're adding a choice of the same type. (That is, unit type advancements are cleared only if you're adding a new unit advancement choice, and AMLA choices are cleared only if you're adding new AMLA choices.)<br />
** '''types''': a comma-separated list of additional unit types the unit can advance to. ('''Note:''' If using this, you probably want to include a filter to prevent the unit from being able to advance to this type once it has already done so.)<br />
** '''[advancement]''': an advancement choice to add, see [[UnitTypeWML#After_max_level_advancement_(AMLA)|AMLAs]]; you can have several of these tags to add multiple advancement choices at the same time.<br />
* '''remove_advancement''': {{DevFeature1.13|2}} remove existing advancement choices from the unit<br />
** '''types''': a list of unit type advancements to remove as a possibility<br />
** '''amlas''': a list of AMLA id attributes; any advancement possibility with the given id will be removed<br />
<br />
=== Movement and Vision ===<br />
<br />
Wesnoth 1.14 introduced vision points, which default to a reserved value (-1) which means "the same as the max movement points". Using an effect with apply_to=vision sets the number of vision points, and from then on they're no longer affected by the movement points.<br />
<br />
Consider a unit with 5 mp, and default vision:<br />
* It has (effectively) 5 mp and 5 vp.<br />
* After (mp + 1), it will have 6 mp and 6 vp.<br />
* After (vp + 2), it will have 5 mp and 7 vp.<br />
* After (mp + 1) (vp + 2), it will have 6 mp and 8 vp.<br />
* After (vp + 2) (mp + 1), it will have 6 mp and 7 vp.<br />
<br />
=== Examples ===<br />
== Effect: apply_to = new_animation ==<br />
This is the only way to change animations of units after they have been placed on the map.<br />
In this example, I add very simple idle animation (taken from Goblin Spearman) to the unit, which moves to hex (x=1, y=5). If you want something more complex, you need to check [[AnimationWML]] page.<br />
<br />
[event]<br />
name = moveto<br />
[filter]<br />
x,y = 1,5<br />
[/filter]<br />
[object]<br />
[filter]<br />
x,y = 1,5<br />
[/filter]<br />
[effect]<br />
apply_to = new_animation<br />
[idle_anim]<br />
{STANDARD_IDLE_FILTER}<br />
start_time=0<br />
[frame]<br />
image="units/goblins/spearman-idle-[1~12].png:[150*3,300,150*8]"<br />
[/frame]<br />
[/idle_anim]<br />
[/effect]<br />
[/object]<br />
[/event]<br />
<br />
If you are going to use '''advanced WML''' and want to add animation to unit, stored in variable, then following example might help you. '''This way is not efficient if you have no additional logic like inventoriy, shops, advanced unit modifications in your add-on.''' Is is preferred to use first variant or define all needed animation in unit_type.<br />
[event]<br />
name = moveto<br />
[filter]<br />
x,y = 1,5<br />
[/filter]<br />
[store_unit]<br />
[filter]<br />
x,y=1,5<br />
[/filter]<br />
variable = stored_unit<br />
[/store_unit]<br />
[set_variables]<br />
name = stored_unit.modifications.object<br />
[value]<br />
[effect]<br />
apply_to = new_animation<br />
[idle_anim]<br />
{STANDARD_IDLE_FILTER}<br />
start_time=0<br />
[frame]<br />
image="units/goblins/spearman-idle-[1~12].png:[150*3,300,150*8]"<br />
[/frame]<br />
[/idle_anim]<br />
[/effect]<br />
[/value]<br />
[/set_variables]<br />
[unstore_unit]<br />
variable = stored_unit<br />
[/unstore_unit]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[UnitTypeWML]]<br />
* [[ReferenceWML]]<br />
* [[AnimationWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Units&diff=65815LuaWML/Units2020-07-24T17:42:47Z<p>Vasya: /* wesnoth.put_unit */ Add deprecation and removal notice</p>
<hr />
<div><div class="tright"> __TOC__ </div><br />
<br />
This page describes the [[LuaWML]] functions for handling units.<br />
<br />
A unit is a proxy table with the following fields:<br />
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map. {{DevFeature1.13|11}} These are now read/write under all circumstances, including for on-map units)<br />
* '''loc''': {{DevFeature1.13|11}} shortcut to get/set both x and y at once (read/write). Setting x and y individually would result in two moves, and there's the possibility that the intermediate move fails if the hex is occupied by another unit. In general, note that moving a unit by changing the proxy unit's coordinates does not work if the goal hex is occupied (it is not executed), so it is necessary to check if the hex is available first.<br />
* '''side''': integer (read/write)<br />
* '''id''': string (read only)<br />
* '''type''': string (read only)<br />
* '''name''': translatable string (read only)<br />
* '''cost''' {{DevFeature1.13|10}}: integer (read)<br />
* '''max_hitpoints''', '''max_experience''', '''max_moves''': integers (read only)<br />
* '''max_attacks''': integer (read only)<br />
* '''attacks_left''': integer (read/write) Setting below 0 is limited to 0.<br />
* '''extra_recruit''': table (read/write)<br />
* '''advances_to''': table (read/write)<br />
* '''hitpoints''', '''experience''': integer (read/write)<br />
* '''moves''': integer (read/write)<br />
* '''level''': {{DevFeature1.13|5}} integer (read/write)<br />
* '''resting''': boolean (read/write)<br />
* '''hidden''': boolean (read/write)<br />
* '''petrified''', '''canrecruit''': booleans (read only)<br />
* '''role''', '''facing''': strings (read/write)<br />
* '''status''': proxy associative table (read only, read/write fields), provides fields like [[SingleUnitWML#Unit_State|poisoned, slowed, petrified, uncovered, guardian, unhealable, invulnerable]]<br />
* '''image_mods''': string (read only)<br />
* '''upkeep''' {{DevFeature1.13|5}}: one of 'loyal', 'full' or a number (read/writre)<br />
* '''variables''': proxy associative table (read only, read/write fields, including ''variables.__cfg''), only toplevel named fields are proxied. {{DevFeature1.13|2}} subcontainers can be accessed by using the usual variable syntax: <syntaxhighlight inline lang='lua'>unit.variables["a.b.c[6].d"]</syntaxhighlight><br />
* '''attacks''': {{DevFeature1.13|0}}an object to access the units attacks, you can use the attacks index or the attacks name to index an attack. every attack has the following members:<br />
** '''description''': translatable string (read/write)<br />
** '''name''': string (read)<br />
** '''type''': string (read/write)<br />
** '''range''': string (read/write)<br />
** '''damage''': number(read/write)<br />
** '''number''': number(read/write)<br />
** '''movement_used''': number(read/write)<br />
** '''attack_weight''': number(read/write)<br />
** '''defense_weight''': number(read/write)<br />
** '''specials''' wml table(read/write)<br />
* '''valid''': string or nil (read only)<br />
* '''advancements''': {{DevFeature1.13|2}} an array of wml tables (read/write)<br />
* '''__cfg''': WML table (dump) ([[SingleUnitWML]])<br />
* {{DevFeature1.13|2}} The following fields are unit methods synonymous to one of the functions described on this page:<br />
** '''[[#wesnoth.match_unit|matches]]'''<br />
** '''[[#wesnoth.put_recall_unit|to_recall]]'''<br />
** '''[[#wesnoth.put_unit|to_map]]'''<br />
** '''[[#wesnoth.erase_unit|erase]]'''<br />
** '''[[#wesnoth.copy_unit|clone]]'''<br />
** '''[[#wesnoth.extract_unit|extract]]'''<br />
** '''[[#wesnoth.advance_unit|advance]]'''<br />
** '''[[#wesnoth.add_modification|add_modification]]'''<br />
** '''[[#wesnoth.remove_modifications|remove_modifications]]'''<br />
** '''[[#wesnoth.unit_resistance|resistance]]'''<br />
** '''[[#wesnoth.unit_defense|defense]]'''<br />
** '''[[#wesnoth.unit_movement_cost|movement]]'''<br />
** '''[[#wesnoth.unit_vision_cost|vision]]'''<br />
** '''[[#wesnoth.unit_jamming_cost|jamming]]'''<br />
** '''[[#wesnoth.unit_ability|ability]]'''<br />
** '''[[#wesnoth.transform_unit|transform]]'''<br />
The metatable of these proxy tables appears as '''"unit"'''.<br />
<br />
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same "underlying_id" WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''"map"''', '''"recall"''', '''"private"''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.<br />
<br />
The term "proxy", here in particular "proxy unit", means that the variable retrieved in the lua code (with get_units for example) is an accessor (reference) to the C++ object which represents that unit. This is very different from unit variables obtained by [store_unit] in wml. The fields marked as "writable" above can be modified without the need to use put_unit afterwards. This same reason explains that modifications to the unit from outside the lua code (like [kill] invalidating the proxy unit) have immediate effect on the lua code's proxy unit variable (with the exception of private proxy units).<br />
<br />
==== wesnoth.get_units ====<br />
<br />
* '''wesnoth.get_units(''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_units(''filter'', ''fake_location'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_units(''filter'', ''other_unit'')'''<br />
<br />
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters. If a second unit is passed, it can be referenced via the $other_unit variable in the main filter as well as via the "other" variable in WFL formulas used in the main filter. If a location is passed, the filter is run as if the unit were at that location (rather than its real location). This affects things such as [filter_adjacent] and ability_active, and should work even for a unit on the recall list.<br />
<br />
<syntaxhighlight lang='lua'><br />
local leaders_on_side_two = wesnoth.get_units { side = 2, canrecruit = true }<br />
local name_of_leader = leaders_on_side_two[1].name<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_unit ====<br />
<br />
* '''wesnoth.get_unit(''x'', ''y'')'''<br />
* '''wesnoth.get_unit(''id'')'''<br />
<br />
Returns the unit at the given location or with the given ID.<br />
<br />
<syntaxhighlight lang='lua'><br />
local args = ...<br />
local unit = wesnoth.get_unit(args.x1, args.y1)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.match_unit ====<br />
<br />
* '''wesnoth.match_unit(''unit'', ''filter'')'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''other_unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''other_unit''])'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''location'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''location''])'''<br />
<br />
Returns true if the given unit matches the WML filter passed as the second argument. If ''other_unit'' is specified, it is used for the ''$other_unit'' auto-stored variable in the filter. Otherwise, this variable is not stored for the filter. If an extra ''location'' is specified, the filter matches as if the unit were at that location.<br />
<br />
<syntaxhighlight lang='lua'><br />
assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.put_unit ====<br />
<br />
* '''wesnoth.put_unit(''unit'')'''<br />
* '''wesnoth.put_unit(''x'', ''y'', ''unit'')''' -- Deprecated in {{DevFeature1.13|2}}, removed in {{DevFeature1.15|0}}<br />
* '''wesnoth.put_unit(''x'', ''y'')''' -- Deprecated in {{DevFeature1.13|2}}, removed in {{DevFeature1.15|0}}<br />
* {{DevFeature1.13|2}} '''wesnoth.put_unit(''unit'', ''x'', ''y'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':to_map([''x'', ''y''])<br />
<br />
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead. {{DevFeature1.13|2}} This use is now deprecated; use wesnoth.erase_unit instead.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- create a unit with random traits, then erase it<br />
wesnoth.put_unit(17, 42, { type = "Elvish Lady" })<br />
wesnoth.put_unit(17, 42)<br />
</syntaxhighlight><br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- move the leader back to the top-left corner<br />
wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])<br />
</syntaxhighlight><br />
<br />
If x,y is a village, this function does not capture it (as of 1.14). Use [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner(x, y, unit.side)]] if that's what you want.<br />
<br />
==== wesnoth.erase_unit ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
* '''wesnoth.erase_unit(''unit'')'''<br />
* '''wesnoth.erase_unit(''x'', ''y'')'''<br />
* '''''unit'':erase()'''<br />
<br />
Erases a unit from the map. After calling this on a unit, the unit is no longer valid.<br />
<br />
==== wesnoth.get_recall_units ====<br />
<br />
* '''wesnoth.get_recall_units()'''<br />
<br />
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.<br />
<br />
==== wesnoth.put_recall_unit ====<br />
<br />
* '''wesnoth.put_recall_unit(''unit'', [''side''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':to_recall([''side''])'''<br />
<br />
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- put the unit at location 17,42 on the recall list for side 2<br />
wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)<br />
</syntaxhighlight><br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.<br />
<br />
==== wesnoth.create_unit ====<br />
<br />
* '''wesnoth.create_unit(''unit_info'')'''<br />
<br />
Creates a private unit from a WML table.<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.create_unit { type = "White Mage", gender = "female" }<br />
</syntaxhighlight><br />
<br />
==== wesnoth.copy_unit ====<br />
<br />
* '''wesnoth.copy_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':clone()'''<br />
<br />
Creates a private unit from another unit.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- extract a unit from the map<br />
local u = wesnoth.copy_unit(wesnoth.get_units({ type = "Thug" })[1])<br />
wesnoth.erase_unit(u.x, u.y)<br />
-- u is still valid at this point<br />
</syntaxhighlight><br />
<br />
==== wesnoth.extract_unit ====<br />
<br />
* '''wesnoth.extract_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':extract()'''<br />
<br />
Removes a unit from the map or from a recall list and makes it private.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- remove all the units from the recall list of side 1 and put them in a WML container<br />
local l = {}<br />
for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do<br />
wesnoth.extract_unit(u)<br />
table.insert(l, u.__cfg)<br />
end<br />
helper.set_variable_array("player_recall_list", l)<br />
</syntaxhighlight><br />
<br />
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.<br />
<br />
<br />
==== wesnoth.advance_unit ====<br />
<br />
* '''wesnoth.advance_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':advance()'''<br />
<br />
{{DevFeature1.13|0}} Advances the unit (and shows the advance unit dialog if needed) if the unit has enough xp. This function should be called after modifying the units experience directly. A similar function is called by wesnoth internally after unit combat. The second argument is a boodean value that specifies whether the advancement should be animated. The third agrument is a boodean value that specifies whether advancement related events should be fired.<br />
<br />
<br />
This function only works for units on the map.<br />
<br />
This function can also trigger multiple advancements if the unit has enough xp.<br />
<br />
==== wesnoth.add_modification ====<br />
<br />
* '''wesnoth.add_modification(''unit'', ''type'', ''effects'', [''write_to_mods''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':add_modification(''type'', ''effects'', [''write_to_mods''])'''<br />
<br />
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (one of "trait", "object", or "advance"). The option "advance" applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.<br />
<br />
{{DevFeature1.13|2}} In 1.13.2 and later, the "advance" type is replaced with "advancement", to match the equivalent tag in [[UnitTypeWML|[unit_type]]]. Also, it takes a fourth argument which, if false, causes it to not write the modification tag to the unit's [modifications] (as would be done with an [object] with no_write=true).<br />
<br />
<syntaxhighlight lang='lua'><br />
local T = wml.tag<br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
local effects = {<br />
id = "my_effect_id",<br />
T.effect { <br />
apply_to = "image_mod", <br />
replace = "RC(red>blue)" <br />
},<br />
T.effect {<br />
apply_to = "new_animation",<br />
T.standing_animation {<br />
-- AnimationWML<br />
}<br />
}<br />
} <br />
wesnoth.add_modification(u, "object", effects)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.remove_modifications ====<br />
<br />
* {{DevFeature1.13|?}} '''wesnoth.remove_modifications(''unit'', ''cfg'' [, ''type''])'''<br />
* {{DevFeature1.13|?}} '''''unit'':remove_modifications(''cfg'' [, ''type''])'''<br />
<br />
Modifies a given unit. The unit needs to be a proxy unit. The second argument is a filter for the modifications to remove. It takes the same syntax as [[FilterWML#Filtering_on_WML_data|[filter_wml]]]; all matching modifications will be removed. The third argument is the type (tag name) of the modifications to search for; it defaults to <tt>"object"</tt>, but you can also pass <tt>"trait"</tt> or <tt>"advancement"</tt>.<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
wesnoth.remove_modifications(u, { id = "my_effect_id" })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_resistance ====<br />
<br />
* '''wesnoth.unit_resistance(''unit'', ''damage_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':resistance(''damage_type'')'''<br />
<br />
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).<br />
<br />
<syntaxhighlight lang='lua'><br />
local fire_resistance = 100 - wesnoth.unit_resistance(u, "fire")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_defense ====<br />
<br />
* '''wesnoth.unit_defense(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':defense(''terrain_code'')'''<br />
<br />
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)<br />
<br />
<syntaxhighlight lang='lua'><br />
local flat_defense = 100 - wesnoth.unit_defense(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_movement_cost ====<br />
<br />
* '''wesnoth.unit_movement_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':movement(''terrain_code'')'''<br />
<br />
Returns the movement cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local move_cost = wesnoth.unit_movement_cost(u, "Gt")<br />
<syntaxhighlight><br />
<br />
==== wesnoth.unit_vision_cost ====<br />
<br />
* '''wesnoth.unit_vision_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':vision(''terrain_code'')'''<br />
<br />
Returns the vision cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local see_cost = wesnoth.unit_vision_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_jamming_cost ====<br />
<br />
* '''wesnoth.unit_jamming_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':jamming(''terrain_code'')'''<br />
<br />
Returns the jamming cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local jam_cost = wesnoth.unit_jamming_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_ability ====<br />
<br />
* '''wesnoth.unit_ability(''unit'', ''ability_tag'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':ability(''ability_tag'')'''<br />
<br />
Returns true if the unit is currently under effect by an ability with this given TAG NAME. This means that the ability could be owned by the unit itself, or by an adjacent unit.<br />
<br />
<syntaxhighlight lang='lua'><br />
function has_teleport(u)<br />
return wesnoth.unit_ability(u, "teleport")<br />
end<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_types ====<br />
<br />
This is not a function but a read-only table indexed by unit type ids. Its elements are proxy tables with these fields:<br />
<br />
* '''id''': string<br />
* '''name''': translatable string (read only)<br />
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)<br />
* '''abilities''': array of ability keys (strings), e.g. {"curing", "regenerates"}<br />
* {{DevFeature1.13|11}} '''advances_to''': array of unit types to which unit can advance<br />
* {{DevFeature1.13|11}} '''advances_from''': array of unit types from which unit can advance. Note: this is OOS-unsafe in Multiplayer games. Different clients may have additional Era-s with units upgradable to this unit type.<br />
* '''__cfg''': WML table (dump), see [[UnitTypeWML]]<br />
<br />
The metatable of these proxy tables appears as '''"unit type"'''.<br />
<br />
<syntaxhighlight lang='lua'><br />
local lich_cost = wesnoth.unit_types["Ancient Lich"].cost<br />
</syntaxhighlight><br />
<br />
Note that different clients have different set of available units in a Multiplayer game. It is OOS-unsafe to e.g. count the number of units.<br />
Presuming correctly written add-ons, it is still safe to e.g. access any given unit or its properties.<br />
<br />
==== wesnoth.races ====<br />
<br />
This is not a function but a table indexed by race ids. Its elements are proxy tables for all races the engine knows about.<br />
known fields of each element:<br />
* '''id''': string<br />
* '''description''', '''name''', '''plural_name''' (translatable strings)<br />
* '''num_traits''' (integer)<br />
* '''ignore_global_traits''' (boolean)<br />
* '''undead_variation''' (string)<br />
(all read only)<br />
* '''__cfg''': WML table (dump)<br />
<br />
<syntaxhighlight lang='lua'><br />
wesnoth.message(tostring(wesnoth.races["lizard"].name))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_traits ====<br />
<br />
* '''wesnoth.get_traits()'''<br />
<br />
Returns a table with named fields (trait id strings) holding the wml tables defining the traits. arguments: none. All global traits the engine knows about, race-specific traits are not included.<br />
Known fields and subtags of each element are the ones which were given in the wml definition of the [[SingleUnitWML|trait]].<br />
wesnoth.message(tostring(wesnoth.get_traits().strong.male_name))<br />
<br />
==== wesnoth.simulate_combat ====<br />
<br />
* '''wesnoth.simulate_combat(''attacker'', [''attacker_weapon_index''], ''defender'', [''defender_weapon_index''])'''<br />
<br />
Computes the hitpoint distribution and status chance after a combat between two units. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.<br />
<br />
Optional integers can be passed after each unit to select a particular weapon, otherwise the "best" one is selected. When giving the weapon, the parameter is the weapon number (integer, starting at 1) and not an element from the table returned by helper.child_range(att, "attack").<br />
<br />
<syntaxhighlight lang='lua'><br />
local function display_stats(n, t)<br />
wesnoth.message(string.format(<br />
"Chance for the %s\n to be slowed: %f,\n to be poisoned: %f,\n to die: %f.\nAverage HP: %f.",<br />
n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))<br />
end<br />
local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def, def_weapon)<br />
display_stats("attacker", att_stats)<br />
display_stats("defender", def_stats)<br />
</syntaxhighlight><br />
<br />
Returns 2 additional tables which contain information about the weapons and the effect of single hits with these keys: num_blows, damage, chance_to_hit, poisons, slows, petrifies, plagues, plague_type, backstabs, rounds, firststrike, drains, drain_constant, drain_percent, attack_num, name. <br />
Name is the wml name not the description. If there is no weapon, then name will be nil<br />
<br />
<syntaxhighlight lang='lua'><br />
local att_stats, def_stats, att_weapon, def_weapon = wesnoth.simulate_combat(attacker, att_weapon_number, defender)<br />
wesnoth.message(string.format(<br />
"The attack %s should be countered with %s, which does %d damage, has %d%% chance to hit and forces %d attack rounds due to its berserk ability.",<br />
att_weapon.name, def_weapon.name or "no weapon", def_weapon.damage, def_weapon.chance_to_hit, def_weapon.rounds))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.transform_unit ====<br />
<br />
* '''wesnoth.transform_unit(''unit'', ''to_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':transform(''to_type'')'''<br />
<br />
Changes the type of a unit and adjust attributes accordingly. Note that hit points are only changed if necessary to accommodate the new maximum hit points. Poison is automatically removed if the transformed unit is immune.<br />
<br />
<syntaxhighlight lang='lua'><br />
local ev = wesnoth.current.event_context<br />
local u = wesnoth.get_units{x=ev.x1, y=ev.y1}[1]<br />
wesnoth.transform_unit(u, "Spearman")<br />
-- If a full heal is desired:<br />
u.hitpoints = u.max_hitpoints<br />
u.status.poisoned = false<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_known_unit ====<br />
<br />
* {{DevFeature1.13|10}} '''wesnoth.add_known_unit(''unit_type_id'')'''<br />
<br />
adds the unit type with the given id to the list of known units (so that they appear in the help)<br />
<br />
==== wesnoth.create_animator ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.create_animator()'''<br />
<br />
Returns an object that can be used to set up and run an animation. The object has three methods:<br />
<br />
* '''animator:run()'''<br />
<br />
Runs the animation. {{DevFeature1.15|0}} Implicitly clears the animator.<br />
<br />
* '''animator:clear()'''<br />
<br />
Clears any units previously added to the animation.<br />
<br />
* '''animator:add(''unit'', ''flag'', ''hits'', ''params'')'''<br />
<br />
Adds a unit to the animation. The ''flag'' specifies which animation to play, and the ''hits'' parameter is required for attack animations to specify which variant of the animation to play. Possibly keys in ''params'' are:<br />
<br />
* '''facing''': A location. The animation will be played with the unit facing that location.<br />
* '''value''': Either a number or a list of two numbers. Use this to pass ''value'' and/or ''value_second'' to default animations that use them.<br />
* '''with_bars''': Whether to show HP bars and such while the animation plays.<br />
* '''text''': Text to float as the animation plays.<br />
* '''color''': Color of the floating text - a list of red, green, blue.<br />
* '''primary''': The primary weapon to use for the animation. Must be a Lua unit attack proxy.<br />
* '''secondary''': The secondary weapon to use for the animation.<br />
<br />
Normal usage would be to create it, call '''add''' one or more times, then call '''run'''.<br />
<br />
==== wesnoth.effects ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
This table contains the implementation of custom [[EffectWML|[effect]]]s. Each value is a function that takes a unit and the effect config. Note that the default effects defined by the Wesnoth engine are not in this table. <br />
<br />
<syntaxhighlight lang='lua'><br />
function wesnoth.effects.min_resistance(u, cfg)<br />
local resistance_new = {}<br />
local resistance_old = helper.parsed(helper.get_child(cfg, "resistance"))<br />
for k,v in pairs(resistance_old) do<br />
if type(k) == "string" and type(v) == "number" and wesnoth.unit_resistance(u, k) >= v then<br />
resistance_new[k] = v<br />
end<br />
end<br />
--important: use wesnoth.add_modification(..., false) so that the function will only execute the effects of that object and not store the object in the unit.<br />
wesnoth.add_modification(u, "object", {<br />
T.effect {<br />
apply_to = "resistance",<br />
replace = true,<br />
T.resistance (resistance_new),<br />
},<br />
}, false)<br />
end<br />
</syntaxhighlight><br />
<br />
The code above adds a new <code>min_resistance</code> effect that will set the resistances to specific values if they are currently below that value. It can then be used like this (for example, in [[DirectActionsWML#.5Bobject.5D|[object]]]):<br />
<br />
<syntaxhighlight lang='wml'><br />
[effect]<br />
apply_to=min_resistance<br />
[resistance]<br />
cold=50<br />
[/resistance]<br />
[/effect]<br />
</syntaxhighlight><br />
<br />
Note that in order work properly effects must be registered before any units are created. This means it must be places into toplevel or scenario/era/modification level [lua] tag and in particular must not be done from within a preload event.<br />
<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Built-in effects are now present in the <code>wesnoth.effects</code> table and can be called by custom effects or by other Lua code. They take the same two arguments that a custom effect function does - the unit, and the effect WML.<br />
<br />
In addition, you can now specify description modifiers to be used if a custom effect is placed in a <code>[trait]</code> tag. Instead of setting a function as the effect, you set a table with a <code>__call</code> metafunction which does what the function would have done. The table can then have an additional <code>__descr</code> metafunction which updates descriptions as necessary. The built-in effects all use this structure. This metafunction takes the same arguments as the regular effect function, but should not modify the unit. Instead, it returns a string to be appended to the trait's effect description.<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=ServerAdministration&diff=61129ServerAdministration2019-06-17T12:43:57Z<p>Vasya: /* Available commands */</p>
<hr />
<div>== Overview ==<br />
<br />
The Wesnoth server, [[wesnothd]] provides a simple interface for administering the server from within the game itself.<br />
<br />
To issue an administrative command to the server, you must be connected to the server using Wesnoth, and in the lobby. Any text you type into the chat box that '''begins with '/query ' (or '/q ')''' will be considered an administrative command instead of a normal chat message. It will not be relayed to other users, but instead treated as a command by the server.<br />
<br />
Most commands are not accessible to normal users. They are only accessible once you have authenticated yourself to the server as an administrator. The way to authenticate yourself as an administrator is to use the command,<br />
<br />
'''/query admin <password>'''<br />
<br />
where <password> is the administrative password to the server. The administrative password is specified as the passwd attribute in wesnothd.cfg. Naturally the password for a server should be kept a secret. One danger is that if you forget to type '/query ' at the start of a command you may accidentally type the password in a chat message, and let all users on the server know it. If you do this, then notify an administrator who has access to the box as soon as possible, so they can reset the password in wesnothd.cfg. We may provide features to prevent this kind of accident in future versions.<br />
<br />
A message from the server should tell you that you have successfully authenticated yourself as an administrator. The server will recognize you as an administrator until the next time you log out of the server. If the server has support for accounts it may also remember and authenticate you automatically as an administrator next time.<br />
<br />
== Available commands ==<br />
<br />
Note: Moderators of the official Wesnoth servers can utilize these commands [[ServerAdministration_FromIRC|via IRC]].<br />
<br />
<br />
'''/query report <message>''': sends a message to all moderators which also gets logged in case none is on. You can use this to report abuse, rule violations, etc. (available to non-administrators, duh)<br />
<br />
'''/query games''': shows how many games have ended in various ways. (available to non-administrators)<br />
<br />
'''/query metrics''': shows a simple metrics report of how the server has been performing. (available to non-administrators)<br />
<br />
'''/query netstats''': shows some network stats. (available to non-administrators)<br />
<br />
'''/query stats''': shows the current number of users and games. (available to non-administrators)<br />
<br />
'''/query wml''': shows stats about WML documents and their current memory consumption. (available to non-administrators)<br />
<br />
'''/query status [<nickname mask>]''': this command will show you a list of users (matching the nickname mask) connected to the server, with IP addresses, and how long they have been connected. Note that IP addresses of users are not available to non-administrators, and should be treated as confidential. When used as a non-administrator it just returns the entry of the user.<br />
<br />
'''/query motd [<message>]''': this command sets the message of the day that appears as the first message users get when they log on to the server. Without argument it returns the current motd. (available to non-administrators)<br />
<br />
'''/query msg <message>''': this command will relay the message 'message' to all users on the server, even if they are in a game. The message will appear to come from 'server', so you should write your name as part of the message if it is necessary to show who it comes from.<br />
<br />
'''/query lobbymsg <message>''': this command will relay the message 'message' to all users in the lobby of the server. The message will appear to come from 'server', so you should write your name as part of the message if it is necessary to show who it comes from.<br />
<br />
'''/query pm &lt;nick&gt; <message>''': sends a private message to a user. Sender name will be visible to receiver.<br />
<br />
'''/query clones''': shows a list of all users that have the same IP address as another one.<br />
<br />
'''/query kick <mask> [<reason>]''': this command will disconnect the user matching the given nickname or ip mask from the server.<br />
<br />
'''/query ban <mask> &lt;time&gt; <reason>''': this command will make the server refuse connections from users matching the given IP mask or the IPs of users matching the nickname mask. Existing bans (and their reason!) will be overwritten so you can change the reason for a ban by adding it again.<br />
<br />
'''/query gban <mask> <group> &lt;time&gt; <reason>''': this command will make a ban that belongs to a group. They function just like ordinary bans but only the group name is mentioned in the ban listing.<br />
<br />
'''/query bans''': shows a list of currently banned IP masks and the reasons for the bans.<br />
<br />
'''/query kban <mask> &lt;time&gt; <reason>''': this command is equivalent to 'kick <mask>' 'ban <mask> &lt;time&gt; <reason>' -- i.e. bans the users matching the IP mask or the IPs of users matching the nickname mask and disconnects them all in one go. The most common way to ban someone from the server.<br />
<br />
'''/query unban <ipmask>''': this command removes the specified IP mask from the ban list. To unban a user, unban the corresponding IP address.<br />
<br />
'''/query ungban <group>''': this command removes all bans in the group.<br />
<br />
'''/query searchlog <mask> (or /q sl <mask>)''': this returns the IP a nickname matching the mask has used or the nicknames that used a matching IP. Unlike status this searches the IP log.<br />
<br />
'''/query deny_unregistered_login [yes|no]''': If set to yes the server will refuse to let unregistered users log in. Without an argument the current setting is displayed. There is an alias 'dul' for convenience.<br />
<br />
<br />
Masks are arguments that can contain wildcards ('*' and '?'). '*' matches any number of characters (including none), and '?' any one character. IP masks are masks that contain at least one '.'.<br />
<br />
The time parameter is used to set the time when a ban expires. A simple example is 2D12h which means after 2 days and 12 hours the ban gets removed. Modifiers are: s=seconds, m=minutes, h=hours, D=days, M=months and Y=years (case doesn't actually matter except for minutes (m) and months (M); also you can write the modifiers (partially) out as in 2days12hours). Permanent bans can be set with 'permanent' or '0' as the time argument. We can also set shortcuts like LONG, MEDIUM and SHORT for common ban lengths but none is set yet.<br />
<br />
== Future extensions ==<br />
<br />
The current administrative interface is fairly primitive. We plan to provide some further extensions in the future, such as,<br />
<br />
'''/query mute <nickname>''': makes it so that any messages sent by the user with the given nickname will not be received by any other user on the server unless they share an IP address with 'nickname'. Any games created by 'nickname' will likewise not be seen by other users. 'nickname' may observe games but will not appear in the observer list, and players of the game will not see any messages they type.<br />
<br />
== See Also ==<br />
* [[CommandMode]]<br />
* [[DebugMode]]<br />
* [[ChatCommands]]<br />
* [[ServerAdministration_FromIRC|Server Administration via IRC]]<br />
<br />
[[Category:Troubleshooting and Bugs]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Events&diff=60995LuaWML/Events2019-05-07T13:58:22Z<p>Vasya: /* on_event.lua */</p>
<hr />
<div>This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.<br />
<br />
==== wesnoth.fire ====<br />
<br />
* '''wesnoth.fire(''wml_action_name'', ''wml_action_contents'')'''<br />
<br />
Fires a [[ActionWML|WML action]]. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.fire("message", { speaker="narrator", message=_ "Hello World!" })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.wml_actions ====<br />
<br />
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].<br />
<br />
<syntaxhighlight lang=lua><br />
function wesnoth.wml_actions.freeze_unit(cfg)<br />
local unit_id = cfg.id or helper.wml_error "[freeze_unit] expects an id= attribute."<br />
helper.modify_unit({ id = unit_id }, { moves = 0 })<br />
end<br />
</syntaxhighlight><br />
<br />
The new tag can now be used in plain WML code.<br />
<br />
<syntaxhighlight lang=wml><br />
[freeze_unit]<br />
id=Delfador<br />
[/freeze_unit]<br />
</syntaxhighlight><br />
<br />
You can override functions already assigned to the table. This is useful if you need to extend functionality of core tags. For instance, the following script overrides the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.<br />
<br />
<syntaxhighlight lang=lua><br />
function wesnoth.wml_actions.print(cfg)<br />
cfg.size = (cfg.size or 12) + 10<br />
wml_actions.print(cfg)<br />
end<br />
</syntaxhighlight><br />
<br />
Note: When calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the handler. In particular, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Moreover, table arguments might be modified by the action handler, so they should usually not be reused for consecutive calls. If variable substitution should happen and/or table content should be preserved, one can call [[#wesnoth.tovconfig]] and pass its result to the handler. Calling [[#wesnoth.fire]] is another possibility.<br />
<br />
==== wesnoth.wml_conditionals ====<br />
<br />
{{DevFeature1.13|0}}<br />
<br />
This is an associative table like wesnoth.wml_actions. You can use it to define new conditional wml tags that will be recognized in WML when using [if], [show_if], [while], etc., or more generally when '''wesnoth.eval_conditional''' is run.<br />
<br />
Use it like<br />
<br />
<syntaxhighlight lang=lua><br />
function wesnoth.wml_conditionals.foo(cfg)<br />
local bar = cfg.bar or error("[foo] tag did not have 'bar' attribute")<br />
<br />
return (bar == "baz")<br />
end<br />
</syntaxhighlight><br />
<br />
If this lua code is executed, it would make the following syntax be valid WML in your add-on:<br />
<br />
<syntaxhighlight lang=wml><br />
[if]<br />
[foo]<br />
bar = $X<br />
[/foo]<br />
[then]<br />
[message]<br />
...<br />
[/message]<br />
[/then]<br />
[/if]<br />
</syntaxhighlight><br />
<br />
You cannot override the meaning of any core conditional tags.<br />
<br />
==== wesnoth.game_events ====<br />
<br />
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.<br />
<br />
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.<br />
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.<br />
* '''on_event''': function called before each WML event is executed; its argument is the event name; other event arguments can be recovered from [[LuaWML:Misc#wesnoth.current|wesnoth.current.event_context]].<br />
* '''on_mouse_action''': function called when the user leftclicks on hex; its arguments are x,y of location selected. {{DevFeature1.13|10}} Might be from earlier 1.13, not tested.<br />
<br />
''on_mouse_action'' has several gotchas. Currently (1.14.1), the sequence goes like this:<br />
* The player clicks the mouse (mousedown followed by mouse up in the same hex).<br />
* on_mouse_action triggers, for that hex.<br />
* the click has its normal UI effect (such as selecting or moving a unit), based on the '''current''' position of the mouse.<br />
Thus, if you display any sort of animation during the on_mouse_action function, the player may have ''moved'' the mouse, causing a mouse-click effect to happen in a place they didn't expect, which is also different than the location that was passed to on_mouse_action. In addition, there are the usual gotchas about this function not being synchronized for network games or replays. See also: https://github.com/wesnoth/wesnoth/issues/2325<br />
<br />
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.<br />
<br />
<syntaxhighlight lang=lua><br />
-- some value that survives save/load cycles, but that is not forwarded to the next level<br />
local level_local_data = 0<br />
<br />
local old_on_load = wesnoth.game_event.on_load<br />
function wesnoth.game_event.on_load(cfg)<br />
for i = 1,#cfg do<br />
if cfg[i][1] == "my_data" then<br />
-- recover the value stored in the savefile<br />
level_local_data = cfg[i][2].value<br />
-- erase the child, since it has been handled<br />
table.remove(cfg, i)<br />
break<br />
end<br />
end<br />
-- call the previous hook, in case there are still some containers in the savefile<br />
old_on_load(cfg)<br />
end<br />
<br />
local old_on_save = wesnoth.game_events.on_save<br />
function wesnoth.game_events.on_save()<br />
-- call the previous hook, in case it had some containers to store<br />
local cfg = old_on_save()<br />
-- add our own container to them<br />
table.insert(cfg, { "my_data", { value = level_local_data } })<br />
-- tell the engine to store them in the savefile<br />
return cfg<br />
end<br />
</syntaxhighlight><br />
<br />
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.<br />
<br />
<br />
Note: Some tag names are reserved for engine use and should not be modified using the above on_save/on_load method. These tag names are:<br />
"color_palette", "color_range", "era", "event", "generator", "label",<br />
"lua", "menu_item", "music", "next_item_name", "objectives", "side", "sound_source",<br />
"story", "terrain_graphics", "time", "time_area", "tunnel", "used_item", "variables"<br />
<br />
Note: a on_event handler will not prevent undoing of that event, so usually you need to add an event to diallow undo to prevent OOS. You can add an event handler for that event inside a on_event callback. A possible way to define a disallow_undo function is:<br />
<br />
<syntaxhighlight lang=lua><br />
function disallow_undo()<br />
wesnoth.wml_actions.event { name = wesnoth.current.event_context.name }<br />
end<br />
</syntaxhighlight><br />
Which should then be called from every on_event callback which changes the gamestate.<br />
<br />
{{DevFeature1.13|5}}:<br />
The event names passed to ''on_event'' always use underscores instead of spaces<br />
<br />
==== wesnoth.persistent_tags ====<br />
<br />
{{DevFeature1.13|12}}<br />
<br />
This is an associative table defining tags that should be persisted in saved games. Each tag is itself a table containing two functions, read and write. The write function is called in <tt>on_load</tt> and passed a function as a parameter which takes a WML table and adds it the saved game under the specified tag; the read function is called once per matching tag found in the saved game, and is passed a WML table of its contents. Note the asymmetry here: if you're saving an array, the write function is responsible for saving the entire array (and is only called once), while the read function is only responsible for loading one item (and is called several times).<br />
<br />
Example:<br />
<br />
<syntaxhighlight lang=lua><br />
local inventory = {}<br />
<br />
function wesnoth.persistent_tags.inventory.read(cfg)<br />
inventory[cfg.side] = cfg<br />
end<br />
<br />
function wesnoth.persistent_tags.inventory.write(add)<br />
for i = 1, #wesnoth.sides do<br />
add(inventory[i])<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
Notice that you don't need to create <tt>wesnoth.persistent_tags.inventory</tt> as an empty table first; you can simply define the read and write functions.<br />
<br />
==== wesnoth.fire_event ====<br />
<br />
* '''wesnoth.fire_event(''event_name'', [''x1'', ''y1'', [''x2'', ''y2'']], [''first_weapon'', [''second_weapon'']])'''<br />
<br />
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables "unit", "second_unit", "weapon", and "second_weapon". These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.<br />
<br />
wesnoth.fire_event("explosion", 17, 42, { damage = "fire" })<br />
<br />
==== wesnoth.fire_event_by_id ====<br />
{{DevFeature1.13|6}}<br />
<br />
* '''wesnoth.fire_event_by_id(''event_id'', [''x1'', ''y1'', [''x2'', ''y2'']], [''first_weapon'', [''second_weapon'']])'''<br />
<br />
Fires a single WML event with the given id. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of the event handler, and are used to fill the WML variables "unit", "second_unit", "weapon", and "second_weapon". These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.<br />
<br />
wesnoth.fire_event_by_id("explosion_1", 17, 42, { damage = "fire" })<br />
<br />
==== wesnoth.add_event_handler ====<br />
<br />
* '''wesnoth.add_event_handler(''cfg'')'''<br />
<br />
{{DevFeature1.13|0}}<br />
<br />
Registers a new event handler. This takes a WML table containing the same information normally used by the [[EventWML#The_.5Bevent.5D_Tag|[event]]] tag.<br />
<br />
==== wesnoth.remove_event_handler ====<br />
<br />
* '''wesnoth.remove_event_handler(''id'')'''<br />
<br />
{{DevFeature1.13|0}}<br />
<br />
Removes an event handler. This requires the event handler to have been assigned an [[EventWML#id|id]] at creation time.<br />
<br />
==== wesnoth.eval_conditional ====<br />
<br />
* '''wesnoth.eval_conditional(''conditional_tags'')'''<br />
<br />
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.<br />
<br />
<syntaxhighlight lang=lua><br />
local result = wesnoth.eval_conditional {<br />
{ "have_unit", { id = "hero" } },<br />
{ "variable", { name = "counter", numerical_equals = "$old_counter" } }<br />
}<br />
</syntaxhighlight><br />
<br />
==== wesnoth.tovconfig ====<br />
<br />
* '''wesnoth.tovconfig(''config'')'''<br />
<br />
Converts a WML table into a proxy object which performs variable substitution on the fly.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.set_variable("varname", "to_be_deleted")<br />
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" } -- correct<br />
wesnoth.wml_actions.clear_variable { name = "$varname" } -- error: try to delete a variable literally called "$varname"<br />
wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = "$varname" }) -- correct: "$varname" is replaced by "to_be_deleted" at the right time<br />
</syntaxhighlight><br />
<br />
==== helper.set_wml_action_metatable ====<br />
<br />
* '''helper.set_wml_action_metatable{}'''<br />
<br />
Sets the metatable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].<br />
<br />
<syntaxhighlight lang=lua><br />
local W = helper.set_wml_action_metatable {}<br />
W.message { speaker = "narrator", message = "?" }<br />
</syntaxhighlight><br />
<br />
==== helper.wml_error ====<br />
<br />
* '''helper.wml_error(''message'')'''<br />
<br />
Interrupts the current execution and displays a chat message that looks like a WML error.<br />
<br />
<syntaxhighlight lang=lua><br />
local names = cfg.name or helper.wml_error("[clear_variable] missing required name= attribute.")<br />
</syntaxhighlight><br />
<br />
==== helper.literal ====<br />
<br />
* '''helper.literal(''config'')'''<br />
<br />
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. 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).<br />
<br />
<syntaxhighlight lang=lua><br />
function wml_actions.display_literal_value(cfg)<br />
cfg = helper.literal(cfg)<br />
wesnoth.message(tostring(cfg.value)) <br />
end<br />
</syntaxhighlight><br />
<br />
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.<br />
<br />
==== helper.parsed ====<br />
<br />
* '''helper.parsed(''config'')'''<br />
<br />
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
==== helper.shallow_literal ====<br />
<br />
* '''helper.shallow_literal(''config'')'''<br />
<br />
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
==== helper.shallow_parsed ====<br />
<br />
* '''helper.shallow_parsed(''config'')'''<br />
<br />
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
=== on_event.lua ===<br />
<br />
{{DevFeature1.13|6}}<br />
<br />
* '''on_event(''name'', [ ''priority'',] ''function'')'''<br />
<br />
The file ''data/lua/on_event.lua'' provides a simple way to register lua functions as wml event handlers.<br />
<br />
<syntaxhighlight lang=lua><br />
local on_event = wesnoth.require("lua/on_event.lua")<br />
on_event("moveto", function(context)<br />
if context.x1 == 10 and context.y1 == 11 then<br />
wesnoth.message("unit moved to (10,11)")<br />
end<br />
end)<br />
<br />
on_event("die", function(context)<br />
if context.x1 == 20 and context.y1 == 21 then<br />
wesnoth.message("unit died at (20,21)")<br />
end<br />
end)<br />
</syntaxhighlight><br />
<br />
The passed function will be called with '''wesnoth.current.event_context''' as paremter. This isn't as powerful as wml event handlers though: Filters must be implemented with an if in the function body (as shown above with ''context.x1 == 10 and context.x1 == 11''). There is no way to remove those event handlers, in particular they behave like ''first_time_only=no'' events. They are not persisted on save/load so they must be re-defined on each load (e.g. in a preload event).<br />
Events are executed from lowest priority to highest.<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=DirectActionsWML&diff=59960DirectActionsWML2018-09-20T18:56:42Z<p>Vasya: /* [remove_object] */</p>
<hr />
<div>{{WML Tags}}<br />
== Direct actions ==<br />
<br />
Direct actions are actions that have a direct effect on gameplay. They can be used inside of [[EventWML|events]].<br />
<br />
The following tags are actions:<br />
<br />
=== [endlevel] ===<br />
Ends the scenario.<br />
* '''result''': before the scenario is over, all events with ''name=result'' are triggered. If ''result=victory'', the player progresses to the next level (i.e., the next scenario in single player); if ''result=defeat'', the game returns to the main menu. <br />
<br />
When the result is "victory" the following keys can be used:<br />
* '''bonus''': whether the player should get bonus gold (maximum possible gold that could have been earned by waiting the level out). The default is bonus=yes. {{DevFeature1.13|2}} Alternatively, a number, defining the bonus multiple (1.0 meaning full).<br />
* '''carryover_report''': whether the player should receive a summary of the scenario outcome, the default is carryover_report=yes.<br />
* '''save''': whether a start-of-scenario save should be created for the next scenario, the default is save=yes. Do not confuse this with saving of replays for the current scenario.<br />
* '''replay_save''': whether a replay save for the current scenario is allowed, the default is replay_save=yes. If yes, the player's settings in preferences will be used to determine if a replay is saved. If no, will override and not save a replay.<br />
* '''linger_mode''': If ...=yes, the screen is greyed out and there's the possibility to save before advancing to the next scenario, the default is linger_mode=yes.<br />
* '''reveal_map''': (Multiplayer only) (Default is 'yes') If 'no', shroud doesn't disappear when game ended.<br />
* '''next_scenario''': (default specified in '''[scenario]''' tag) the ID of the next scenario that should be played. All units that side 1 controls at this point become available for recall in ''next_scenario''.<br />
* '''carryover_percentage''': by default 80% of the gold is carried over to the next scenario, with this key the amount can be changed.<br />
* '''carryover_add''': if yes the gold will be added to the starting gold the next scenario, if no the next scenario will start with the amount of the current scenario (after taxes) or the minimum in the next scenario. Default is no.<br />
* '''music''': (default specified in '''[scenario]''' or '''[game_config]''' tags) a comma-separated list of music tracks from which one will be chosen and played once after any events related to the end of level result are executed; by default, victory_music is used on victory, and defeat_music on defeat.<br />
* '''end_credits''': Whether to display the credits screen at the end of a single-player campaign. Defaults to ''yes''. Note that this has cumulative effects over the campaign - it persists even if the endlevel does not trigger the end of the campaign. See also [[CampaignWML]].<br />
* '''end_text''': (translatable) Text that is shown centered in a black screen at the end of a campaign. Defaults to "The End". Note that this has cumulative effects over the campaign - it persists even if the endlevel does not trigger the end of the campaign. See also [[CampaignWML]].<br />
* '''end_text_duration''': Delay, in milliseconds, before displaying the game credits at the end of a campaign. In other words, for how much time '''end_text''' is displayed on screen. Defaults to 3500. Note that this has cumulative effects over the campaign - it persists even if the endlevel does not trigger the end of the campaign. See also [[CampaignWML]].<br />
* <strike>'''[next_scenario_settings]''': Any tags or attribute children of this optional argument to [endlevel] are merged into the scenario/multiplayer tag of the *next* scenario. This allows you to e.g. reconfigure the [side] tags or settings, just before load. </strike> This feature was removed in 1.11.17, it might be redesigned and reintroduced.<br />
* <strike>'''[next_scenario_append]''': Any tags of this optional argument are appended at high level to the next scenario. This is most appropriate for [event] tags, although you may find other uses. Example test scenario for these features: https://gna.org/support/download.php?file_id=20119 </strike> This feature was removed in 1.11.17, it might be redesigned and reintroduced.<br />
* '''[result]''' {{DevFeature1.13|0}} Allows specification of a side specific result, this is for competitive multiplayer scenarios/campaigns where it might happen that one player wins but another player loses. The following attributes are accepted and have the same effect as in '''[endlevel]''':<br />
** '''result'''<br />
** '''bonus'''<br />
** '''carryover_percentage'''<br />
** '''carryover_add'''<br />
<br />
And there is also<br />
** '''side''' The number of the side for which these results should apply.<br />
<br />
=== [unit] ===<br />
Creates a unit (either on the map, on a recall list, or into a variable for later use.) For syntax see [[SingleUnitWML]].<br />
* {{Short Note:Predefined Macro|GENERIC_UNIT}}<br />
<br />
=== [recall] ===<br />
Recalls a unit taking into account any [http://wiki.wesnoth.org/SingleUnitWML filter_recall] of the leader. The unit is recalled free of charge, and is placed near its leader, e.g., if multiple leaders are present, near the first found which would be able to normally recall it.<br />
<br />
If neither a valid map location is provided nor a leader on the map would be able to recall it, the tag is ignored.<br />
<br />
* [[StandardUnitFilter]]: the first matching unit will be recalled. If no units match this tag is ignored. Do not use a [filter] tag. If a comma separated list is given, every unit currently considered for recall is checked against all the types (not each single one of the types against all units).<br />
* '''x,y''': the unit is placed here instead of next to the leader.<br />
* '''show''': yes/no, default yes: whether the unit is animated (faded in) or instantly displayed<br />
* '''fire_event''': boolean yes|no (default no); whether any according prerecall or recall events shall be fired.<br />
* '''check_passability''': (boolean yes|no, default yes): If yes, checks for terrain passability when placing the unit (a nearby passable hex is chosen).<br />
* '''[secondary_unit]''': {{DevFeature1.13|?}} If present and show=yes, a matching unit will be chosen and their recruiting animation played.<br />
<br />
=== [teleport] ===<br />
Teleports a unit on map. {{Short Note:Predefined Macro|TELEPORT_UNIT}}<br />
* '''[filter]''': [[StandardUnitFilter]] the first unit matching this filter will be teleported.<br />
* '''x,y''': the hex to teleport to. If that hex is occupied, the closest unoccupied hex will be used instead.<br />
* '''clear_shroud''': should shroud be cleared on arrival<br />
* '''animate''': should a teleport animation be played (if the unit doesn't have a teleport animation, it will fade out/fade in)<br />
* '''check_passability''': (boolean yes|no, default yes): normally, units will not be teleported into terrain that is impassable for them. Setting this attribute to "no" permits it.<br />
<br />
(Note: There is also a ability named teleport, see [[AbilitiesWML]].)<br />
<br />
=== [terrain_mask] ===<br />
Changes the terrain on the map. See [[TerrainMaskWML]].<br />
<br />
=== [terrain] ===<br />
Changes the terrain on the map.<br />
* '''terrain''': the character of the terrain to use. See [[TerrainCodesWML]] to see what letter a type of terrain uses.<br />
* [[StandardLocationFilter]]. This [[StandardLocationFilter]]'s terrain= key is used for the new terrain, filtering by terrain can be done with a nested [[StandardLocationFilter]]: [and]terrain=terrain_string_to_be_filtered_for.<br />
* '''layer''': (overlay|base|both, default=both) only change the specified layer.<br />
* '''replace_if_failed''': (default=no) When replacing just one layer failed, try to replace the whole terrain. If '''terrain''' is an overlay only terrain, use the default_base as base layer. If the terrain has no default base, do nothing.<br />
<br />
If you want to remove the overlays from a terrain and leave only the base, use:<br />
layer=overlay<br />
terrain="^"<br />
<br />
<b>Note:</b> When a hex changes from a village terrain to a non-village terrain, and a team owned that village it loses that village. When a hex changes from a non-village terrain to a village terrain and there is a unit on that hex it does not automatically capture the village. The reason for not capturing villages it that there are too many choices to make; should a unit lose its movement points, should capture events be fired. It is easier to do this as wanted by the author in WML.<br />
<br />
=== [gold] ===<br />
Gives sides gold.<br />
* '''amount''': the amount of gold to give.<br />
* '''side''': (default=1) the number of the side to give the gold to. Can be a comma-separated list of sides. note: Default side=1 for empty side= is deprecated.<br />
* [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF.<br />
<br />
=== [unstore_unit] ===<br />
Creates a unit from a game variable, and activates it on the playing field. This must be a specific variable describing a unit, and may not be an array -- to unstore an entire array, iterate over it. The variable is not cleared. See also [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]], [[ConditionalActionsWML#.5Bwhile.5D|[while]]] and [[InternalActionsWML#.5Bclear_variable.5D|[clear_variable]]].<br />
* '''variable''': the name of the variable.<br />
* '''find_vacant''': whether the unit should be placed on the nearest vacant tile to its specified location. If this is set to 'no'(default), then any unit on the same tile as the unit being unstored will be destroyed. <br />
* '''check_passability''': (boolean yes|no, default yes): If yes, checks for terrain passability when placing the unit. This key has no effect if find_vacant=no (no check performed then). Before 1.9 this key is always "no".<br />
* '''text''': (translatable) floating text to display above the unit, such as a damage amount<br />
* '''male_text''', '''female_text''': {{DevFeature1.13|2}} (translatable) gender-specific versions of the above<br />
* '''red''', '''green''', '''blue''': (default=0,0,0) the color to display the text in. Values vary from 0-255. You may find it convenient to use the {COLOR_HARM} or {COLOR_HEAL} macro instead. (Use {COLOR_HARM} or {COLOR_HEAL} instead of the whole red,green,blue= line.)<br />
* '''advance''': (default=yes) if yes the unit is advanced if it has enough XP. When modifying XP make sure to do it from inside a [[EventWML#Multiplayer_safety|synchronized event]] or it may lead to OOS errors especially when several advancement paths exist. Note that advance and post advance events are called, so infinite loops can happen.<br />
* '''fire_event''': (boolean yes|no, default no) Whether any advance/post advance events shall be fired if an advancement takes place, no effect otherwise.<br />
* '''animate''': (boolean yes|no, default yes) Whether "levelout" and "levelin" (or fade to white and back) animations shall be played if an advancement takes place, no effect otherwise.<br />
* '''x''' ,'''y''': override unit location, "x,y=recall,recall" will put the unit on the unit's side's recall list.<br />
Units can be unstored with negative (or zero) hit points. This can be useful if modifying a unit in its last_breath event (as the unit's death is already the next step), but tends to look wrong in other cases. In particular, it is possible to have units with negative hit points in play. Such units are aberrations, subject to unusual behavior as the game compensates for them. (For example, such units are currently automatically hit&ndash;and killed&ndash;in combat.) The details of the unusual behavior are subject to change between stable releases without warning.<br />
<br />
=== [allow_recruit] ===<br />
Allows a side to recruit units it couldn't previously recruit.<br />
* '''type''': the types of units that the side can now recruit.<br />
* '''side''': (default=1) the number of the side that is being allowed to recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated.<br />
* [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF.<br />
<br />
=== [allow_extra_recruit] ===<br />
Allows a leader to recruit units it couldn't previously recruit.<br />
These types add to the types the leader can recruit because of [side]recruit=.<br />
* '''extra_recruit''': the types of units that the unit can now recruit.<br />
* '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units.<br />
<br />
=== [disallow_recruit] ===<br />
Prevents a side from recruiting units it could previously recruit.<br />
* '''type''': the types of units that the side can no longer recruit. {{DevFeature1.13|0}} If omitted, all recruits for matching sides will be disallowed.<br />
* '''side''': (default=1) the number of the side that may no longer recruit the units. This can be a comma-separated list note: Default side=1 for empty side= is deprecated.<br />
* [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF.<br />
<br />
=== [disallow_extra_recruit] ===<br />
Prevents a leader from recruiting units it could previously recruit.<br />
* '''extra_recruit''': the types of units that the side can no longer recruit.<br />
* '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units.<br />
<br />
=== [set_recruit] ===<br />
Sets the units a side can recruit.<br />
* '''recruit''': the types of units that the side can now recruit.<br />
* '''side''': (default=1) the number of the side that is having its recruitment set. This can be a comma-separated list. note: Default side=1 for empty side= is deprecated.<br />
* [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF.<br />
<br />
=== [set_extra_recruit] === <br />
Sets the units a leader can recruit.<br />
* '''extra_recruit''': the types of units that the leader can now recruit.<br />
* '''[[StandardUnitFilter]]''': All units matching this filter are modified. Does not match on recall list units.<br />
<br />
=== [modify_side] ===<br />
Modifies some details of a given side in the middle of a scenario. '''The following listed properties are the only properties that [modify_side] can affect!'''<br />
* '''side''': (default=1) the number of the side that is to be changed. note: Default side=1 for empty side= is deprecated.<br />
* '''[filter_side]''' with a [[StandardSideFilter]] as argument<br />
* '''income''': the income given at the begining of each turn.<br />
* '''recruit''': a list of unit types, replacing the side's current recruitment list.<br />
* '''team_name''': the team in which the side plays the scenario.<br />
* '''user_team_name''': a translatable string representing the team's description. This has no effect on alliances. Defaults to ''team_name''.<br />
* '''side_name''': {{DevFeature1.13|?}} a translatable string representing the side leader's description.<br />
* '''gold''': the amount of gold the side owns.<br />
* '''village_gold''': the income setting per village for the side.<br />
* '''controller''': the identifier string of the side's controller. Uses the same syntax of the ''controller'' key in the [[SideWML|[side]]] tag. warning: in multiplayer, changing the controller of a side might result in OOS during some events like, for example 'side_turn_end'; see [https://github.com/wesnoth/wesnoth/issues/2563 issue #2563].<br />
* '''fog''': a boolean string (yes/no) describing the status of Fog for the side.<br />
* '''shroud''': a boolean string describing the status of Shroud for the side.<br />
* '''hidden''': a boolean string specifying whether side is shown in status table.<br />
* '''color''': a team color range specification, name (e.g. "red", "blue"), or number (e.g. "1", "2") for this side. The default color range names, numbers, and definitions can be found in data/core/team_colors.cfg.<br />
* '''[ai]''': sets/changes AI parameters for the side. Only parameters that are specified in the tag are changed, this does not reset others to their default values. Uses the same syntax as described in [[AiWML]]. Note that [modify_side][ai] works for all simple AI parameters and some, but not all, of the composite ones. If in doubt, use [http://wiki.wesnoth.org/AiWML#Adding_and_Deleting_Aspects_with_the_.5Bmodify_ai.5D_Tag [modify_ai]] instead, which always works. {{DevFeature1.13|?}} If this contains an '''ai_algorithm''', the AI parameters will be reset to those of the indicated AI before adding any additional parameters included in the tag. In other words, this allows replacing the AI config rather than appending to it.<br />
* '''switch_ai''': replaces a side ai with a new AI from specified file(ignoring those AI parameters above). Path to file follows the usual WML convention.<br />
* '''reset_maps''': If set to "yes", then the shroud is spread to all hexes, covering the parts of the map that had already been explored by the side, including hexes currently seen. (Seen hexes will be cleared at the end of most events; they can also be manually cleared with {{tag|InterfaceActionsWML|redraw}}.) This is only effective if shroud is on, but this is evaluated after shroud= (and before shroud_data=).<br />
* '''reset_view''': If set to "yes", then the fog of war is spread to all hexes, covering the parts of the map that had already been seen this turn by the side, including hexes currently seen, excluding hexes affected by multi-turn {{tag|DirectActionsWML|lift_fog}}. (Seen hexes will be cleared at the end of most events; they can also be manually cleared with {{tag|InterfaceActionsWML|redraw}}.) This is only effective if fog is on, but this is evaluated after fog=.<br />
* '''share_maps''': change the share_maps side attribute. Be sure to use shroud=yes for that side and have it as an ally<br />
* '''share_view''': change the share_view side attribute. Be sure to use fog=yes for that side and have it as an ally<br />
* '''share_vision''': change both the above at the same time<br />
* '''shroud_data''': changes to the side's shroud, using the same format as when defining the [side].<br />
* '''suppress_end_turn_confirmation''': Boolean value controlling whether or not a player is asked for confirmation when skipping a turn.<br />
* '''scroll_to_leader''': Boolean value controlling whether or not the game view scrolls to the side leader at the start of their turn when present.<br />
* '''flag''': Flag animation for villages owned by this side (see [[SideWML|[side]]]).<br />
* '''flag_icon''': Flag icon used for this side in the status bar (see [[SideWML|[side]]]).<br />
* '''village_support''': The number of unit levels this side is able to support (does not pay upkeep on) per village it controls.<br />
* '''defeat_condition''' {{DevFeature1.13|0}}: When the side is considered defeated (see [[SideWML|[side]]]).<br />
<br />
=== [modify_turns] ===<br />
Modifies the turn limit in the middle of a scenario.<br />
* '''value''': the new turn limit.<br />
* '''add''': if used instead of ''value'', specifies the number of turns to add to the current limit (can be negative).<br />
* '''current''': changes the current turn number after applying turn limit modifications, if any. It is not possible to change the turn number to exceed the turn limit (1 <= current turns <= max turns).<br />
<br />
=== [allow_end_turn] ===<br />
Allows human players to end their turn through the user interface if they were previously affected by the '''[disallow_end_turn]''' action. This action doesn't take any arguments.<br />
<br />
=== [disallow_end_turn] ===<br />
Disallows human players to end their turn through the user interface. This action doesn't take any arguments.<br />
<br />
=== [capture_village] ===<br />
Changes the ownership of a village.<br />
* [[StandardLocationFilter]]: all village locations matching the filter are affected.<br />
* '''side''': the side that takes control of the village. This side needs to have a leader (canrecruit=yes). If the side key is not given, the village will become neutral (unless [filter_side] is present, in which case that side fiter decides, see below).<br />
* '''[filter_side]''' with [[StandardSideFilter]] tags and keys as arguments; if both this tag and inline side= are present it's an error. Otherwise, the first matching side gets ownership (or the village becomes neutral if none match).<br />
* '''fire_event''' (boolean yes|no, default: no): Whether any capture events shall be fired.<br />
<br />
=== [kill] ===<br />
Removes all units (including units in a recall list) that match the filter from the game.<br />
* [[StandardUnitFilter]]: Selection criterion; do not use a [filter] tag.<br />
* '''animate''' (default 'no'): if 'yes', displays the unit dying (fading away). {{DevFeature1.13|8}} If '''[secondary_unit]''' is given, also plays the victory animation of that unit.<br />
* '''fire_event''' (default 'no'): if 'yes', triggers any appropriate 'die' events (See [[EventWML]]). Note that events are only fired for killed units that have been on the map (as opposed to recall list).<br />
* '''[secondary_unit]''' with a [[StandardUnitFilter]] as argument. Do not use a [filter] tag. Has an effect only if fire_event=yes ({{DevFeature1.13|8}} or if it has a victory animation and animate=yes). The first on-map unit matching the filter becomes second_unit in any fired die and last breath events. If an on-map unit matches and if there are several units killed with a single [kill] tag, second_unit is this same unit for all of them. If no on-map unit matches or [secondary_unit] isn't present, the variable second_unit in each of the die and last breath events is always the same as the variable unit (the dying unit).<br />
* '''[primary_attack]''', '''[secondary_attack]''' {{DevFeature1.13|8}} The attacks to use for matching the animation. Useful for example on the wose, whose death animation depends on the damage type it was killed by.<br />
<br />
=== [move_unit] ===<br />
works like the MOVE_UNIT macro.<br />
* [[StandardUnitFilter]] as argument; do not use a [filter] tag. All units matching the filter are moved. If the target location is occupied, the nearest free location is chosen.<br />
* '''to_x''' (unsigned integer): The units are moved to this x coordinate. Can be a comma-separated list, in which case the unit follows this given path during the move.<br />
* '''to_y''' (unsigned integer): The units are moved to this y coordinate. Can be a comma-separated list.<br />
* '''fire_event''' (optional, boolean yes|no, default no): Whether any according moveto events shall be fired. The target location ($x1, $y1 in the event) may not be the same location that the unit was tried to be moved to, if the original target location is occupied or impassable.<br />
* '''check_passability''' (boolean yes|no, default yes): Whether the terrain the unit is moved to should be checked for suiting the unit. (If it does not, a nearby suitable hex is chosen.)<br />
* '''force_scroll''': Whether to scroll the map or not even when [[InterfaceActionsWML#.5Block_view.5D|[lock_view]]] is in effect or ''Follow Unit Actions'' is disabled in ''Advanced Preferences''. Defaults to using [[InterfaceActionsWML#.5Bmove_unit_fake.5D|[move_unit_fake]]]'s default value.<br />
<br />
=== [modify_ai] ===<br />
Changes AI objects (aspects, goals, candidate actions or stages) for a specified side. See [[Modifying_AI_Components#The_.5Bmodify_ai.5D_Tag|Modifying AI Components]] for full description.<br />
<br />
* '''action''' (string): Takes values 'add', 'change', 'delete' or 'try_delete' to do just that for the AI object.<br />
* '''path''' (string): Describes which AI object is to be modified. <br />
* '''[facet]''', '''[goal]''', '''[candidate_action]''' or '''[stage]''': Details about the AI object to be modified.<br />
* [[StandardSideFilter]] tags and keys; default for empty side= is all sides, as usual in a SSF.<br />
<br />
=== [modify_unit] ===<br />
works similar to the MODIFY_UNIT macro.<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter are modified. Matches on recall list units too.<br />
* '''[object]''', '''[trait]''', {{DevFeature1.13|5}} '''[advancement]''' - The given modifications will be immediately applied to all units matching the filter.<br />
** '''delayed_variable_substitution''' {{DevFeature1.13|5}} (boolean yes|no, default no): If set to "yes", the wml block contained in this [object], [trait], or [advancement] is not variable-substituted at execution time of the event containing this [modify_unit]. You need this for any effect that uses variable substitution or when using [effect][filter] with a $this_unit. {{DevFeature1.13|9}} This is no longer needed when adding ABILITY_TELEPORT, ABILITY_LEADERSHIP or SPECIAL_BACKSTAB.<br />
* '''[effect]''' {{DevFeature1.13|6}} Applies the effect directly to the unit.<br />
* Accepts generally the syntax inside of wml unit variables created by [store_unit] which can be viewed in a savefile or by using the [[CommandMode|inspect command]]. Cannot remove things or add/alter unit animations. Subtags with the same name must be written in the correct order to match them with the tag they are supposed to modify. Note that keys will be processed in arbitrary order, which may cause problems if you use formulas that depend on other formulas. To work around this you may need to use the tag twice with the same filter.<br />
example usage (see also the test scenario):<br />
<syntaxhighlight lang='wml'><br />
[modify_unit]<br />
[filter]<br />
x,y=38,6<br />
[/filter]<br />
hitpoints=10<br />
{TRAIT_HEALTHY}<br />
[/modify_unit]<br />
</syntaxhighlight><br />
<br />
The unit which is currently modified is accessible via $this_unit, e.g. hitpoints = "$($this_unit.hitpoints / 2)" to set the hitpoints of all units to half of their particular maxima. This this_unit variable is independent from the this_unit variable available in the SUF used to determine which units to modify (first all matching units are gathered, and then all those are modified).<br />
<br />
=== [transform_unit] ===<br />
Transforms every unit on the map matching the filter to the given unit type. Keeps intact hit points, experience and status. If the unit is transformed to a non-living type (undead or mechanical), it will be also unpoisoned. Hit points will be changed if necessary to respect the transformed unit's maximum hit points.<br />
* [[StandardUnitFilter]]: do not use a [filter] tag.<br />
* '''transform_to''': the unit type in which all the units matching the filter will be transformed. If missing, the units will follow their normal advancement.<br />
<br />
=== [petrify] ===<br />
<br />
* [[StandardUnitFilter]] as an argument. Do not use a [filter] tag. All units matching this filter are petrified. Recall list units are included.<br />
<br />
=== [unpetrify] ===<br />
* [[StandardUnitFilter]] as an argument. Do not use a [filter] tag. All units matching this filter are unpetrified. Recall list units are included.<br />
<br />
=== [object] ===<br />
Gives some unit an object which modifies their stats in some way.<br />
* '''id''': (Optional) allows the item to be removed later. By default, an object with a defined ID can only be picked up once per scenario, even if it is removed later or first_time_only=no is set for the event. You can remove this restriction by setting take_only_once=no. For filtering objects, it might be simpler to use a custom key such as item_id. The id string can contain only letters, numbers and underscores.<br />
* '''take_only_once''': (default yes) {{DevFeature1.13|6}} If set to "no", the object's ID does not prevent it from being taken more than once.<br />
* '''delayed_variable_substitution''' (boolean yes|no, default no): If set to "yes", the wml block contained in this [object] is not variable-substituted at execution time of the event where this [object] is within. You need this for any effect that uses variable substitution or when using [effect][filter] with a $this_unit. {{DevFeature1.13|9}} This is no longer needed when adding ABILITY_TELEPORT, ABILITY_LEADERSHIP or SPECIAL_BACKSTAB.<br />
* '''[effect]''': one or more effect elements may be listed. See [[EffectWML]] for a description of [effect].<br />
* '''duration''':<br />
**if 'scenario', effects only last until the end of the level (note : 'level' is the scenario, so this doesn't mean it last until the unit levels-up).<br />
**if 'forever' or not set, effects never wear off.<br />
** if 'turn', effects only last until the start of the unit's next turn (when the unit refreshes movement and attacks). (Like other start-of-turn behavior, objects with a duration of "turn" won't expire before turn 2.)<br />
** {{DevFeature1.13|1}} if 'turn end' or 'turn_end', effects only last until the end of the unit's next turn (exactly like the slowed status).<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. The first unit found that matches the filter will be given the object. Only on-map units are considered. If no unit matches or no [filter] is supplied, it is tried to apply the object to the unit at the $x1,$y1 location of the event where this [object] is in. The case of no unit being at that spot is handled in the same way as no unit matching a given filter ([else] commands executed, cannot_use_message displayed)<br />
* '''[then]''': a subtag that lets you execute actions if the filter conditions are met. The most common action that should be inside here is a '''[remove_item]''' tag, but you could probably put any tags that otherwise work in a [then] tag.<br />
* '''[else]''': a subtag that lets you execute actions if the filter conditions are *not* met.<br />
* '''silent''': whether or not messages should be suppressed. Default is "no". {{DevFeature1.13|2}} If no description is provided, this defaults to yes, but can still be overridden.<br />
* '''image''': the displayed image of the object.<br />
* '''name''': (translatable) displayed as a caption of the image.<br />
<br />
* '''description''': (translatable) displayed as a message of the image.<br />
* '''cannot_use_message''': (translatable) displayed instead of '''description''' if no unit passes the filter test.<br />
<br />
=== [remove_object] ===<br />
<br />
{{DevFeature1.13|6}}<br />
<br />
Removes an object from matching units.<br />
<br />
* [[StandardUnitFilter]]: All units matching the filter have matching objects removed. Use no [filter] tag.<br />
* '''object_id''': The id of the object to be removed.<br />
<br />
Note that some unit properties are not restored ideally, e.g. current unit's health reversion might not work as expected (max_hitpoints will though).<br />
<br />
=== [remove_shroud] ===<br />
Removes some shroud from the map for a certain side (only relevant for sides that have shroud=yes).<br />
* '''side''': (default=1) the side for which to remove shroud. This can be a comma-separated list of sides. note: Default side=1 for empty side= is deprecated.<br />
* '''[filter_side]''' with a [[StandardSideFilter]] as argument<br />
* [[StandardLocationFilter]]: the range of tiles for which shroud should be removed<br />
<br />
=== [place_shroud] ===<br />
Places some shroud on the map for a certain side (only relevant for sides that have shroud=yes).<br />
* '''side''': (default=1) the side for which to place shroud. This can be a comma-separated list. note: Default side=1 for empty side= is deprecated.<br />
* '''[filter_side]''' with a [[StandardSideFilter]] as argument<br />
* [[StandardLocationFilter]]: the range of tiles on which shroud should be placed<br />
<br />
=== [lift_fog] ===<br />
Lifts the fog of war from parts of the map for a certain side (only relevant for sides that have fog=yes), allowing a player to witness what occurs there even if that player has no units within vision range.<br />
* '''[filter_side]''' with a [[StandardSideFilter]] indicating which sides should be affected.<br />
* [[StandardLocationFilter]]: the tiles from which fog should be lifted.<br />
* '''multiturn''': ''yes/no, default:no''. The default (not multiturn) causes fog to be removed in the same way that normal vision works; the cleared tiles will remain cleared until fog is recalculated (which normally happens when a side ends its turn). When multiturn is set to "yes", the cleared tiles remain clear until {{tag||reset_fog}} cancels the clearing. This allows tiles to remain clear for multiple turns, or to be refogged before the end of the current turn (without also refogging all tiles). Multiturn lifted fog is not shared with allies (even when share_view=yes).<br />
<br />
=== [reset_fog] ===<br />
The primary use of this tag is to remove multiturn lifted fog (created by {{tag||lift_fog}}), which causes the fog to reset to what it would have been had WML not interfered. (That is, hexes that a side's units could not see at any point this turn will be re-fogged, while seen hexes remain defogged.)<br />
* '''[filter_side]''' with a [[StandardSideFilter]] indicating which sides should be affected.<br />
* [[StandardLocationFilter]]: the fog reset will be restricted to these tiles.<br />
* '''reset_view''': ''yes/no, default: no'' If set to "yes", then in addition to removing multiturn fog, the side's current view is canceled (independent of the SLF). This means that all hexes will become fogged for the side unless multiturn fog exists outside the tiles selected by the SLF. Normally, one would want the currently seen hexes to become clear of fog; this is done automatically at the end of many events, and it can be done manually with {{tag|InterfaceActionsWML|redraw}}.<br />
Omitting both the SSF and the SLF would cancel all earlier uses of [lift_fog].<br />
Additionally setting reset_view="yes" would cause the side's entire map to be fogged (unless an ally keeps hexes clear by sharing its view).<br />
<br />
=== [allow_undo] ===<br />
Normally when an event with a handler fires, the player's undo stack is cleared, preventing all actions performed so far from being undone. Including this tag in the event handler prevents the stack from being cleared for this reason, allowing the player to undo actions. (However, the stack might still be cleared for other reasons, such as fog being cleared or combat occurring.) In the common cases, this means '''[allow_undo]''' allows the current action to be undone even though an event was handled. There is a less common case, though &mdash; specifically when handling a menu item, where there is no current action &mdash; and in this case, '''[allow_undo]''' means merely that earlier actions can still be undone.<br />
* Using this tag in a menu item has an additional side effect in 1.11. Starting with version 1.11.1, executing a WML menu item normally counts as doing something as far as the "you have not started your turn yet" dialog is concerned. However, a menu item whose handler includes '''[allow_undo]''' will not count.<br />
<br />
The types of actions that can be undone are movement, recalling, and dismissing a unit from the recall list. If an action is undone, only the position (or existence) of the involved unit will be restored; any altered variables or changes to the game will remain changed after the action is undone. It is up to the scenario designer to avoid abusing this command.<br />
* Technically, if '''[allow_undo]''' is inside an '''[event]''' with ''first_time_only=yes'' (the default setting), and the user undoes the event, then the state of the game has changed in this way: the event will not fire a second time, even though the user undid the action the first time.<br />
* Although recalling can be undone, recruitment can not be undone; this seems to apply even when the recruit's traits are not randomly-generated (tested on 1.12.6 and 1.14.4+dev).<br />
<br />
If an '''[event]''' uses both '''[allow_undo]''' and [[InternalActionsWML#.5Bfire_event.5D|'''[fire_event]''']] then the '''[allow_undo]''' must be after the '''[fire_event]'''.<br />
<br />
Due to a bug in 1.12 (https://gna.org/bugs/?23323) '''[allow_undo]''' should not be used in events that use one of the following things because it might cause OOS: <br />
* [message] with [option]s<br />
* [get_global_variable]<br />
* wesnoth.synchronize_choice<br />
<br />
While in 1.13 using '''[allow_undo]''' together with those things won't give you a guaranteed OOS, there are some non-obvious situations where it will, for example assume the following event:<br />
<br />
[event]<br />
name="moveto"<br />
[message]<br />
message = "message"<br />
[option]<br />
label = "option 1"<br />
[command]<br />
[/command]<br />
[/option]<br />
[option]<br />
label = "option 2"<br />
[command]<br />
[/command]<br />
[/option]<br />
[/message]<br />
[allow_undo]<br />
[/allow_undo]<br />
[/event]<br />
<br />
It will cause OOS when the message is undone: since the event is already executed (erased) on one client only , the clients will disagree about how many choices happen during the next moveto action.<br />
<br />
=== [on_undo] ===<br />
{{DevFeature1.13|2}}<br />
Contains commands to execute when the player undoes the action which triggered the parent event.<br />
*'''delayed_variable_substitution''' {{DevFeature1.13|5}}: ''yes/no, default no (always no before 1.13.5)'' As in [[EventWML]], specifies whether to perform variable substitution when the parent event is run, or when the contents are run. If delayed substitution is used, [[SyntaxWML#Automatically_Stored_Variables|automatically stored variables]] from the parent event context are available, but may occasionally have unexpected values. (In particular, $unit.x and $unit.y may not have the expected value when undoing a move event, though $x1 and $y1 should be correct.)<br />
<br />
Note:<br />
It is not clear where whether the actionwml in [on_undo] in exceuted before or after the action is undone. Also, specially for enter/leave_hex events the units position when executing the [on_undo] code is usually different than when executing the original event. The reccomended way to wokr around these issues is to refer to the unit by is instead of position and store all other needed information variables as 'upvalues'. You can also move the actual undo code to an external event. For example<br />
[event]<br />
name="undo_blah"<br />
first_time_only=no<br />
[store_unit]<br />
id="$moved_unit_id"<br />
[/store_unit]<br />
... do undo stuff stuff<br />
[/event]<br />
<br />
...<br />
... in some other event<br />
[on_undo]<br />
# store ''upvalues<br />
{VARIABLE moved_unit_id $unit.id}<br />
# call actual undo handler<br />
[fire_event]<br />
name = "undo_blah"<br />
[/fire_event]<br />
[on_undo]<br />
<br />
=== [on_redo] ===<br />
{{DevFeature1.13|2}}<br />
Same as [on_undo], except executes the commands on redo. Note that the parent event is not triggered again on a redo.<br />
<br />
{{DevFeature1.13|8}} [on_redo] is deprecated and has no effect anymore.<br />
<br />
Note that [on_redo] is not guaranteed to be called when redoing an action, the engine might also decide to just fire the original events again.<br />
<br />
=== [cancel_action] ===<br />
Although Wesnoth 1.12 does not have this tag, it is the default behavior of {{tag|EventWML|enter_hex}}/{{tag|EventWML|leave_hex}} events in that version.<br />
<br />
{{DevFeature1.13|9}} In this version, [cancel_action] is recognised, but has no effect (a bug).<br />
<br />
{{DevFeature1.13|11}}<br />
In an {{tag|EventWML|enter_hex}}/{{tag|EventWML|leave_hex}} event, interrupt the movement, leaving the unit where it is. This is intended to be used with an event that gives the player new information, to let the player choose whether to change their plans. For example, if the player has commanded a unit to move from (1,1) to (3,3) and attack a unit on (4,4); then a [cancel_action] inside an [enter_hex] event on (2,2) would make the unit stop on (2,2). A [cancel_action] inside an [enter_hex] on (3,3) would let the player choose whether to attack.<br />
<br />
=== [heal_unit] ===<br />
Heal a unit. The variable '''$heal_amount''' will be set to the exact number of points healed (i.e can be less than the parameter '''amount''' if the unit is fully healed). $heal_amount contains only the number of hitpoints the first unit that was found got healed.<br />
* '''[filter]''': [[StandardUnitFilter]] All matching on-map units are healed. If no filter is supplied, it is tried to take the unit at $x1, $y1.<br />
* '''[filter_second]''': [[StandardUnitFilter]] all the units matching the filter ''and'' having the ''heals'' ability will have their animation played (if ''animate'' is set to yes) for each of the units healed.<br />
* '''amount''': (integer, default full) the maximum points the unit(s) will be healed. Can't set below 1 or above max_hitpoints. If "full", sets hitpoints to max_hitpoints. Before 1.9 the default is 0.<br />
* '''animate''': a boolean which indicate if the healing animations must be played. (default no)<br />
* '''moves''': (integer, default 0) The maximum current movement points the units will be "healed". Can't set below 0 or above max_moves. If "full", sets moves to max_moves.<br />
* '''restore_attacks''': (boolean, default no) Whether the units' attacks_left should be reset to their max_attacks (usually 1).<br />
* '''restore_statuses''': (boolean, default yes) Whether standard statuses should be reset to "no". This affects poisoned, slowed, petrified and unhealable. Before 1.9 this is always "no".<br />
<br />
=== [harm_unit] ===<br />
Harms every unit matching the filter, for the specific damage amount.<br />
* '''[filter]''': [[StandardUnitFilter]] all matching units will be harmed (required).<br />
* '''[filter_second]''': [[StandardUnitFilter]] if present, the first matching unit will attack all the units matching the filter above.<br />
* '''amount''': the amount of damage that will be done (required).<br />
* '''alignment''': (default neutral) applies an alignment to the damage, this means that if alignment=chaotic, the damage will be increased at night and reduced at day.<br />
* '''damage_type''': if present, amount will be altered by unit resistance to the damage type specified.<br />
* '''kill''': (default yes) if yes, when a harmed unit goes to or below 0 HP, it is killed; if no its HP are set to 1.<br />
* '''fire_event''': (default no) if yes, when a unit is killed by harming, the corresponding events are fired. If yes, also the corresponding advance and post advance events are fired.<br />
* '''animate''': (default no) if yes, scrolls to each unit before harming it and plays its defense (or attack, if it's the harmer) and death animations. Special values supported, other than the usual yes and no, are "attacker", that means only the harmer will be animated, and "defender", that means only the harmed units will be animated. If the supplied value is yes, attacker or defender also advancement animations are played.<br />
* '''[primary_attack], [secondary_attack]''': these set the weapon against which the harmed units will defend, and that the harming unit will use to attack, respectively (notice this is the opposite of '''[filter]''' and '''[filter_second]''' above). This allows for playing specific defense and attack animations. Both tags are expected to contain a [[FilterWML#Filtering_Weapons|Standard Weapon Filter]].<br />
* '''delay''': if animate=yes, sets the delay (in milliseconds, default 500) between each unit harming.<br />
* '''variable''': if present, the damage caused to the unit, altered by resistances, will be stored in a WML array with the given name, under the "harm_amount" key.<br />
* '''poisoned, slowed, petrified, unhealable''': (default no) if yes, every harmed unit that doesn't already have such status will have it set.<br />
* '''experience''': if yes, and there is a harmer, experience will be attributed like in regular combat.<br />
* '''resistance_multiplier''': the harmed unit's resistance is multiplied by the supplied value; this means that a value lower than 1 increases it, and a value greater than 1 decreases it. Default value is 1, that means no modification.<br />
<br />
=== [time_area] ===<br />
How a day should progress in a given area. Everywhere not specified in a [time_area] tag is affected by the [time] tags in the [scenario] tag.<br />
* [[StandardLocationFilter]]: the locations to affect. ''note: only for [event][time_area]s - at scenario toplevel [time_area] does not support [[StandardLocationFilter]], only location ranges''<br />
* '''[time]''': one or more tags describing the new schedule, see [[TimeWML]].<br />
* '''id''': an unique identifier assigned to a time_area. Optional, unless you want to remove the time_area later. Can be a comma-separated list when removing time_areas, see below.<br />
* '''remove''': (boolean) yes/no value. Indicates whether the specified time_area should be removed. Requires an identifier. If no identifier is used, however, all time_areas are removed.<br />
* '''current_time''': The time slot number (starting with zero) active at the creation of the area.<br />
<br />
''Example:'' (caves in parts of a map)<br />
[time_area]<br />
x=1-2,4-5<br />
y=1-2,1-2<br />
{UNDERGROUND}<br />
[/time_area]<br />
<br />
=== [remove_time_area] ===<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
This is a syntactic shortcut for [time_area] remove=.<br />
* '''id''': Comma-separated list of time area ids to remove.<br />
<br />
=== [end_turn] ===<br />
End the current side's turn. The current event is finished before the turn is ended. Also, if the current event (where the tag appears) has been fired by another event, that event (and the complete stack of other possible parent events) is ended before [end_turn] comes into affect. Also, events following the event stack that fired [end_turn] are not omitted (e.g. [end_turn] is used by a side turn event and a turn refresh event does something afterwards).<br />
<br />
=== [replace_map] ===<br />
<br />
Replaces the entire map.<br />
* '''map''': Content of a wesnoth map file. example:<br />
map="{campaigns/Heir_To_The_Throne/maps/01_The_Elves_Besieged.map}"<br />
* '''map_file''': {{DevFeature1.13|?}} Path to a Wesnoth map file; can be used instead of '''map'''. The file will be loaded when the tag is executed, rather than being embedded wholesale in the preprocessed WML.<br />
* '''expand''': if 'yes', allows the map size to increase. The expansion direction is currently always bottom-right.<br />
* '''shrink''': if 'yes', allows the map size to decrease. If the map size is reduced, any units that would no longer be on the map due to its coordinates no longer existing will be put into the recall list.<br />
Note: When a hex changes from a village terrain to a non-village terrain, and a team owned that village it loses that village. When a hex changes from a non-village terrain to a village terrain and there is a unit on that hex it does not automatically capture the village. The reason for not capturing villages it that there are too many choices to make; should a unit lose its movement points, should capture events be fired. It is easier to do this as wanted by the author in WML.<br />
<br />
=== [replace_schedule] ===<br />
Replace the time of day schedule of the entire scenario.<br />
* [[TimeWML]]: the new schedule.<br />
* '''current_time''': The time slot number (starting with zero) active at schedule replacement.<br />
<br />
=== [tunnel] ===<br />
<br />
Create a tunnel between some locations, later usable by units to move from source hex to target hex (using the movement cost of unit on the target terrain).<br />
<br />
'''Behavior Change as of Wesnoth 1.13.6:''' Vision is now possible (and enabled by default) through tunnels and allied units on the exit hex do not block a tunnel by default any more. This is done in order for moves through tunnels to be consistent with other moves. The previous behavior can still be accomplished by using the new optional keys listed below.<br />
<br />
* '''[filter]''': (required) [[StandardUnitFilter]] the units which can use the tunnel. Leave empty for "all units".<br />
* '''[source]''': (required) [[StandardLocationFilter]] the source hex(es).<br />
* '''[target]''': (required) [[StandardLocationFilter]] the target hex(es).<br />
* '''id''': (optional) identifier for the tunnel, to allow removing.<br />
* '''remove''': (boolean, default: no) If yes, removes all defined tunnels with the same ID (then only id= is necessary).<br />
* '''bidirectional''': (boolean, default: yes) If yes, creates also a tunnel in the other direction. <br />
* '''always_visible''': (boolean, default: no) If yes, the possible movement of enemies under fog can be seen.<br />
* '''allow_vision''': (boolean, default: yes) {{DevFeature1.13|6}} If no, vision through a tunnel is not possible. Note that in that case the tunnel cannot be used if the tunnel exit is under shroud (which previously was ''always'' the case).<br />
* '''pass_allied_units''': (boolean, default: yes) {{DevFeature1.13|6}} If no, allied (including own) units on the exit hex block a tunnel.<br />
<br />
(Note: The tunnel tag can also be used inside the [[AbilitiesWML|[teleport]]] ability, without remove= and id=).<br />
<br />
=== [do_command] ===<br />
<br />
{{DevFeature1.13|0}}<br />
<br />
Executes a command, specified using the same syntax as a [command] tag in [[ReplayWML]]. Not all [command]'s are valid: only these are accepted<br />
<br />
* [attack]<br />
* [move]<br />
* [recruit]<br />
* [recall]<br />
* [disband]<br />
* [fire_event]<br />
* [lua_ai] {{DevFeature1.13|12}} This has been removed and is replaced with [custom_command]<br />
<br />
The tags corresponding to player actions generally use the same codepath as if a player had ordered it. That means for example that only moves that player would be allowed to do are possible, and movement is interrupted when sighting enemy unit.<br />
<br />
One purpose of this tag is to allow scripting of noninteractive scenarios -- without a tag like this, this might require elaborate mechanisms to coerce ais in order to test these code paths.<br />
<br />
This command should always be replay safe.<br />
<br />
=== [put_to_recall_list] ===<br />
<br />
{{DevFeature1.13|0}}<br />
<br />
Puts a unit to the recall list of its side.<br />
* '''[[StandardUnitFilter]]''': the unit(s) to get put to the recall list.<br />
* '''heal''': (default=no) Whether the unit should be refreshed, similar to the unit moving to the recall list at the end of a scenario.<br />
<br />
<br />
== Useful Macros ==<br />
There are some predefined macros that you find useful for direct actions. You can find a complete list along with a detailed explanation of how they work [http://www.wesnoth.org/macro-reference.xhtml here].<br />
* '''{MOVE_UNIT}''': Moves a unit to another location in the map and the player sees the movement (unlike [teleport])<br />
* '''{FULL_HEAL}''': Brings a unit to full HP<br />
* '''{LOYAL_UNIT}''': Create a loyal unit<br />
* '''{MODIFY_TERRAIN_MASK}''': Modify an area of terrain<br />
<br />
== See Also ==<br />
<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Units&diff=59952LuaWML/Units2018-09-12T19:41:19Z<p>Vasya: fix typo</p>
<hr />
<div>This page describes the [[LuaWML]] functions for handling units.<br />
<br />
A unit is a proxy table with the following fields:<br />
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map. {{DevFeature1.13|11}} These are now read/write under all circumstances, including for on-map units)<br />
* '''loc''': {{DevFeature1.13|11}} shortcut to get/set both x and y at once (read/write). Setting x and y individually would result in two moves, and there's the possibility that the intermediate move fails if the hex is occupied by another unit. In general, note that moving a unit by changing the proxy unit's coordinates does not work if the goal hex is occupied (it is not executed), so it is necessary to check if the hex is available first.<br />
* '''side''': integer (read/write)<br />
* '''id''': string (read only)<br />
* '''type''': string (read only)<br />
* '''name''': translatable string (read only)<br />
* '''cost''' {{DevFeature1.13|10}}: integer (read)<br />
* '''max_hitpoints''', '''max_experience''', '''max_moves''': integers (read only)<br />
* '''max_attacks''': integer (read only)<br />
* '''attacks_left''': integer (read/write) Setting below 0 is limited to 0.<br />
* '''extra_recruit''': table (read/write)<br />
* '''advances_to''': table (read/write)<br />
* '''hitpoints''', '''experience''': integer (read/write)<br />
* '''moves''': integer (read/write)<br />
* '''level''': {{DevFeature1.13|5}} integer (read/write)<br />
* '''resting''': boolean (read/write)<br />
* '''hidden''': boolean (read/write)<br />
* '''petrified''', '''canrecruit''': booleans (read only)<br />
* '''role''', '''facing''': strings (read/write)<br />
* '''status''': proxy associative table (read only, read/write fields), provides fields like [[SingleUnitWML#Unit_State|poisoned, slowed, petrified, uncovered, guardian, unhealable, invulnerable]]<br />
* '''image_mods''': string (read only)<br />
* '''upkeep''' {{DevFeature1.13|5}}: one of 'loyal', 'full' or a number (read/writre)<br />
* '''variables''': proxy associative table (read only, read/write fields, including ''variables.__cfg''), only toplevel named fields are proxied. {{DevFeature1.13|2}} subcontainers can be accessed by using the usual variable syntax: <syntaxhighlight inline lang='lua'>unit.variables["a.b.c[6].d"]</syntaxhighlight><br />
* '''attacks''': {{DevFeature1.13|0}}an object to access the units attacks, you can use the attacks index or the attacks name to index an attack. every attack has the following members:<br />
** '''description''': translatable string (read/write)<br />
** '''name''': string (read)<br />
** '''type''': string (read/write)<br />
** '''range''': string (read/write)<br />
** '''damage''': number(read/write)<br />
** '''number''': number(read/write)<br />
** '''movement_used''': number(read/write)<br />
** '''attack_weight''': number(read/write)<br />
** '''defense_weight''': number(read/write)<br />
** '''specials''' wml table(read/write)<br />
* '''valid''': string or nil (read only)<br />
* '''advancements''': {{DevFeature1.13|2}} an array of wml tables (read/write)<br />
* '''__cfg''': WML table (dump) ([[SingleUnitWML]])<br />
* {{DevFeature1.13|2}} The following fields are unit methods synonymous to one of the functions described on this page:<br />
** '''[[#wesnoth.match_unit|matches]]'''<br />
** '''[[#wesnoth.put_recall_unit|to_recall]]'''<br />
** '''[[#wesnoth.put_unit|to_map]]'''<br />
** '''[[#wesnoth.erase_unit|erase]]'''<br />
** '''[[#wesnoth.copy_unit|clone]]'''<br />
** '''[[#wesnoth.extract_unit|extract]]'''<br />
** '''[[#wesnoth.advance_unit|advance]]'''<br />
** '''[[#wesnoth.add_modification|add_modification]]'''<br />
** '''[[#wesnoth.remove_modifications|remove_modifications]]'''<br />
** '''[[#wesnoth.unit_resistance|resistance]]'''<br />
** '''[[#wesnoth.unit_defense|defense]]'''<br />
** '''[[#wesnoth.unit_movement_cost|movement]]'''<br />
** '''[[#wesnoth.unit_vision_cost|vision]]'''<br />
** '''[[#wesnoth.unit_jamming_cost|jamming]]'''<br />
** '''[[#wesnoth.unit_ability|ability]]'''<br />
** '''[[#wesnoth.transform_unit|transform]]'''<br />
The metatable of these proxy tables appears as '''"unit"'''.<br />
<br />
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same "underlying_id" WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''"map"''', '''"recall"''', '''"private"''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.<br />
<br />
The term "proxy", here in particular "proxy unit", means that the variable retrieved in the lua code (with get_units for example) is an accessor (reference) to the C++ object which represents that unit. This is very different from unit variables obtained by [store_unit] in wml. The fields marked as "writable" above can be modified without the need to use put_unit afterwards. This same reason explains that modifications to the unit from outside the lua code (like [kill] invalidating the proxy unit) have immediate effect on the lua code's proxy unit variable (with the exception of private proxy units).<br />
<br />
<br />
==== wesnoth.get_units ====<br />
<br />
* '''wesnoth.get_units(''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_units(''filter'', ''fake_location'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_units(''filter'', ''other_unit'')'''<br />
<br />
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters. If a second unit is passed, it can be referenced via the $other_unit variable in the main filter as well as via the "other" variable in WFL formulas used in the main filter. If a location is passed, the filter is run as if the unit were at that location (rather than its real location). This affects things such as [filter_adjacent] and ability_active, and should work even for a unit on the recall list.<br />
<br />
<syntaxhighlight lang='lua'><br />
local leaders_on_side_two = wesnoth.get_units { side = 2, canrecruit = true }<br />
local name_of_leader = leaders_on_side_two[1].name<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_unit ====<br />
<br />
* '''wesnoth.get_unit(''x'', ''y'')'''<br />
* '''wesnoth.get_unit(''underlying_id'')'''<br />
<br />
Returns the unit at the given location or with the given underlying ID.<br />
<br />
<syntaxhighlight lang='lua'><br />
local args = ...<br />
local unit = wesnoth.get_unit(args.x1, args.y1)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.match_unit ====<br />
<br />
* '''wesnoth.match_unit(''unit'', ''filter'')'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''other_unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''other_unit''])'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''location'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''location''])'''<br />
<br />
Returns true if the given unit matches the WML filter passed as the second argument. If ''other_unit'' is specified, it is used for the ''$other_unit'' auto-stored variable in the filter. Otherwise, this variable is not stored for the filter. If an extra ''location'' is specified, the filter matches as if the unit were at that location.<br />
<br />
<syntaxhighlight lang='lua'><br />
assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.put_unit ====<br />
<br />
* '''wesnoth.put_unit(''unit'')'''<br />
* '''wesnoth.put_unit(''x'', ''y'', ''unit'')'''<br />
* '''wesnoth.put_unit(''x'', ''y'')'''<br />
* {{DevFeature1.13|2}} '''wesnoth.put_unit(''unit'', ''x'', ''y'')''' -- The above two forms are also deprecated.<br />
* {{DevFeature1.13|2}} '''''unit'':to_map([''x'', ''y''])<br />
<br />
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead. {{DevFeature1.13|2}} This use is now deprecated; use wesnoth.erase_unit instead.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- create a unit with random traits, then erase it<br />
wesnoth.put_unit(17, 42, { type = "Elvish Lady" })<br />
wesnoth.put_unit(17, 42)<br />
</syntaxhighlight><br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- move the leader back to the top-left corner<br />
wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])<br />
</syntaxhighlight><br />
<br />
==== wesnoth.erase_unit ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
* '''wesnoth.erase_unit(''unit'')'''<br />
* '''wesnoth.erase_unit(''x'', ''y'')'''<br />
* '''''unit'':erase()'''<br />
<br />
Erases a unit from the map. After calling this on a unit, the unit is no longer valid.<br />
<br />
==== wesnoth.get_recall_units ====<br />
<br />
* '''wesnoth.get_recall_units()'''<br />
<br />
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.<br />
<br />
==== wesnoth.put_recall_unit ====<br />
<br />
* '''wesnoth.put_recall_unit(''unit'', [''side''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':to_recall([''side''])'''<br />
<br />
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- put the unit at location 17,42 on the recall list for side 2<br />
wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)<br />
</syntaxhighlight><br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.<br />
<br />
==== wesnoth.create_unit ====<br />
<br />
* '''wesnoth.create_unit(''unit_info'')'''<br />
<br />
Creates a private unit from a WML table.<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.create_unit { type = "White Mage", gender = "female" }<br />
</syntaxhighlight><br />
<br />
==== wesnoth.copy_unit ====<br />
<br />
* '''wesnoth.copy_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':clone()'''<br />
<br />
Creates a private unit from another unit.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- extract a unit from the map<br />
local u = wesnoth.copy_unit(wesnoth.get_units({ type = "Thug" })[1])<br />
wesnoth.erase_unit(u.x, u.y)<br />
-- u is still valid at this point<br />
</syntaxhighlight><br />
<br />
==== wesnoth.extract_unit ====<br />
<br />
* '''wesnoth.extract_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':extract()'''<br />
<br />
Removes a unit from the map or from a recall list and makes it private.<br />
<br />
<syntaxhighlight lang='lua'><br />
-- remove all the units from the recall list of side 1 and put them in a WML container<br />
local l = {}<br />
for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do<br />
wesnoth.extract_unit(u)<br />
table.insert(l, u.__cfg)<br />
end<br />
helper.set_variable_array("player_recall_list", l)<br />
</syntaxhighlight><br />
<br />
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.<br />
<br />
<br />
==== wesnoth.advance_unit ====<br />
<br />
* '''wesnoth.advance_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':advance()'''<br />
<br />
{{DevFeature1.13|0}} Advances the unit (and shows the advance unit dialog if needed) if the unit has enough xp. This function should be called after modifying the units experience directly. A similar function is called by wesnoth internally after unit combat. The second argument is a boodean value that specifies whether the advancement should be animated. The third agrument is a boodean value that specifies whether advancement related events should be fired.<br />
<br />
<br />
This function only works for units on the map.<br />
<br />
This function can also trigger multiple advancements if the unit has enough xp.<br />
<br />
==== wesnoth.add_modification ====<br />
<br />
* '''wesnoth.add_modification(''unit'', ''type'', ''effects'', [''write_to_mods''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':add_modification(''type'', ''effects'', [''write_to_mods''])'''<br />
<br />
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (one of "trait", "object", or "advance"). The option "advance" applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.<br />
<br />
{{DevFeature1.13|2}} In 1.13.2 and later, the "advance" type is replaced with "advancement", to match the equivalent tag in [[UnitTypeWML|[unit_type]]]. Also, it takes a fourth argument which, if false, causes it to not write the modification tag to the unit's [modifications] (as would be done with an [object] with no_write=true).<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
wesnoth.add_modification(u, "object", { { "effect", { apply_to = "image_mod", replace = "RC(red>blue)" } } })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.remove_modifications ====<br />
<br />
* {{DevFeature1.13|?}} '''wesnoth.remove_modifications(''unit'', ''cfg'' [, ''type''])'''<br />
* {{DevFeature1.13|?}} '''''unit'':remove_modifications(''cfg'' [, ''type''])'''<br />
<br />
Modifies a given unit. The unit needs to be a proxy unit. The second argument is a filter for the modifications to remove. It takes the same syntax as [[FilterWML#Filtering_on_WML_data|[filter_wml]]]; all matching modifications will be removed. The third argument is the type (tag name) of the modifications to search for; it defaults to <tt>"object"</tt>, but you can also pass <tt>"trait"</tt> or <tt>"advancement"</tt>.<br />
<br />
<syntaxhighlight lang='lua'><br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
wesnoth.remove_modifications(u, { id = your_object_id })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_resistance ====<br />
<br />
* '''wesnoth.unit_resistance(''unit'', ''damage_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':resistance(''damage_type'')'''<br />
<br />
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).<br />
<br />
<syntaxhighlight lang='lua'><br />
local fire_resistance = 100 - wesnoth.unit_resistance(u, "fire")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_defense ====<br />
<br />
* '''wesnoth.unit_defense(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':defense(''terrain_code'')'''<br />
<br />
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)<br />
<br />
<syntaxhighlight lang='lua'><br />
local flat_defense = 100 - wesnoth.unit_defense(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_movement_cost ====<br />
<br />
* '''wesnoth.unit_movement_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':movement(''terrain_code'')'''<br />
<br />
Returns the movement cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local move_cost = wesnoth.unit_movement_cost(u, "Gt")<br />
<syntaxhighlight><br />
<br />
==== wesnoth.unit_vision_cost ====<br />
<br />
* '''wesnoth.unit_vision_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':vision(''terrain_code'')'''<br />
<br />
Returns the vision cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local see_cost = wesnoth.unit_vision_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_jamming_cost ====<br />
<br />
* '''wesnoth.unit_jamming_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':jamming(''terrain_code'')'''<br />
<br />
Returns the jamming cost of a unit on a particular terrain.<br />
<br />
<syntaxhighlight lang='lua'><br />
local jam_cost = wesnoth.unit_jamming_cost(u, "Gt")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_ability ====<br />
<br />
* '''wesnoth.unit_ability(''unit'', ''ability_tag'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':ability(''ability_tag'')'''<br />
<br />
Returns true if the unit is currently under effect by an ability with this given TAG NAME. This means that the ability could be owned by the unit itself, or by an adjacent unit.<br />
<br />
<syntaxhighlight lang='lua'><br />
function has_teleport(u)<br />
return wesnoth.unit_ability(u, "teleport")<br />
end<br />
</syntaxhighlight><br />
<br />
==== wesnoth.unit_types ====<br />
<br />
This is not a function but a read-only table indexed by unit type ids. Its elements are proxy tables with these fields:<br />
<br />
* '''id''': string<br />
* '''name''': translatable string (read only)<br />
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)<br />
* '''abilities''': array of ability keys (strings), e.g. {"curing", "regenerates"}<br />
* {{DevFeature1.13|11}} '''advances_to''': array of unit types to which unit can advance<br />
* {{DevFeature1.13|11}} '''advances_from''': array of unit types from which unit can advance. Note: this is OOS-unsafe in Multiplayer games. Different clients may have additional Era-s with units upgradable to this unit type.<br />
* '''__cfg''': WML table (dump), see [[UnitTypeWML]]<br />
<br />
The metatable of these proxy tables appears as '''"unit type"'''.<br />
<br />
<syntaxhighlight lang='lua'><br />
local lich_cost = wesnoth.unit_types["Ancient Lich"].cost<br />
</syntaxhighlight><br />
<br />
Note that different clients have different set of available units in a Multiplayer game. It is OOS-unsafe to e.g. count the number of units.<br />
Presuming correctly written add-ons, it is still safe to e.g. access any given unit or its properties.<br />
<br />
==== wesnoth.races ====<br />
<br />
This is not a function but a table indexed by race ids. Its elements are proxy tables for all races the engine knows about.<br />
known fields of each element:<br />
* '''id''': string<br />
* '''description''', '''name''', '''plural_name''' (translatable strings)<br />
* '''num_traits''' (integer)<br />
* '''ignore_global_traits''' (boolean)<br />
* '''undead_variation''' (string)<br />
(all read only)<br />
* '''__cfg''': WML table (dump)<br />
<br />
<syntaxhighlight lang='lua'><br />
wesnoth.message(tostring(wesnoth.races["lizard"].name))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_traits ====<br />
<br />
* '''wesnoth.get_traits()'''<br />
<br />
Returns a table with named fields (trait id strings) holding the wml tables defining the traits. arguments: none. All global traits the engine knows about, race-specific traits are not included.<br />
Known fields and subtags of each element are the ones which were given in the wml definition of the [[SingleUnitWML|trait]].<br />
wesnoth.message(tostring(wesnoth.get_traits().strong.male_name))<br />
<br />
==== wesnoth.simulate_combat ====<br />
<br />
* '''wesnoth.simulate_combat(''attacker'', [''attacker_weapon_index''], ''defender'', [''defender_weapon_index''])'''<br />
<br />
Computes the hitpoint distribution and status chance after a combat between two units. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.<br />
<br />
Optional integers can be passed after each unit to select a particular weapon, otherwise the "best" one is selected. When giving the weapon, the parameter is the weapon number (integer, starting at 1) and not an element from the table returned by helper.child_range(att, "attack").<br />
<br />
<syntaxhighlight lang='lua'><br />
local function display_stats(n, t)<br />
wesnoth.message(string.format(<br />
"Chance for the %s\n to be slowed: %f,\n to be poisoned: %f,\n to die: %f.\nAverage HP: %f.",<br />
n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))<br />
end<br />
local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def, def_weapon)<br />
display_stats("attacker", att_stats)<br />
display_stats("defender", def_stats)<br />
</syntaxhighlight><br />
<br />
Returns 2 additional tables which contain information about the weapons and the effect of single hits with these keys: num_blows, damage, chance_to_hit, poisons, slows, petrifies, plagues, plague_type, backstabs, rounds, firststrike, drains, drain_constant, drain_percent, attack_num, name. <br />
Name is the wml name not the description. If there is no weapon, then name will be nil<br />
<br />
<syntaxhighlight lang='lua'><br />
local att_stats, def_stats, att_weapon, def_weapon = wesnoth.simulate_combat(attacker, att_weapon_number, defender)<br />
wesnoth.message(string.format(<br />
"The attack %s should be countered with %s, which does %d damage, has %d%% chance to hit and forces %d attack rounds due to its berserk ability.",<br />
att_weapon.name, def_weapon.name or "no weapon", def_weapon.damage, def_weapon.chance_to_hit, def_weapon.rounds))<br />
</syntaxhighlight><br />
<br />
==== wesnoth.transform_unit ====<br />
<br />
* '''wesnoth.transform_unit(''unit'', ''to_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':transform(''to_type'')'''<br />
<br />
Changes the type of a unit and adjust attributes accordingly. Note that hit points are only changed if necessary to accommodate the new maximum hit points. Poison is automatically removed if the transformed unit is immune.<br />
<br />
<syntaxhighlight lang='lua'><br />
local ev = wesnoth.current.event_context<br />
local u = wesnoth.get_units{x=ev.x1, y=ev.y1}[1]<br />
wesnoth.transform_unit(u, "Spearman")<br />
-- If a full heal is desired:<br />
u.hitpoints = u.max_hitpoints<br />
u.status.poisoned = false<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_known_unit ====<br />
<br />
* {{DevFeature1.13|10}} '''wesnoth.add_known_unit(''unit_type_id'')'''<br />
<br />
adds the unit type with the given id to the list of known units (so that they appear in the help)<br />
<br />
==== wesnoth.create_animator ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.create_animator()'''<br />
<br />
Returns an object that can be used to set up and run an animation. The object has three methods:<br />
<br />
* '''animator:run()'''<br />
<br />
Runs the animation. {{DevFeature1.15|0}} Implicitly clears the animator.<br />
<br />
* '''animator:clear()'''<br />
<br />
Clears any units previously added to the animation.<br />
<br />
* '''animator:add(''unit'', ''flag'', ''hits'', ''params'')'''<br />
<br />
Adds a unit to the animation. The ''flag'' specifies which animation to play, and the ''hits'' parameter is required for attack animations to specify which variant of the animation to play. Possibly keys in ''params'' are:<br />
<br />
* '''facing''': A location. The animation will be played with the unit facing that location.<br />
* '''value''': Either a number or a list of two numbers. Use this to pass ''value'' and/or ''value_second'' to default animations that use them.<br />
* '''with_bars''': Whether to show HP bars and such while the animation plays.<br />
* '''text''': Text to float as the animation plays.<br />
* '''color''': Color of the floating text - a list of red, green, blue.<br />
* '''primary''': The primary weapon to use for the animation. Must be a Lua unit attack proxy.<br />
* '''secondary''': The secondary weapon to use for the animation.<br />
<br />
Normal usage would be to create it, call '''add''' one or more times, then call '''run'''.<br />
<br />
==== wesnoth.effects ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
This table contains the implementation of custom [[EffectWML|[effect]]]s. Each value is a function that takes a unit and the effect config. Note that the default effects defined by the Wesnoth engine are not in this table. <br />
<br />
<syntaxhighlight lang='lua'><br />
function wesnoth.effects.min_resistance(u, cfg)<br />
local resistance_new = {}<br />
local resistance_old = helper.parsed(helper.get_child(cfg, "resistance"))<br />
for k,v in pairs(resistance_old) do<br />
if type(k) == "string" and type(v) == "number" and wesnoth.unit_resistance(u, k) >= v then<br />
resistance_new[k] = v<br />
end<br />
end<br />
--important: use wesnoth.add_modification(..., false) so that the function will only execute the effects of that object and not store the object in the unit.<br />
wesnoth.add_modification(u, "object", {<br />
T.effect {<br />
apply_to = "resistance",<br />
replace = true,<br />
T.resistance (resistance_new),<br />
},<br />
}, false)<br />
end<br />
</syntaxhighlight><br />
<br />
The code above adds a new <code>min_resistance</code> effect that will set the resistances to specific values if they are currently below that value. It can then be used like this (for example, in [[DirectActionsWML#.5Bobject.5D|[object]]]):<br />
<br />
<syntaxhighlight lang='wml'><br />
[effect]<br />
apply_to=min_resistance<br />
[resistance]<br />
cold=50<br />
[/resistance]<br />
[/effect]<br />
</syntaxhighlight><br />
<br />
Note that because currently all Lua code is executed after [unit]s in [side] are created, it is currently not possible to use these effects in [unit]s in [side]<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Built-in effects are now present in the <code>wesnoth.effects</code> table and can be called by custom effects or by other Lua code. They take the same two arguments that a custom effect function does - the unit, and the effect WML.<br />
<br />
In addition, you can now specify description modifiers to be used if a custom effect is placed in a <code>[trait]</code> tag. Instead of setting a function as the effect, you set a table with a <code>__call</code> metafunction which does what the function would have done. The table can then have an additional <code>__descr</code> metafunction which updates descriptions as necessary. The built-in effects all use this structure. This metafunction takes the same arguments as the regular effect function, but should not modify the unit. Instead, it returns a string to be appended to the trait's effect description.<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&diff=59930LuaWML/Tiles2018-08-23T10:15:23Z<p>Vasya: /* wesnoth.map.distance_between */</p>
<hr />
<div>This page describes the [[LuaWML]] functions for handling terrains and tiles. The ''items'' library can be loaded by<br />
<br />
<syntaxhighlight lang=lua><br />
items = wesnoth.require "lua/wml/items.lua"<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_map_size ====<br />
<br />
* '''wesnoth.get_map_size()'''<br />
<br />
Returns the width, the height, and the border size of the map.<br />
<br />
<syntaxhighlight lang=lua><br />
local w,h,b = wesnoth.get_map_size()<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_terrain ====<br />
<br />
* '''wesnoth.get_terrain(''x'', ''y'')'''<br />
<br />
Returns the terrain code for the given location.<br />
<br />
<syntaxhighlight lang=lua><br />
local is_grassland = wesnoth.get_terrain(12, 15) == "Gg"<br />
</syntaxhighlight><br />
<br />
==== wesnoth.set_terrain ====<br />
<br />
* '''wesnoth.set_terrain(''x'', ''y'', ''terrain_code'', [''layer''], [''replace_if_failed''])'''<br />
<br />
Modifies the terrain at the given location.<br />
<br />
<syntaxhighlight lang=lua><br />
function create_village(x, y)<br />
wesnoth.set_terrain(x, y, "Gg^Vh")<br />
end<br />
</syntaxhighlight><br />
<br />
An optional 4th parameter can be passed (layer): overlay, base or both, default both: Change the specified layer only.<br />
<br />
An optional 5th boolean parameter (replace_if_failed) can be passed, see the documentation of the [terrain] tag. To pass the 5th parameter but not the 4th, pass nil for the 4th.<br />
<br />
==== wesnoth.get_terrain_info ====<br />
<br />
* '''wesnoth.get_info(''terrain_code'')'''<br />
<br />
Returns the terrain details for the given terrain code.<br />
<br />
<syntaxhighlight lang=lua><br />
local is_keep = wesnoth.get_terrain_info(wesnoth.get_terrain(12, 15)).keep<br />
</syntaxhighlight><br />
<br />
Terrain info is a plain table with the following fields:<br />
* '''id''': string<br />
* '''name''', '''description''', '''editor_name''': translatable strings<br />
* '''castle''', '''keep''', '''village''': booleans<br />
* '''healing''': integer<br />
<br />
==== wesnoth.get_selected_tile ====<br />
<br />
* '''wesnoth.get_selected_tile()'''<br />
<br />
Returns the two coordinates of the currently selected tile. This is mostly useful for defining command-mode helpers.<br />
<br />
<syntaxhighlight lang=lua><br />
function chg_unit(attr, val)<br />
local x, y = wesnoth.get_selected_tile()<br />
if not x then wesnoth.message("Error", "No unit selected."); return end<br />
helper.modify_unit({ x = x, y = y }, { [attr] = val })<br />
end<br />
-- Function chg_unit can be used in command mode to modify unit attributes on the fly:<br />
-- :lua chg_unit("status.poisoned", true)<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_locations ====<br />
<br />
* '''wesnoth.get_locations(''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.get_locations(''filter'' [, ''reference_unit''])'''<br />
<br />
Returns a table containing all the locations matching the given filter. Locations are stored as pairs: tables of two elements. See [[StandardLocationFilter]] for details about location filters. If a unit is passed, it can be referenced from the filter via the $teleport_unit variable, as well as in WFL formulas used in the filter.<br />
<br />
<syntaxhighlight lang=lua><br />
-- replace all grass terrains by roads<br />
for i,loc in ipairs(wesnoth.get_locations { terrain = "Gg" }) do<br />
wesnoth.set_terrain(loc[1], loc[2], "Rr")<br />
end<br />
</syntaxhighlight><br />
<br />
==== wesnoth.get_villages ====<br />
<br />
* '''wesnoth.get_villages([''filter''])'''<br />
<br />
This function, when called without arguments, returns a table containing all the villages present on the map (as tables of two elements). If it's called with a WML table as argument, a table containing only the villages matching the supplied [[StandardLocationFilter]] is returned.<br />
<br />
<syntaxhighlight lang=lua><br />
-- How many villages do we have on our map?<br />
v = #wesnoth.get_villages()<br />
</syntaxhighlight><br />
<br />
==== wesnoth.match_location ====<br />
<br />
* '''wesnoth.match_location(''x'', ''y'', ''filter'')'''<br />
* {{DevFeature1.13|12}} '''wesnoth.match_location(''x'', ''y'', ''filter'' [, ''reference_unit''])'''<br />
<br />
Returns true if the given location passes the filter. If a unit is passed, it can be referenced from the filter via the $teleport_unit variable, as well as in WFL formulas used in the filter.<br />
<br />
<syntaxhighlight lang=lua><br />
bool b = wesnoth.match_location(x, y, { terrain = "Ww", { "filter_adjacent_location", terrain = "Ds,*^Bw*" } })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_tile_overlay ====<br />
<br />
* '''wesnoth.add_tile_overlay(''x'', ''y'', ''item_wml'')'''<br />
<br />
Places a tile overlay (either an image or a halo) at a given location. The overlay is described by a table supporting the same fields as [[InterfaceActionsWML|[item]]]. Note that the overlay is not kept over save/load cycles.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.add_tile_overlay(17, 42, { image = "items/orcish-flag.png" })<br />
</syntaxhighlight><br />
<br />
==== wesnoth.remove_tile_overlay ====<br />
<br />
* '''wesnoth.remove_tile_overlay(''x'', ''y'', [''filename''])'''<br />
<br />
Removes all the overlays at the given location. If a filename is passed as a third argument, only this overlay (either image or halo) is removed.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.remove_tile_overlay(17, 42, "items/orcish-flag.png")<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_fog ====<br />
<br />
* '''wesnoth.add_fog([''sides''], ''locations'', [''permanent''])'''<br />
<br />
{{DevFeature1.13|5}} Fogs over the specified locations for the specified sides (or all sides, if no sides are specified). You can specify sides either as a single integer or a list of integers. The ''permanent'' argument defaults to false, causing temporary fog overrides to be cleared; if true, it affects the team's permanent fog as well.<br />
<br />
==== wesnoth.remove_fog ====<br />
<br />
* '''wesnoth.remove_fog([''sides''], ''locations'', [''permanent''])'''<br />
<br />
{{DevFeature1.13|5}} Unfogs the specified locations for the specified sides (or all sides, if no sides are specified). You can specify sides either as a single integer or a list of integers. The ''permanent'' argument defaults to false, creating temporary fog overrides that disappear at the end of the turn; if true, it affects the team's permanent fog as well.<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.remove_fog(1, { {5, 5}, {5, 6} }) --removes fog on 5,5 and 5,6 for side 1<br />
wesnoth.remove_fog(wesnoth.sides[1].side, { {5, 5} }) -- removes fog for first side on 5,5<br />
wesnoth.remove_fog(1, wesnoth.get_locations{ x = 5, y = 5 }) --removes fog on 5,5<br />
</syntaxhighlight><br />
<br />
==== wesnoth.add_sound_source ====<br />
<br />
* '''wesnoth.add_sound_source(''cfg'')'''<br />
<br />
{{DevFeature1.13|5}} Adds a sound source. Input parameters are the same as for the [add_sound_source] tag. If a sound source with the same ID already exists, it is replaced.<br />
<br />
==== wesnoth.remove_sound_source ====<br />
<br />
* '''wesnoth.remove_sound_source(''id'')'''<br />
<br />
{{DevFeature1.13|5}} Removes a sound source.<br />
<br />
==== wesnoth.get_sound_source ====<br />
<br />
* '''wesnoth.get_sound_source(''id'')'''<br />
<br />
{{DevFeature1.13|5}} Retrieves the parameters of an existing sound source. The result of this function is suitable for feeding back to add_sound_source. The table returned by this function is a copy of the sound source's parameters, so if you change any of them, you must call add_sound_source to update the source.<br />
<br />
<br />
==== wesnoth.map.get_direction ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.get_direction(''from'', ''dir'', [''count''])'''<br />
<br />
Calculates the hex reached by travelling in the specified direction, which should be a string such as "ne" or "s". The optional third parameter ''count'' is number of steps to travel to specified direction. Negative ''count'' is supported to travel opposite direction.<br />
<br />
==== wesnoth.map.get_relative_dir ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.get_relative_dir(''from'', ''to'')'''<br />
<br />
Calculates the direction from one hex to another. Possible returns are strings "n", "ne", "nw", "s", "se", "sw" or "". The empty string means no direction which happens if ''from'' and ''to'' are same.<br />
<br />
==== wesnoth.map.rotate_right_around_center ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.rotate_right_around_center(''loc'', ''center'', ''angle'')'''<br />
<br />
Calculates the hex obtained from rotating the specified location around the specified center by the specified angle. The angle is an integer in the range 1..6.<br />
<br />
==== wesnoth.map.get_adjacent_tiles ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.get_adjacent_tiles(''loc'')'''<br />
<br />
Return all hexes adjacent to the specified hex, as six separate return values.<br />
<br />
==== wesnoth.map.tiles_adjacent ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.tiles_adjacent(''loc1'', ''loc2'')'''<br />
<br />
Tests if two hexes are adjacent.<br />
<br />
==== wesnoth.map.distance_between ====<br />
{{DevFeature1.13|8}}<br />
<br />
* '''wesnoth.map.distance_between(''loc1'', ''loc2'')'''<br />
<br />
Calculates the distance between two hexes.<br />
<br />
<syntaxhighlight lang=lua><br />
local my_distance = wesnoth.map.distance_between({10, 10}, {20, 20})<br />
</syntaxhighlight><br />
<br />
==== wesnoth.label====<br />
{{DevFeature1.13|0}}<br />
<br />
* '''wesnoth.label(''cfg'')'''<br />
<br />
Sets label of cfg.x, cfg.y to cfg.text. More supported keys https://wiki.wesnoth.org/InterfaceActionsWML#.5Blabel.5D<br />
<br />
<syntaxhighlight lang=lua><br />
wesnoth.label {x=10,y=10,text="a",color={255,255,255,255}}<br />
</syntaxhighlight><br />
<br />
==== wesnoth.special_locations ====<br />
<br />
{{DevFeature1.13|12}}<br />
<br />
This is a table containing all the special locations set in the map data, including side starting locations, indexed by their key. (Side starting locations are indexed by the side number.)<br />
<br />
<syntaxhighlight lang=lua><br />
-- Get the starting position of side 3<br />
local enemy_start = wesnoth.special_locations[3]<br />
-- Get a named location, "spire", from the map data<br />
local destination = wesnoth.special_locations.spire<br />
</syntaxhighlight><br />
<br />
==== items.place_image ====<br />
<br />
* '''items.place_image(''x'', ''y'', ''filename'')'''<br />
<br />
Places an image at a given location and registers it as a WML ''[item]'' would do, so that it can be restored after save/load.<br />
<br />
<syntaxhighlight lang=lua><br />
local items = wesnoth.require "lua/wml/items.lua"<br />
items.place_image(17, 42, "items/orcish-flag.png")<br />
</syntaxhighlight><br />
<br />
==== items.place_halo ====<br />
<br />
* '''items.place_halo(''x'', ''y'', ''filename'')'''<br />
<br />
Behaves the same as [[#items.place_image]] but for halos.<br />
<br />
==== items.remove ====<br />
<br />
* '''items.remove(''x'', ''x'', [''filename''])'''<br />
<br />
Removes an overlay set by [[#items.place_image]] or [[#items.place_halo]]. If no filename is provided, all the overlays on a given tile are removed.<br />
<br />
<syntaxhighlight lang=lua><br />
items.remove(17, 42, "items/orcish-flag.png")<br />
</syntaxhighlight><br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Files&diff=59912LuaWML/Files2018-08-05T08:40:26Z<p>Vasya: /* wesnoth.have_file(file_path, restrict_regular_file) */</p>
<hr />
<div>This page describes the [[LuaWML]] functions for handling Lua files.<br />
<br />
==== wesnoth.dofile ====<br />
<br />
Replaces [http://www.lua.org/manual/5.1/manual.html#5.1 basic.dofile] for loading files. Loads the given filename (relative to the content directory) and executes it in an unprotected environment (that is, exceptions propagate to the caller). Returns the values returned by the executed script.<br />
<br />
wesnoth.dofile "~add-ons/MyCampaign/lua/scenario-utils.lua"<br />
<br />
It may be helpful to put as many Lua code as possible in specific files instead of embedding it into WML files, so as to not confuse text editors. Then a scenario only needs to contain the following event:<br />
<br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = << wesnoth.dofile "~add-ons/MyCampaign/lua/scenario-utils.lua" >><br />
[/lua]<br />
[/event]<br />
<br />
If the same files need to be loaded for all the scenarios, the [lua] tag above can be directly put inside the '''_main.cfg''' file (or equivalent file). The Lua code will then be executed at the start of each scenario.<br />
<br />
{{DevFeature1.13|8}} If you pass additional arguments to dofile, they are forwarded to the script in the "..." variable.<br />
<br />
==== wesnoth.require ====<br />
<br />
Loads the given filename (relative to the content directory) and executes it in a protected environment. If the file has already been executed once, then compilation and execution are skipped and the value from its previous run is returned.<br />
<br />
helper = wesnoth.require "lua/helper.lua"<br />
<br />
This function is helpful in writing libraries of functions that can be accessed from various places. So the return value of the file is supposed to be a table containing the methods provided by the library. Such a library would look like:<br />
<br />
local library = {}<br />
function library.do_something(a) ... end<br />
function library.go_somewhere(x, y) ... end<br />
return library<br />
<br />
It can also be helpful when writing unit types with events, since unit types are not necessarily available at ''preload'' time, hence preventing the usage of [[#wesnoth.dofile]] for precompiling code:<br />
<br />
[unit_type]<br />
id = phoenix<br />
[event]<br />
name = last breath<br />
[lua]<br />
code = << wesnoth.require("~add-ons/MyEra/lua/unit-utils.lua").resurrect(...) >><br />
[/lua]<br />
[/event]<br />
[/unit_type]<br />
<br />
{{DevFeature1.13|8}}The ".lua" file extension is now added for you automatically, as is the "lua/" prefix. Both these substitutions only occur if the file without the substitutions does not exist. Taken together, this means that you can now write:<br />
<br />
wesnoth.require "helper"<br />
wesnoth.require "~add-ons/MyEra/lua/unit-utils"<br />
<br />
==== wesnoth.have_file (file_path, restrict_regular_file) ====<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Tests if a file exists. Files are resolved in the same way as by dofile. {{DevFeature1.13|8}} If you pass true as the second argument, it returns true only if the file is a regular file — otherwise, it returns true if the path is valid, whether it is a file, directory, or some other type of object.<br />
<br />
==== wesnoth.read_file ====<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Reads a file into a string. {{DevFeature1.13|8}} If the path is a directory, this instead returns an array of the directory contents, with directories first, followed by files. The special key ndirs contains the number of directories.<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Files&diff=59911LuaWML/Files2018-08-05T08:39:49Z<p>Vasya: /* wesnoth.have_file */</p>
<hr />
<div>This page describes the [[LuaWML]] functions for handling Lua files.<br />
<br />
==== wesnoth.dofile ====<br />
<br />
Replaces [http://www.lua.org/manual/5.1/manual.html#5.1 basic.dofile] for loading files. Loads the given filename (relative to the content directory) and executes it in an unprotected environment (that is, exceptions propagate to the caller). Returns the values returned by the executed script.<br />
<br />
wesnoth.dofile "~add-ons/MyCampaign/lua/scenario-utils.lua"<br />
<br />
It may be helpful to put as many Lua code as possible in specific files instead of embedding it into WML files, so as to not confuse text editors. Then a scenario only needs to contain the following event:<br />
<br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = << wesnoth.dofile "~add-ons/MyCampaign/lua/scenario-utils.lua" >><br />
[/lua]<br />
[/event]<br />
<br />
If the same files need to be loaded for all the scenarios, the [lua] tag above can be directly put inside the '''_main.cfg''' file (or equivalent file). The Lua code will then be executed at the start of each scenario.<br />
<br />
{{DevFeature1.13|8}} If you pass additional arguments to dofile, they are forwarded to the script in the "..." variable.<br />
<br />
==== wesnoth.require ====<br />
<br />
Loads the given filename (relative to the content directory) and executes it in a protected environment. If the file has already been executed once, then compilation and execution are skipped and the value from its previous run is returned.<br />
<br />
helper = wesnoth.require "lua/helper.lua"<br />
<br />
This function is helpful in writing libraries of functions that can be accessed from various places. So the return value of the file is supposed to be a table containing the methods provided by the library. Such a library would look like:<br />
<br />
local library = {}<br />
function library.do_something(a) ... end<br />
function library.go_somewhere(x, y) ... end<br />
return library<br />
<br />
It can also be helpful when writing unit types with events, since unit types are not necessarily available at ''preload'' time, hence preventing the usage of [[#wesnoth.dofile]] for precompiling code:<br />
<br />
[unit_type]<br />
id = phoenix<br />
[event]<br />
name = last breath<br />
[lua]<br />
code = << wesnoth.require("~add-ons/MyEra/lua/unit-utils.lua").resurrect(...) >><br />
[/lua]<br />
[/event]<br />
[/unit_type]<br />
<br />
{{DevFeature1.13|8}}The ".lua" file extension is now added for you automatically, as is the "lua/" prefix. Both these substitutions only occur if the file without the substitutions does not exist. Taken together, this means that you can now write:<br />
<br />
wesnoth.require "helper"<br />
wesnoth.require "~add-ons/MyEra/lua/unit-utils"<br />
<br />
==== wesnoth.have_file(file_path, restrict_regular_file) ====<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Tests if a file exists. Files are resolved in the same way as by dofile. {{DevFeature1.13|8}} If you pass true as the second argument, it returns true only if the file is a regular file — otherwise, it returns true if the path is valid, whether it is a file, directory, or some other type of object.<br />
<br />
==== wesnoth.read_file ====<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Reads a file into a string. {{DevFeature1.13|8}} If the path is a directory, this instead returns an array of the directory contents, with directories first, followed by files. The special key ndirs contains the number of directories.<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Misc&diff=59908LuaWML/Misc2018-08-02T18:38:46Z<p>Vasya: /* helper.rand */</p>
<hr />
<div>This page describes miscellaneous [[LuaWML]] objects and helpers.<br />
<br />
==== wesnoth.game_config ====<br />
<br />
Contrarily to the other values of the ''wesnoth'' table, ''game_config'' is simply a proxy table. Its fields offer an interface to the global settings of Wesnoth:<br />
<br />
* '''version''': string (read only)<br />
* '''base_income''': integer (read/write)<br />
* '''village_income''': integer (read/write)<br />
* '''poison_amount''': integer (read/write)<br />
* '''rest_heal_amount''': integer (read/write)<br />
* '''recall_cost''': integer (read/write)<br />
* '''kill_experience''': integer (read/write)<br />
* '''last_turn''': integer (read/write) turn limit, maximum number of turns<br />
* '''debug''': boolean (read only)<br />
* '''mp_debug''': boolean (read only)<br />
* '''campaign_type''': string (read only) Indicates what type of game this is, e.g. "multiplayer"<br />
* '''theme''': {{DevFeature1.13|8}} string (read/write) The ID of the current scenario theme. If the scenario uses the default theme from preferences, this will be an empty string.<br />
* '''mp_settings''': table. In a multiplayer game, this is a proxy table which gives read only access to all MP-only configuration options which appear as attributes of [multiplayer] tag in a save game file:<br />
** '''active_mods''': string (read only) A list of all active modifications<br />
** '''hash''': string (read only) A hash of mp data<br />
** '''mp_campaign''': string (read only) Name of mp campaign<br />
** '''mp_scenario''': string (read only) ID of this mp scenario<br />
** '''mp_scenario_name''': string (read only) Name of this mp scenario<br />
** '''scenario''': string (read only) MP lobby title <br />
** '''difficulty_define''': string (read only) The campaign difficulty string for an mp campaign<br />
** '''mp_village_gold''': integer (read only) <br />
** '''mp_village_support''': integer (read only) <br />
** '''mp_num_turns''': integer (read only) <br />
** '''mp_era''': string (read only) The id of the chosen era<br />
** '''mp_eras''': string (read only) A list of all era ids<br />
** '''mp_fog''': boolean (read only) <br />
** '''mp_shroud''': boolean (read only) <br />
** '''mp_random_start_time''': boolean (read only) <br />
** '''experience_modifier''': integer (read only) <br />
** '''mp_use_map_settings''': boolean (read only) <br />
** '''mp_countdown''': boolean (read only) Whether the timer is enabled<br />
** '''mp_countdown_action_bonus''': integer (read only) <br />
** '''mp_countdown_init_time''': integer (read only) <br />
** '''mp_countdown_reservoir_time''': integer (read only) <br />
** '''mp_countdown_turn_bonus''': integer (read only) <br />
** '''observer''': boolean (read only) <br />
** '''shuffle_sides''': boolean (read only) <br />
** '''savegame''': boolean (read only) Whether this is a reloaded game<br />
** '''side_users''': string (read only) List of how sides are assigned to users (at game start)<br />
* '''era''': table. A proxy table for the entire era tag corresponding to the current era. Its id will always match wesnoth.game_config.mp_settings.mp_era<br />
Note: wesnoth.game_config.mp_settings, and wesnoth.game_config.era, will only exist if wesnoth.game_config.campaign_type == "multiplayer"<br />
<br />
<br />
-- Poison a bit weak? Let's boost it!<br />
wesnoth.game_config.poison_amount = 15<br />
<br />
-- Warn users when they use bad settings:<br />
if (wesnoth.game_config.mp_settings.shuffle_sides) then<br />
wesnoth.message("Warning: This scenario is not intended to be played with shuffle sides!")<br />
end<br />
<br />
-- Collect basic info about the current era:<br />
local era = wesnoth.game_config.era<br />
local helper = wesnoth.require("lua/helper.lua")<br />
local count = 0<br />
wesnoth.set_variable("era_name", era.name)<br />
for multiplayer_side in helper.child_range(era, "multiplayer_side") do<br />
count = count + 1<br />
wesnoth.set_variable("faction" .. tostring(count) .. "_name", multiplayer_side.name)<br />
wesnoth.set_variable("faction" .. tostring(count) .. "_recruit", multiplayer_side.recruit)<br />
end<br />
wesnoth.set_variable("num_factions", count)<br />
<br />
==== wesnoth.get_era ====<br />
<br />
* '''wesnoth.get_era(''id'')'''<br />
<br />
A function which takes one argument, an era id, and returns the entire era tag corresponding to that id. For a list of valid era ids, use wesnoth.game_config.mp_settings.mp_eras.<br />
<br />
==== wesnoth.current ====<br />
<br />
As with ''game_config'', ''current'' is a proxy table. Its fields are getter for game-related properties:<br />
<br />
* '''side''': integer (read only)<br />
* '''turn''': integer (read only)<br />
* '''event_context''': WML table with attributes ''name'', ''x1'', ''y1'', ''x2'', ''y2'', and children ''weapon'', ''second_weapon'', describing the trigger for the current event. {{DevFeature1.13|2}} ''unit_x'', ''unit_y'' contain the location of the primary unit involved in the event. Currently the only case where this cam be different from ''x1'' and ''y1'' are enter_hex and exit_hex events.<br />
* '''synced_state''' {{DevFeature1.13|0}} whether the current code runs in a synced contex, this returns a string, the possible values are:<br />
** '''synced''' the current code runs on all mp clients, this is the normal context, in which all gamestatechaning actions should take place.<br />
** '''unsynced''' for example during '''select''' events or during the calculation of a wesnoth.theme_items, don't change the gamestate in this context because the current code only runs on one machine, so changign the gamestate here will cause OOS. Typical things to do here are UI related things, or entering the synced state via '''[do_command]'''<br />
** '''local_choice''' the current code was invoked by wesnoth.synchronize_choice and runs only on one local client to calculate the return value for wesnoth.synchronize_choice. You cannot enter the synced context with '''[do_command]''' now.<br />
** '''preload''' we are currently running a preload event or an even earlier event, this behaves similar to '''local_choice'''<br />
<br />
wesnoth.message(string.format("Turn %d, side %d is playing.", wesnoth.current.turn, wesnoth.current.side))<br />
<br />
==== wesnoth.end_turn ====<br />
<br />
* '''wesnoth.end_turn ([''next_side''])'''<br />
<br />
like [endturn] actionwml, has a integer parmaeter that allows to specify the next side that should gain control, any integer in the range [1, 2*nsides] is allowed, where a number greater than nsides also changes the turn counter by one.<br />
<br />
==== wesnoth.synchronize_choice ====<br />
<br />
* '''wesnoth.synchronize_choice(''function'', [''ai_function''])'''<br />
* {{DevFeature1.13|2}} '''wesnoth.synchronize_choice([''description''], ''function'', [''ai_function''], [''for_side''])'''<br />
<br />
Recovers a WML table that was computed on one client only or was stored in a replay. The actual computation is performed by the function passed as the first function argument, assuming that the client is the side currently playing. For all the other clients, the function will not be called. An optional second function can be passed; if present, it will be used instead of the first one when the client happens to be an AI (hence not enable to interact with a user interface).<br />
<br />
local result = wesnoth.synchronize_choice(<br />
function()<br />
-- Called only on the client handling the current side, if it is a human.<br />
local choice = 0<br />
wesnoth.show_dialog(<br />
some_dialog_cfg, nil,<br />
function()<br />
choice = wesnoth.get_dialog_value "some_list"<br />
end)<br />
return { value = choice }<br />
end,<br />
function()<br />
-- Called only on the client handling the current side, if it is an AI.<br />
return { value = math.random(some_list_size) }<br />
end)<br />
wesnoth.message(string.format("Selected item: %d", result.value))<br />
<br />
Note: The return value must be a valid WML table - the same kind of thing you could store to a WML variable, and not, for instance, a proxy unit, anything else that uses metatables, or a lua table with another table as the value of a string attribute. Unlike other lua functions, wesnoth.synchronize_choice will NOT throw an error if the table is invalid, but will silently strip out the contents of any invalid subtag.<br />
<br />
When wesnoth is running in debug mode (e.g. --debug flag on command line) synchronize_choice will chat a "Lua Warning" if it finds that the table returned was partially invalid.<br />
<br />
{{DevFeature1.13|2}}<br />
This function takes now takes these arguments:<br />
* An optional translatable string descibing the type of the user input. This is displayed to the other clients while one client executes the passeed function. Defaults to "input".<br />
* A function: (as before).<br />
* An optional function: for ai sides (as before).<br />
* An optional integer: on which side the function should be evaluated. Defaults to the currently playing side. If the specified side is empty/null controlled the engine will choose another side.<br />
<br />
==== wesnoth.synchronize_choices ====<br />
<br />
* '''wesnoth.synchronize_choices([''description''], ''function'', [''default_function''], [''for_sides''])'''<br />
<br />
{{DevFeature1.13|2}} Similar to the singular form above, this function takes a function parameter and evaluates it on the specified sides. It takes the following arguments:<br />
* An optional translatable string descibing the type of the user input. This is displayed to the other clients while the specified clients execute the passeed function. Defaults to "input"<br />
* A function that evaluates the choice returning a wml table. Unlike above, this function is called for ai and human sides (use if controller == "ai" for checking if it is a ai side)<br />
* An optional function for evaluating the choice in case this side was null controlled. If this function is called, it is called on all clients (unlike the first passed function) defaults to a function returning an empty table.<br />
* An array of integers specifying on which sides this function should be evaluated, the function is evaluated on all passed sides, each side may only appear once in this array. All specified sides execute the function simultaniously.<br />
<br />
This function returns a table with integer as keys and WML tables as values. the keys are the sides where that action was evaluated. The values are the values computed by the passed function.<br />
Example:<br />
[event]<br />
name = "start"<br />
[lua]<br />
code = <<<br />
wesnoth.set_variable("input1",nil)<br />
local result = wesnoth.synchronize_choices(<br />
function()<br />
local option1 = T.option { message = "No", T.command { T.set_variable { name = "input1", value = "No"}}}<br />
local option2 = T.option { message = "Yes", T.command { T.set_variable { name = "input1", value = "Yes"}}}<br />
wesnoth.fire(T.message{ message = "Are you sure you want to play this game?", option1, option2})<br />
return { value = wesnoth.get_variable("input1") }<br />
end,<br />
{1,2})<br />
wesnoth.set_variable("input1",nil)<br />
wesnoth.message("Player 1 wants to play: " .. result[1].value)<br />
wesnoth.message("Player 2 wants to play: " .. result[2].value)<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
==== wesnoth.get_image_size ====<br />
<br />
* '''wesnoth.get_image_size(''filename'')'''<br />
<br />
Returns the width and height of an image.<br />
<br />
local w, h = wesnoth.get_image_size "units/transport/galleon.png"<br />
<br />
==== wesnoth.compare_versions ====<br />
<br />
* '''wesnoth.compare_versions(''version1'', ''operator'', ''version2'')'''<br />
<br />
Takes two versions strings and an operator, returns whether the comparison yields true.<br />
Follows the same rules like the #ifver preprocessor statement.<br />
<br />
local function version_is_sufficient(required)<br />
if not wesnoth.compare_versions then return false end<br />
return wesnoth.compare_versions(wesnoth.game_config.version, ">=", required)<br />
end<br />
local required = "1.9.6"<br />
if not version_is_sufficient(required) then wesnoth.message(string.format(<br />
"Your BfW version is insufficient, please get BfW %s or greater!", required)) end<br />
<br />
==== wesnoth.have_file ====<br />
<br />
* '''wesnoth.have_file(''filename'')'''<br />
<br />
Checks if the file (not necessarily a Lua file) or the directory passed as argument exists. Returns true if the file exists, false otherwise. Follows the same rules like the #ifhave preprocessor statement.<br />
<br />
-- Does the user have installed the UMC Music Book 1?<br />
local umc_music = wesnoth.have_file( "~add-ons/UMC_Music_Book_1/_main.cfg" )<br />
-- and if we want to check for the folder?<br />
local music_folder = wesnoth.have_file( "~add-ons/UMC_Music_Book_1/" )<br />
<br />
==== wesnoth.debug ====<br />
<br />
* '''wesnoth.debug(''wml_table'')'''<br />
<br />
Takes a userdata with metatable wml object or a wml table and dumps its content into a pretty string.<br />
wesnoth.set_variable("number", 100)<br />
local vconfig = wesnoth.tovconfig({ key = "$number", another_key = true,<br />
{"a_subtag", { a_key_in_the_subtag = "foo" }}<br />
})<br />
wesnoth.message(wesnoth.debug(vconfig))<br />
wesnoth.message(wesnoth.debug(vconfig.__literal))<br />
<br />
==== wesnoth.get_time_stamp ====<br />
<br />
* '''wesnoth.get_time_stamp()'''<br />
<br />
This function retrieves the current time stamp, that is the amount of milliseconds passed from when the SDL library was initialized. It takes no arguments and returns an integer.<br />
'''WARNING:''' this function uses the same code as [set_variable] time=stamp, and so it is MP-unsafe. It is provided only for benchmark purposes and AI development, although it should work inside wesnoth.synchronize_choice() as well.<br />
local stamp = wesnoth.get_time_stamp()<br />
<br />
==== wesnoth.random ====<br />
<br />
* '''wesnoth.random([''m'', [''n'']])'''<br />
<br />
{{DevFeature1.13|2}} This function returns a random number generated by the synced random generator which is also used by [set_variable]rand= (and thus also by helper.rand). This function has the same interface as [http://www.lua.org/manual/5.2/manual.html#pdf-math.random math.random] so it can take 0, 1 or 2 arguments.<br />
<br />
In map generation scripts, the values returned by this function depend on the seed the map author has input (if any).<br />
<br />
Be careful as '''random''' is not safe in certain events, see [[EventWML#Multiplayer_safety|Multiplayer_safety]].<br />
<br />
==== wesnoth.unsynced ====<br />
<br />
* '''wesnoth.unsynced(''func'')'''<br />
<br />
calls the given function in a unsynced context, that is in particular, while executing that function random results will not be synced in mp.<br />
<br />
==== wesnoth.compile_formula ====<br />
<br />
* '''wesnoth.compile_formula(''formula'')'''<br />
<br />
{{DevFeature1.13|5}} Compiles a [[Wesnoth Formula Language]] formula into a Lua callable userdata. The callable value returned by this function can take an optional table as argument, which defines variables available to the formula. It can also take a unit proxy as argument, which evaluates the formula in that unit's context just as if it had been used in a [[StandardUnitFilter]].<br />
<br />
A compiled formula can be converted back to valid code using the built-in <code>tostring</code> function.<br />
<br />
==== wesnoth.eval_formula ====<br />
<br />
* '''wesnoth.eval_formula(''formula'', [''variables''])'''<br />
<br />
{{DevFeature1.13|5}} Equivalent to <syntaxhighlight lang='lua' inline>wesnoth.compile_formula(formula)(variables)</syntaxhighlight>. It can also evaluate an already-compiled formula, which is equivalent to calling the formula.<br />
<br />
==== wesnoth.name_generator ====<br />
<br />
* '''wesnoth.name_generator(''type'', ''definition'', [''additional params''])'''<br />
<br />
{{DevFeature1.13|5}} Constructs a name generator for use in generating names using either the Markov chain algorithm used in older versions of Wesnoth or the context-free grammar generator used since 1.13.5. The type parameter indicates which algorithm to use (either markov or cfg). The definition can be a string, just like it would be in a config file, or it can be formatted as a table. Additional parameters may be passed, depending on the type of generator. The function returns a callable userdata, which will return a new name each time it is called (with no parameters).<br />
<br />
* '''Markov chain''': A Markov chain generator works by analyzing a list of input names and noticing tendencies in the way the letters are strung together. It can then apply those tendencies to produce new similar names that were not in the original list. Longer lists give better results. The definition is a list of names, formatted either as a comma-separated string or as an array-like table. The Markov generator can take two additional parameters. The first additional parameter is ''chain_size'', and the second is ''max_length''.<br />
** A value greater than 1 for the chain_size causes the analyzer to consider the words in chunks, which is similar to analyzing them syllable by syllable instead of letter by letter. The default chain size is 2, meaning that the analyzer treats words as consisting of 2-character syllables.<br />
** The max_length places a cap on the total length of the name. The default value is 12 characters.<br />
* '''Context-free grammar''': A [[context-free grammar]] is a way of specifying how strings can be constructed. The definition may be specified as a multi-line string, just as described in the preceding link, or it can be formatted as a table where the keys are non-terminals and the values are what they expand to. The expansion of each non-terminal can be formatted either as a |-separated list as described in the preceding link, or as an array-like table. (Mixing the two forms is permissible too.) The context-free generator has no additional parameters.<br />
<br />
==== wesnoth.format ====<br />
<br />
* '''wesnoth.format(''format_string'', ''values'')'''<br />
<br />
Similar to '''string.format''' but using Wesnoth's variable substitution syntax, and also supporting translatable strings. Any valid config can be passed as the values, though typically you will only need key-value pairs. You could also substitute WML variables into a string by passing '''wesnoth.get_all_vars()''' as the second parameter.<br />
<br />
This function preserves the translatability of the input format string.<br />
<br />
==== wesnoth.format_conjunct_list ====<br />
<br />
* '''wesnoth.format_conjunct_list(''list_of_strings'')'''<br />
<br />
Formats a list of usually-translatable strings into a localized list string of the form "A, B, and C".<br />
<br />
==== wesnoth.format_disjunct_list ====<br />
<br />
* '''wesnoth.format_disjunct_list(''list_of_strings'')'''<br />
<br />
Formats a list of usually-translatable strings into a localized list string of the form "A, B, or C".<br />
<br />
==== helper.set_wml_tag_metatable ====<br />
<br />
* '''helper.set_wml_tag_metatable{}'''<br />
<br />
Sets the metable of a table so that it can be used to create subtags with less brackets. Returns the table. The fields of the table are simple wrappers around table constructors.<br />
<br />
T = helper.set_wml_tag_metatable {}<br />
W.event { name = "new turn", T.message { speaker = "narrator", message = "?" } }<br />
<br />
==== helper.modify_unit ====<br />
<br />
* '''helper.modify_unit(''filter'', ''keys'')'''<br />
<br />
Modifies all the units satisfying the given filter (argument 1) with some WML attributes/objects (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MODIFY_UNIT] macro.<br />
<br />
helper.modify_unit({ id="Delfador" }, { moves=0 })<br />
<br />
'''Note:''' This appears to be less powerful than the [modify_unit] tag and may be removed at some point in the future.<br />
<br />
==== helper.move_unit_fake ====<br />
<br />
* '''helper.move_unit_fake(''unit'', ''destination'')'''<br />
<br />
Fakes the move of a unit satisfying the given filter (argument 1) to the given position (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MOVE_UNIT] macro.<br />
<br />
helper.move_unit_fake({ id="Delfador" }, 14, 8)<br />
<br />
==== helper.rand ====<br />
<br />
* '''helper.rand(''spec'')'''<br />
<br />
(A shortcut to [[InternalActionsWML#.5Bset_variable.5D|set_variable's rand=]] since math.rand is an OOS magnet and therefore disabled.) Pass a string like you would to set_variable's rand=.<br />
<br />
create a random unit at (1, 1) on side=1 :<br />
wesnoth.put_unit(1, 1, { type = helper.rand("Dwarvish Fighter,Dwarvish Thunderer,Dwarvish Scout") })<br />
<br />
Note that '''random''' is only safe in certain events, see [[EventWML#Multiplayer_safety|Multiplayer Safety]].<br />
<br />
==== helper.round ====<br />
<br />
* '''helper.round(''n'')'''<br />
<br />
Unlike other languages (Python, Perl, Javascript, ...), Lua does not include a round function. This helper function allows rounding numbers, following the "round half away from zero method", see Wikipedia [[http://en.wikipedia.org/wiki/Rounding_numbers#Round_half_away_from_zero]]. Returns the number rounded to the nearest integer.<br />
<br />
-- this number will be rounded up<br />
helper.round(345.67) -- returns 346<br />
-- this one will be rounded down<br />
helper.round(543.21) -- returns 543<br />
-- an integer stays integer<br />
helper.round(123) -- returns 123<br />
-- works also for negative numbers<br />
helper.round(-369.84) -- returns -370<br />
helper.round(-246.42) -- returns -246<br />
<br />
==== helper.shuffle ====<br />
<br />
* '''helper.shuffle(''array'')'''<br />
* {{DevFeature1.13|2}} '''helper.shuffle(''array'', ''[random_function]'')'''<br />
This function randomly sorts in place the elements of the table passed as argument, following the Fisher-Yates algorithm. It returns no value.<br />
'''WARNING:''' this function uses Lua's math.random(), and so it is '''not''' MP-safe. It is provided mainly for AI development, although it should work inside wesnoth.synchronize_choice() as well.<br />
<br />
local locs = wesnoth.get_locations( { terrain="G*" } )<br />
helper.shuffle( locs )<br />
<br />
{{DevFeature1.13|2}}<br />
This function now uses the synced RNG by default and should not cause OOS anymore. It is also possible now to pass a different random generator as a second argument; a random generator is a function that takes two integers <i>a</i> and <i>b</i> and returns a random integer in the range [<i>a</i>,<i>b</i>]. For example, math.random can be passed to get the 1.12 behavior:<br />
<br />
local locs = wesnoth.get_locations( { terrain="G*" } )<br />
helper.shuffle( locs, math.random )<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Misc&diff=59907LuaWML/Misc2018-08-02T18:33:36Z<p>Vasya: /* wesnoth.random */</p>
<hr />
<div>This page describes miscellaneous [[LuaWML]] objects and helpers.<br />
<br />
==== wesnoth.game_config ====<br />
<br />
Contrarily to the other values of the ''wesnoth'' table, ''game_config'' is simply a proxy table. Its fields offer an interface to the global settings of Wesnoth:<br />
<br />
* '''version''': string (read only)<br />
* '''base_income''': integer (read/write)<br />
* '''village_income''': integer (read/write)<br />
* '''poison_amount''': integer (read/write)<br />
* '''rest_heal_amount''': integer (read/write)<br />
* '''recall_cost''': integer (read/write)<br />
* '''kill_experience''': integer (read/write)<br />
* '''last_turn''': integer (read/write) turn limit, maximum number of turns<br />
* '''debug''': boolean (read only)<br />
* '''mp_debug''': boolean (read only)<br />
* '''campaign_type''': string (read only) Indicates what type of game this is, e.g. "multiplayer"<br />
* '''theme''': {{DevFeature1.13|8}} string (read/write) The ID of the current scenario theme. If the scenario uses the default theme from preferences, this will be an empty string.<br />
* '''mp_settings''': table. In a multiplayer game, this is a proxy table which gives read only access to all MP-only configuration options which appear as attributes of [multiplayer] tag in a save game file:<br />
** '''active_mods''': string (read only) A list of all active modifications<br />
** '''hash''': string (read only) A hash of mp data<br />
** '''mp_campaign''': string (read only) Name of mp campaign<br />
** '''mp_scenario''': string (read only) ID of this mp scenario<br />
** '''mp_scenario_name''': string (read only) Name of this mp scenario<br />
** '''scenario''': string (read only) MP lobby title <br />
** '''difficulty_define''': string (read only) The campaign difficulty string for an mp campaign<br />
** '''mp_village_gold''': integer (read only) <br />
** '''mp_village_support''': integer (read only) <br />
** '''mp_num_turns''': integer (read only) <br />
** '''mp_era''': string (read only) The id of the chosen era<br />
** '''mp_eras''': string (read only) A list of all era ids<br />
** '''mp_fog''': boolean (read only) <br />
** '''mp_shroud''': boolean (read only) <br />
** '''mp_random_start_time''': boolean (read only) <br />
** '''experience_modifier''': integer (read only) <br />
** '''mp_use_map_settings''': boolean (read only) <br />
** '''mp_countdown''': boolean (read only) Whether the timer is enabled<br />
** '''mp_countdown_action_bonus''': integer (read only) <br />
** '''mp_countdown_init_time''': integer (read only) <br />
** '''mp_countdown_reservoir_time''': integer (read only) <br />
** '''mp_countdown_turn_bonus''': integer (read only) <br />
** '''observer''': boolean (read only) <br />
** '''shuffle_sides''': boolean (read only) <br />
** '''savegame''': boolean (read only) Whether this is a reloaded game<br />
** '''side_users''': string (read only) List of how sides are assigned to users (at game start)<br />
* '''era''': table. A proxy table for the entire era tag corresponding to the current era. Its id will always match wesnoth.game_config.mp_settings.mp_era<br />
Note: wesnoth.game_config.mp_settings, and wesnoth.game_config.era, will only exist if wesnoth.game_config.campaign_type == "multiplayer"<br />
<br />
<br />
-- Poison a bit weak? Let's boost it!<br />
wesnoth.game_config.poison_amount = 15<br />
<br />
-- Warn users when they use bad settings:<br />
if (wesnoth.game_config.mp_settings.shuffle_sides) then<br />
wesnoth.message("Warning: This scenario is not intended to be played with shuffle sides!")<br />
end<br />
<br />
-- Collect basic info about the current era:<br />
local era = wesnoth.game_config.era<br />
local helper = wesnoth.require("lua/helper.lua")<br />
local count = 0<br />
wesnoth.set_variable("era_name", era.name)<br />
for multiplayer_side in helper.child_range(era, "multiplayer_side") do<br />
count = count + 1<br />
wesnoth.set_variable("faction" .. tostring(count) .. "_name", multiplayer_side.name)<br />
wesnoth.set_variable("faction" .. tostring(count) .. "_recruit", multiplayer_side.recruit)<br />
end<br />
wesnoth.set_variable("num_factions", count)<br />
<br />
==== wesnoth.get_era ====<br />
<br />
* '''wesnoth.get_era(''id'')'''<br />
<br />
A function which takes one argument, an era id, and returns the entire era tag corresponding to that id. For a list of valid era ids, use wesnoth.game_config.mp_settings.mp_eras.<br />
<br />
==== wesnoth.current ====<br />
<br />
As with ''game_config'', ''current'' is a proxy table. Its fields are getter for game-related properties:<br />
<br />
* '''side''': integer (read only)<br />
* '''turn''': integer (read only)<br />
* '''event_context''': WML table with attributes ''name'', ''x1'', ''y1'', ''x2'', ''y2'', and children ''weapon'', ''second_weapon'', describing the trigger for the current event. {{DevFeature1.13|2}} ''unit_x'', ''unit_y'' contain the location of the primary unit involved in the event. Currently the only case where this cam be different from ''x1'' and ''y1'' are enter_hex and exit_hex events.<br />
* '''synced_state''' {{DevFeature1.13|0}} whether the current code runs in a synced contex, this returns a string, the possible values are:<br />
** '''synced''' the current code runs on all mp clients, this is the normal context, in which all gamestatechaning actions should take place.<br />
** '''unsynced''' for example during '''select''' events or during the calculation of a wesnoth.theme_items, don't change the gamestate in this context because the current code only runs on one machine, so changign the gamestate here will cause OOS. Typical things to do here are UI related things, or entering the synced state via '''[do_command]'''<br />
** '''local_choice''' the current code was invoked by wesnoth.synchronize_choice and runs only on one local client to calculate the return value for wesnoth.synchronize_choice. You cannot enter the synced context with '''[do_command]''' now.<br />
** '''preload''' we are currently running a preload event or an even earlier event, this behaves similar to '''local_choice'''<br />
<br />
wesnoth.message(string.format("Turn %d, side %d is playing.", wesnoth.current.turn, wesnoth.current.side))<br />
<br />
==== wesnoth.end_turn ====<br />
<br />
* '''wesnoth.end_turn ([''next_side''])'''<br />
<br />
like [endturn] actionwml, has a integer parmaeter that allows to specify the next side that should gain control, any integer in the range [1, 2*nsides] is allowed, where a number greater than nsides also changes the turn counter by one.<br />
<br />
==== wesnoth.synchronize_choice ====<br />
<br />
* '''wesnoth.synchronize_choice(''function'', [''ai_function''])'''<br />
* {{DevFeature1.13|2}} '''wesnoth.synchronize_choice([''description''], ''function'', [''ai_function''], [''for_side''])'''<br />
<br />
Recovers a WML table that was computed on one client only or was stored in a replay. The actual computation is performed by the function passed as the first function argument, assuming that the client is the side currently playing. For all the other clients, the function will not be called. An optional second function can be passed; if present, it will be used instead of the first one when the client happens to be an AI (hence not enable to interact with a user interface).<br />
<br />
local result = wesnoth.synchronize_choice(<br />
function()<br />
-- Called only on the client handling the current side, if it is a human.<br />
local choice = 0<br />
wesnoth.show_dialog(<br />
some_dialog_cfg, nil,<br />
function()<br />
choice = wesnoth.get_dialog_value "some_list"<br />
end)<br />
return { value = choice }<br />
end,<br />
function()<br />
-- Called only on the client handling the current side, if it is an AI.<br />
return { value = math.random(some_list_size) }<br />
end)<br />
wesnoth.message(string.format("Selected item: %d", result.value))<br />
<br />
Note: The return value must be a valid WML table - the same kind of thing you could store to a WML variable, and not, for instance, a proxy unit, anything else that uses metatables, or a lua table with another table as the value of a string attribute. Unlike other lua functions, wesnoth.synchronize_choice will NOT throw an error if the table is invalid, but will silently strip out the contents of any invalid subtag.<br />
<br />
When wesnoth is running in debug mode (e.g. --debug flag on command line) synchronize_choice will chat a "Lua Warning" if it finds that the table returned was partially invalid.<br />
<br />
{{DevFeature1.13|2}}<br />
This function takes now takes these arguments:<br />
* An optional translatable string descibing the type of the user input. This is displayed to the other clients while one client executes the passeed function. Defaults to "input".<br />
* A function: (as before).<br />
* An optional function: for ai sides (as before).<br />
* An optional integer: on which side the function should be evaluated. Defaults to the currently playing side. If the specified side is empty/null controlled the engine will choose another side.<br />
<br />
==== wesnoth.synchronize_choices ====<br />
<br />
* '''wesnoth.synchronize_choices([''description''], ''function'', [''default_function''], [''for_sides''])'''<br />
<br />
{{DevFeature1.13|2}} Similar to the singular form above, this function takes a function parameter and evaluates it on the specified sides. It takes the following arguments:<br />
* An optional translatable string descibing the type of the user input. This is displayed to the other clients while the specified clients execute the passeed function. Defaults to "input"<br />
* A function that evaluates the choice returning a wml table. Unlike above, this function is called for ai and human sides (use if controller == "ai" for checking if it is a ai side)<br />
* An optional function for evaluating the choice in case this side was null controlled. If this function is called, it is called on all clients (unlike the first passed function) defaults to a function returning an empty table.<br />
* An array of integers specifying on which sides this function should be evaluated, the function is evaluated on all passed sides, each side may only appear once in this array. All specified sides execute the function simultaniously.<br />
<br />
This function returns a table with integer as keys and WML tables as values. the keys are the sides where that action was evaluated. The values are the values computed by the passed function.<br />
Example:<br />
[event]<br />
name = "start"<br />
[lua]<br />
code = <<<br />
wesnoth.set_variable("input1",nil)<br />
local result = wesnoth.synchronize_choices(<br />
function()<br />
local option1 = T.option { message = "No", T.command { T.set_variable { name = "input1", value = "No"}}}<br />
local option2 = T.option { message = "Yes", T.command { T.set_variable { name = "input1", value = "Yes"}}}<br />
wesnoth.fire(T.message{ message = "Are you sure you want to play this game?", option1, option2})<br />
return { value = wesnoth.get_variable("input1") }<br />
end,<br />
{1,2})<br />
wesnoth.set_variable("input1",nil)<br />
wesnoth.message("Player 1 wants to play: " .. result[1].value)<br />
wesnoth.message("Player 2 wants to play: " .. result[2].value)<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
==== wesnoth.get_image_size ====<br />
<br />
* '''wesnoth.get_image_size(''filename'')'''<br />
<br />
Returns the width and height of an image.<br />
<br />
local w, h = wesnoth.get_image_size "units/transport/galleon.png"<br />
<br />
==== wesnoth.compare_versions ====<br />
<br />
* '''wesnoth.compare_versions(''version1'', ''operator'', ''version2'')'''<br />
<br />
Takes two versions strings and an operator, returns whether the comparison yields true.<br />
Follows the same rules like the #ifver preprocessor statement.<br />
<br />
local function version_is_sufficient(required)<br />
if not wesnoth.compare_versions then return false end<br />
return wesnoth.compare_versions(wesnoth.game_config.version, ">=", required)<br />
end<br />
local required = "1.9.6"<br />
if not version_is_sufficient(required) then wesnoth.message(string.format(<br />
"Your BfW version is insufficient, please get BfW %s or greater!", required)) end<br />
<br />
==== wesnoth.have_file ====<br />
<br />
* '''wesnoth.have_file(''filename'')'''<br />
<br />
Checks if the file (not necessarily a Lua file) or the directory passed as argument exists. Returns true if the file exists, false otherwise. Follows the same rules like the #ifhave preprocessor statement.<br />
<br />
-- Does the user have installed the UMC Music Book 1?<br />
local umc_music = wesnoth.have_file( "~add-ons/UMC_Music_Book_1/_main.cfg" )<br />
-- and if we want to check for the folder?<br />
local music_folder = wesnoth.have_file( "~add-ons/UMC_Music_Book_1/" )<br />
<br />
==== wesnoth.debug ====<br />
<br />
* '''wesnoth.debug(''wml_table'')'''<br />
<br />
Takes a userdata with metatable wml object or a wml table and dumps its content into a pretty string.<br />
wesnoth.set_variable("number", 100)<br />
local vconfig = wesnoth.tovconfig({ key = "$number", another_key = true,<br />
{"a_subtag", { a_key_in_the_subtag = "foo" }}<br />
})<br />
wesnoth.message(wesnoth.debug(vconfig))<br />
wesnoth.message(wesnoth.debug(vconfig.__literal))<br />
<br />
==== wesnoth.get_time_stamp ====<br />
<br />
* '''wesnoth.get_time_stamp()'''<br />
<br />
This function retrieves the current time stamp, that is the amount of milliseconds passed from when the SDL library was initialized. It takes no arguments and returns an integer.<br />
'''WARNING:''' this function uses the same code as [set_variable] time=stamp, and so it is MP-unsafe. It is provided only for benchmark purposes and AI development, although it should work inside wesnoth.synchronize_choice() as well.<br />
local stamp = wesnoth.get_time_stamp()<br />
<br />
==== wesnoth.random ====<br />
<br />
* '''wesnoth.random([''m'', [''n'']])'''<br />
<br />
{{DevFeature1.13|2}} This function returns a random number generated by the synced random generator which is also used by [set_variable]rand= (and thus also by helper.rand). This function has the same interface as [http://www.lua.org/manual/5.2/manual.html#pdf-math.random math.random] so it can take 0, 1 or 2 arguments.<br />
<br />
In map generation scripts, the values returned by this function depend on the seed the map author has input (if any).<br />
<br />
Be careful as '''random''' is not safe in certain events, see [[EventWML#Multiplayer_safety|Multiplayer_safety]].<br />
<br />
==== wesnoth.unsynced ====<br />
<br />
* '''wesnoth.unsynced(''func'')'''<br />
<br />
calls the given function in a unsynced context, that is in particular, while executing that function random results will not be synced in mp.<br />
<br />
==== wesnoth.compile_formula ====<br />
<br />
* '''wesnoth.compile_formula(''formula'')'''<br />
<br />
{{DevFeature1.13|5}} Compiles a [[Wesnoth Formula Language]] formula into a Lua callable userdata. The callable value returned by this function can take an optional table as argument, which defines variables available to the formula. It can also take a unit proxy as argument, which evaluates the formula in that unit's context just as if it had been used in a [[StandardUnitFilter]].<br />
<br />
A compiled formula can be converted back to valid code using the built-in <code>tostring</code> function.<br />
<br />
==== wesnoth.eval_formula ====<br />
<br />
* '''wesnoth.eval_formula(''formula'', [''variables''])'''<br />
<br />
{{DevFeature1.13|5}} Equivalent to <syntaxhighlight lang='lua' inline>wesnoth.compile_formula(formula)(variables)</syntaxhighlight>. It can also evaluate an already-compiled formula, which is equivalent to calling the formula.<br />
<br />
==== wesnoth.name_generator ====<br />
<br />
* '''wesnoth.name_generator(''type'', ''definition'', [''additional params''])'''<br />
<br />
{{DevFeature1.13|5}} Constructs a name generator for use in generating names using either the Markov chain algorithm used in older versions of Wesnoth or the context-free grammar generator used since 1.13.5. The type parameter indicates which algorithm to use (either markov or cfg). The definition can be a string, just like it would be in a config file, or it can be formatted as a table. Additional parameters may be passed, depending on the type of generator. The function returns a callable userdata, which will return a new name each time it is called (with no parameters).<br />
<br />
* '''Markov chain''': A Markov chain generator works by analyzing a list of input names and noticing tendencies in the way the letters are strung together. It can then apply those tendencies to produce new similar names that were not in the original list. Longer lists give better results. The definition is a list of names, formatted either as a comma-separated string or as an array-like table. The Markov generator can take two additional parameters. The first additional parameter is ''chain_size'', and the second is ''max_length''.<br />
** A value greater than 1 for the chain_size causes the analyzer to consider the words in chunks, which is similar to analyzing them syllable by syllable instead of letter by letter. The default chain size is 2, meaning that the analyzer treats words as consisting of 2-character syllables.<br />
** The max_length places a cap on the total length of the name. The default value is 12 characters.<br />
* '''Context-free grammar''': A [[context-free grammar]] is a way of specifying how strings can be constructed. The definition may be specified as a multi-line string, just as described in the preceding link, or it can be formatted as a table where the keys are non-terminals and the values are what they expand to. The expansion of each non-terminal can be formatted either as a |-separated list as described in the preceding link, or as an array-like table. (Mixing the two forms is permissible too.) The context-free generator has no additional parameters.<br />
<br />
==== wesnoth.format ====<br />
<br />
* '''wesnoth.format(''format_string'', ''values'')'''<br />
<br />
Similar to '''string.format''' but using Wesnoth's variable substitution syntax, and also supporting translatable strings. Any valid config can be passed as the values, though typically you will only need key-value pairs. You could also substitute WML variables into a string by passing '''wesnoth.get_all_vars()''' as the second parameter.<br />
<br />
This function preserves the translatability of the input format string.<br />
<br />
==== wesnoth.format_conjunct_list ====<br />
<br />
* '''wesnoth.format_conjunct_list(''list_of_strings'')'''<br />
<br />
Formats a list of usually-translatable strings into a localized list string of the form "A, B, and C".<br />
<br />
==== wesnoth.format_disjunct_list ====<br />
<br />
* '''wesnoth.format_disjunct_list(''list_of_strings'')'''<br />
<br />
Formats a list of usually-translatable strings into a localized list string of the form "A, B, or C".<br />
<br />
==== helper.set_wml_tag_metatable ====<br />
<br />
* '''helper.set_wml_tag_metatable{}'''<br />
<br />
Sets the metable of a table so that it can be used to create subtags with less brackets. Returns the table. The fields of the table are simple wrappers around table constructors.<br />
<br />
T = helper.set_wml_tag_metatable {}<br />
W.event { name = "new turn", T.message { speaker = "narrator", message = "?" } }<br />
<br />
==== helper.modify_unit ====<br />
<br />
* '''helper.modify_unit(''filter'', ''keys'')'''<br />
<br />
Modifies all the units satisfying the given filter (argument 1) with some WML attributes/objects (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MODIFY_UNIT] macro.<br />
<br />
helper.modify_unit({ id="Delfador" }, { moves=0 })<br />
<br />
'''Note:''' This appears to be less powerful than the [modify_unit] tag and may be removed at some point in the future.<br />
<br />
==== helper.move_unit_fake ====<br />
<br />
* '''helper.move_unit_fake(''unit'', ''destination'')'''<br />
<br />
Fakes the move of a unit satisfying the given filter (argument 1) to the given position (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MOVE_UNIT] macro.<br />
<br />
helper.move_unit_fake({ id="Delfador" }, 14, 8)<br />
<br />
==== helper.rand ====<br />
<br />
* '''helper.rand(''spec'')'''<br />
<br />
(A shortcut to [[InternalActionsWML#.5Bset_variable.5D|set_variable's rand=]] since math.rand is an OOS magnet and therefore disabled.) Pass a string like you would to set_variable's rand=.<br />
<br />
create a random unit at (1, 1) on side=1 :<br />
wesnoth.put_unit(1, 1, { type = helper.rand("Dwarvish Fighter,Dwarvish Thunderer,Dwarvish Scout") })<br />
<br />
==== helper.round ====<br />
<br />
* '''helper.round(''n'')'''<br />
<br />
Unlike other languages (Python, Perl, Javascript, ...), Lua does not include a round function. This helper function allows rounding numbers, following the "round half away from zero method", see Wikipedia [[http://en.wikipedia.org/wiki/Rounding_numbers#Round_half_away_from_zero]]. Returns the number rounded to the nearest integer.<br />
<br />
-- this number will be rounded up<br />
helper.round(345.67) -- returns 346<br />
-- this one will be rounded down<br />
helper.round(543.21) -- returns 543<br />
-- an integer stays integer<br />
helper.round(123) -- returns 123<br />
-- works also for negative numbers<br />
helper.round(-369.84) -- returns -370<br />
helper.round(-246.42) -- returns -246<br />
<br />
==== helper.shuffle ====<br />
<br />
* '''helper.shuffle(''array'')'''<br />
* {{DevFeature1.13|2}} '''helper.shuffle(''array'', ''[random_function]'')'''<br />
This function randomly sorts in place the elements of the table passed as argument, following the Fisher-Yates algorithm. It returns no value.<br />
'''WARNING:''' this function uses Lua's math.random(), and so it is '''not''' MP-safe. It is provided mainly for AI development, although it should work inside wesnoth.synchronize_choice() as well.<br />
<br />
local locs = wesnoth.get_locations( { terrain="G*" } )<br />
helper.shuffle( locs )<br />
<br />
{{DevFeature1.13|2}}<br />
This function now uses the synced RNG by default and should not cause OOS anymore. It is also possible now to pass a different random generator as a second argument; a random generator is a function that takes two integers <i>a</i> and <i>b</i> and returns a random integer in the range [<i>a</i>,<i>b</i>]. For example, math.random can be passed to get the 1.12 behavior:<br />
<br />
local locs = wesnoth.get_locations( { terrain="G*" } )<br />
helper.shuffle( locs, math.random )<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=EventWML&diff=59749EventWML2018-06-04T20:16:37Z<p>Vasya: /* unit placed {{DevFeature1.13|3}} */</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of [[ActionWML|actions]] which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
<syntaxhighlight lang='wml'><br />
name=<value><br />
</syntaxhighlight><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
<syntaxhighlight lang='wml'><br />
name=attacker misses,defender misses<br />
</syntaxhighlight><br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. <br />
<br />
Spaces in event names can be interchanged with ''underscores'' (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
==== Predefined Events Without Filters ====<br />
<br />
These events do not take filter parameters (except [filter_condition] which works for all events).<br />
<br />
===== preload =====<br />
<br />
Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
<br />
'''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
===== prestart =====<br />
<br />
Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
<br />
'''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
===== start =====<br />
<br />
Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
<br />
'''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
===== new turn =====<br />
<br />
Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
===== turn end =====<br />
<br />
Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
===== turn ''X'' end =====<br />
<br />
Triggers at the end of turn ''X''.<br />
<br />
===== side turn =====<br />
<br />
Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
===== ai turn =====<br />
<br />
Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
<br />
'''Note:''' ''This event can break replays if it is used improperly. The ai turn event does not fire during replays. The intention is only to guide the AI to make choices (movements, attacks) which are then saved to the replay.''<br />
<br />
===== turn refresh =====<br />
<br />
Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status. WML variable '''side_number''' holds the number of this side.<br />
<br />
Note that the turn refresh event does occur on turn 1, even though healing, income and unit refreshing do not.<br />
<br />
===== turn ''X'' =====<br />
<br />
Triggers at the start of turn ''X''. It's the first side initialization event. <br />
<br />
Side initialization events go in the order of: <br />
<br />
# '''turn ''X''''' <br />
# '''new turn''' <br />
# '''side turn''' <br />
# '''side ''X'' turn''' <br />
# '''side turn ''X''''' <br />
# '''side ''X'' turn ''Y''''' <br />
# '''turn refresh''' <br />
# '''side ''X'' turn refresh''' <br />
# '''turn ''X'' refresh''' <br />
# '''side ''X'' turn ''Y'' refresh'''<br />
<br />
===== side ''X'' turn ''Y'' =====<br />
<br />
This event triggers at the start of turn ''Y'' of side X <br />
<br />
===== side ''X'' turn =====<br />
<br />
This event triggers at the start of any turn of side X<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== side turn ''X'' =====<br />
<br />
This event triggers at the start of any side on turn X<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== side X turn Y refresh =====<br />
<br />
This event triggers at the turn refresh for side X on turn Y<br />
<br />
===== side ''X'' turn refresh =====<br />
<br />
This event triggers at the turn refresh for side X<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== turn ''X'' refresh =====<br />
<br />
This event triggers for any side at the refresh of turn X.<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== side turn end =====<br />
<br />
Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
<br />
# '''side turn end''' <br />
# '''side ''X'' turn end''' <br />
# '''side turn ''X'' end''' <br />
# '''side ''X'' turn ''Y'' end''' <br />
# '''turn end''' <br />
# '''turn ''X'' end''' <br />
<br />
===== time over =====<br />
<br />
Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
===== enemies defeated =====<br />
<br />
Triggers when all sides that are not defeated are allied and if there is at least one human (or human networked) side among them. Especially this event triggers in a situaltion that would normaly cause a victory due to enemies defeated. (regardless of whether this was disabled with victory_when_enemies_defeated=no). <br />
<br />
===== victory =====<br />
<br />
In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]]). This event is not synchonized in networked mp or in replays. The reason is that it is possible to have diffrent results in a mp game (one player wins so a '''victory''' event is fired on that client, other player loses so a '''defeat''' event is fired on his client)<br />
<br />
===== defeat =====<br />
<br />
In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]]). Like '''victory''', this event is not synchonized in networked mp or in replays.<br />
<br />
==== Predefined Events With Filters ====<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables '''unit''' and '''second_unit''' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]. weapon and second_weapon variables are available inside attack, attacker_hits, defender_hits, die and last_breath events. See [[VariablesWML#Automatically_Stored_Variables|automatically stored variables]] for more information.<br />
<br />
===== moveto =====<br />
<br />
Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on. If the unit moves to a village, the capture event will be fired before this event. <br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' $x2 and $y2 refer to the hex the unit came from.<br />
<br />
===== sighted =====<br />
<br />
A '''sighted''' event is triggered by a unit becoming visible to a side (other than the unit's own side). This is mostly useful when the side seeing the unit uses [[fog of war]] or [[shroud]], but they still fire even when fog/shroud is not in use, and they do take into account the {{tag2|AbilitiesWML#The_.5Babilities.5D_tag|hides}} ability (for a moving unit and for ambushers). The ''primary unit'' is the unit that became visible, and the ''secondary unit'' belongs to the side that now sees the primary unit. In some cases, sighted events can be delayed from when they "should" occur. If that happens, the secondary unit will be filtered as if it was at the location where the event "should" have occurred, and ''x2,y2'' will store that location (not the current position of the secondary unit). To understand when sighted events fire, it is helpful to distinguish the times the acting unit sights other units from the times when the acting unit is sighted.<br />
<br />
An acting unit can sight other units when it is recruited, recalled, leveled, or moved, and when fog or shroud is cleared from occupied hexes as a result. In these cases, the acting unit is always the ''secondary unit''. For the first three actions, there are two events associated with the action; clearing occurs between these events, but any sighted events are fired after the second event. (For example, when a unit is recruited, the ''prerecruit'' event fires, then fog is cleared, then the ''recruit'' event fires, then ''sighted'' events fire.) For movement, the sighted events fire between ''enter_hex'' and ''exit_hex'' events, but sometimes sighted events are postponed until the moving unit reaches a good place to stop (e.g. not in an occupied hex). As a major exception to the above, players have the option to delay shroud (and fog) updates. If the player delays shroud updates, sighted events are also delayed until the shroud is updated.<br />
<br />
An acting unit can be sighted by other sides when it is recruited, recalled, leveled (in rare cases), or moved. In these cases, the acting unit is always the ''primary unit''. These events fire after sightings by the acting unit (unless the player delayed shroud updates). For the first two, the sighted event fires for all sides that can see the unit, other than the unit's own side (even if those sides use neither fog nor shroud). For leveling units, sides that could see the unit before it leveled are excluded. (This is why these events are rare &ndash; the leveling unit must have lost a [hides] ability as a result of leveling in order to be seen after, but not before, leveling.) For movement, a sighted event is fired for each side that could see the unit after movement, but not before. In particular, only the starting and ending hexes are considered; a unit that moves through seen hexes but ends movement in a fogged hex does not trigger a sighted event for itself. In all cases where the acting unit is sighted, a (single) ''secondary unit'' is chosen from the sighting team. This choice should be considered arbitrary, but units within their sight range of the acting unit are chosen in preference to units further away. You may want to use [filter_second] in order to restrict a sighted event in a single player scenario to only being triggered by the player and not by other non-allied sides.<br />
<br />
Sighted events are not triggered by a ''hides'' ability becoming inactive, unless it becomes inactive due to that unit's movement or to that unit ambushing another. (To detect a ''nightstalk'' ability becoming inactive due to time of day, use a ''new_turn'' event. Custom ''hides'' abilities might need similar handling.)<br />
<br />
Sighted events have some special caveats for WML authors. First and foremost, {{tag|DirectActionsWML|allow_undo}} should generally be avoided in sighted events. It can be used if current unit positions have no bearing on the event, but otherwise it could cause a replay to go out of sync if a player delays shroud updates and undoes a move. This should not be an onerous restriction, though, as clearing fog will block the ability to undo, regardless of what happens within an event. Secondly, it is currently possible for WML to kill a unit involved in a sighted event before that event fires. If that happens, filters on the killed unit will not match anything and the event may seem to have not fired.<br />
<br />
===== enter_hex =====<br />
<br />
Triggers for each hex entered during movement, with $x1,$y1 identifying the hex entered and $x2,$y2 identifying the previous hex (just exited). In Wesnoth 1.12, the movement will be interrupted, stopping the unit where it is; this behavior can be avoided by using the {{tag|DirectActionsWML|allow_undo}} tag or `NO_INTERRUPT_NO_UNDO` macro. {{DevFeature1.13|11}} movement is not interrupted unless the {{tag|DirectActionsWML|cancel_action}} tag is used.<br />
<br />
'''Note:''' This event behaves a bit unusually if the hex is occupied (and the moving unit is simply passing through). When this happens, $x1,$y1 is still the hex where the event was triggered, but the moving unit (stored in $unit) will be located somewhere earlier in the route (the most recent unoccupied hex). That is, $x1,$y1 will not equal $unit.x,$unit.y (a condition that can be used to detect when the entered hex is occupied). The moving unit will have already spent its movement points to enter the event's hex even though it is has not actually moved from the most recent unoccupied hex.<br />
<br />
'''Note:''' At the time of writing (7ca5a0df, just before 1.13.11), if the hex is occupied then $unit contains the occupying unit, not the moving unit.<br />
<br />
===== exit_hex =====<br />
<br />
Triggers for each hex exited during movement, with $x1,$y1 identifying the hex exited and $x2,$y2 identifying the next hex (to be entered). If this event is handled without using {{tag|DirectActionsWML|allow_undo}}, then movement is interrupted, stopping the unit where it is. {{DevFeature1.13|11}} movement is not interrupted unless the {{tag|DirectActionsWML|cancel_action}} tag is used.<br />
<br />
'''Note:''' This event behaves a bit unusually if the hex is occupied (and the moving unit is simply passing through). When this happens, $x1,$y1 is still the hex where the event was triggered, but the moving unit (stored in $unit) will be located somewhere earlier in the route (the most recent unoccupied hex). That is, $x1,$y1 will not equal $unit.x,$unit.y (a condition that can be used to detect when the exited hex is occupied). The moving unit will have already spent its movement points to enter the event's hex even though it is has not actually moved from the most recent unoccupied hex.<br />
<br />
===== attack =====<br />
<br />
Triggers when the primary unit attacks the secondary unit. Variables $weapon and $second_weapon contain weapons used for this attack by primary and secondary units respectively for all attack-related events (attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, die and last_breath).<br />
<br />
===== attack end =====<br />
<br />
Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
===== attacker hits =====<br />
<br />
Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
===== attacker misses =====<br />
<br />
Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
===== defender hits =====<br />
<br />
Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
===== defender misses =====<br />
<br />
Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
===== petrified =====<br />
Triggers when the primary unit is hit by an attack with the 'petrifies' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'petrifies' ability).<br />
<br />
===== last breath =====<br />
<br />
Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
===== die =====<br />
<br />
Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
===== capture =====<br />
<br />
Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture. This event will be fired before the moveto event. Villages becoming neutral (via [capture_village]) do not fire capture events. The variable $owner_side contains the previous owner side of the village. 0 means neutral.<br />
<br />
===== recruit =====<br />
<br />
Triggers when the primary unit is recruited (by the secondary unit). (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
===== prerecruit =====<br />
<br />
Triggers when the primary unit is recruited (by the secondary unit) but before it is displayed.<br />
<br />
===== recall =====<br />
<br />
Triggers after the primary unit is recalled (by the secondary unit).<br />
<br />
===== prerecall =====<br />
<br />
Triggers when the primary unit is recalled (by the secondary unit) but before it is displayed.<br />
<br />
===== advance =====<br />
<br />
Triggers just before the primary unit is going to advance to another unit, or advance by AMLA. (This is after the player selects which advancement, if there is a choice). If this event removes the unit, changes the unit's type, or reduces the unit's experience below what it needs to advance, then the advancement is aborted. This also applies to advancement by AMLA.<br />
<br />
===== pre advance =====<br />
<br />
{{DevFeature1.13|0}} Triggers before the unit advancement dialog is shown. If this event removes the unit or reduces the unit's experience below what it needs to advance, then the advancement is aborted.<br />
<br />
===== post advance =====<br />
<br />
Triggers just after the primary unit has advanced to another unit, or advance by AMLA.<br />
<br />
===== select =====<br />
<br />
Triggers when the primary unit is selected. Prior to version 1.11, this also triggered when a move was interrupted, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
===== menu item ''X'' =====<br />
<br />
Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
===== unit placed {{DevFeature1.13|3}}=====<br />
<br />
Triggers when the primary unit is placed on the map, regardless of method. This includes but might not be limited to:<br />
* Leaders and units placed in side definitions (fired once for every unit right before prestart events)<br />
* Recruited and recalled units<br />
* Units placed on the map with the [unit] tag ('''not''' units created directly onto a recall list or variable)<br />
* Units placed by the wesnoth.put_unit() Lua function<br />
* Units created via debug mode<br />
* Units created by plague<br />
* Every use of [unstore_unit]<br />
* Units moved on map with [move_unit]<br />
This event is solely intended for special cases where no other event types suffice, for example if you must immediately apply a modification to every unit that ever appears. The event does '''not''' keep track of which units it has previously fired for, but can fire an unlimited number of times for the same unit as long the unit is "placed" several times and the event filter doesn't prevent it.<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives. Also, custom events come very handy in [[Wml_optimisation]].<br />
<br />
Example:<br />
<syntaxhighlight lang='wml'><br />
# The following is the definition of a custom event "unit recruited"<br />
[event]<br />
name=unit_recruited<br />
first_time_only=no<br />
[message]<br />
speaker=unit<br />
message=_ "Reporting for duty!"<br />
[/message]<br />
[/event]<br />
<br />
# This is a standard recruit event that triggers whenever a unit is recruited by side 1<br />
[event]<br />
name=recruit<br />
first_time_only=no<br />
[filter]<br />
[/filter]<br />
[filter_second]<br />
side=1<br />
[/filter_second]<br />
<br />
# And now a fire_event tag is used to trigger the previously defined event<br />
[fire_event]<br />
name=unit_recruited<br />
[/fire_event]<br />
<br />
# As a result, every time side 1 recruits a unit, this unit says "Reporting for duty!"<br />
[/event]<br />
</syntaxhighlight><br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== id ====<br />
: If an id is specified, then the event will not be added if another event with the same id already exists. An id will also allow the event to be removed, see below. Supplying a non-empty id= is mandatory in case of a [unit_type][event].<br />
<br />
==== remove ====<br />
: Whether to remove an event instead of adding a new one. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; if yes, then the contents of the event are ignored and the event with the specified id is removed instead. {{DevFeature1.13|0}} May be a comma separated list.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
id=id_of_event_to_remove<br />
remove=yes<br />
[/event]<br />
</syntaxhighlight><br />
<br />
<b>Note:</b> {{DevFeature1.13|0}} You can now use [[InternalActionsWML#.5Bremove_event.5D|[remove_event]]] instead (the [event] remove= syntax still works). It also accepts a comma separated list.<br />
<br />
<syntaxhighlight lang='wml'><br />
[remove_event]<br />
id=id_of_event_to_remove<br />
[/remove_event]<br />
</syntaxhighlight><br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria based on the weapon used by the primary unit. This is usable in the events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'', ''attack end'', ''last breath'', and ''die''. For more information and filter keys, see [[FilterWML#Filtering Weapons|Filtering Weapons]]. The most commonly used keys are the following.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the weapon used by the secondary unit.<br />
<br />
==== [filter_condition] ====<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* [[ConditionalActionsWML#Condition_Tags|Condition Tags]]<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== [filter_side] ====<br />
: The current side (usually the side $side_number) must match the passed [[StandardSideFilter]] for the event to fire.<br />
:* SSF tags and keys as arguments as described in [[StandardSideFilter]].<br />
: note: This tag makes most sense in side turn and turn refresh events. However, all wml events have a current side so one could also prevent e.g. a moveto event from firing if you put a [filter_side] tag there and the moving unit's side doesn't match.<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all [[ActionWML|action tags]] within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
More details in [[ActionWML]].<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* enter hex<br />
* exit hex<br />
* sighted<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance<br />
* pre advance<br />
* post advance <br />
* attack<br />
* attack end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* start<br />
* prestart (prestart are synced but [message][option] & [unstore_unit] advancement choices will do a random decision because UI things don't work during prestart events.)<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh<br />
* side turn end<br />
* side X turn end<br />
* side turn X end<br />
* side X turn Y end<br />
* turn end<br />
* turn X end<br />
* {{DevFeature1.13|0}} enemies defeated<br />
* {{DevFeature1.13|0}} time over<br />
* {{DevFeature1.13|10}} victory<br />
* {{DevFeature1.13|10}} defeat<br />
The following are <b>not</b> synced:<br />
* select<br />
* preload<br />
* victory {{DevFeature1.13|10}} local_victory<br />
* defeat {{DevFeature1.13|10}} local_defeat<br />
* ai turn<br />
<br />
If an event is not listed here, ask someone to be sure.<br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
<syntaxhighlight lang='wml'><br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
</syntaxhighlight><br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
=== Event IDs ===<br />
<br />
This problem can be avoided by setting an '''id''' on the event, i.e.:<br />
<br />
<syntaxhighlight lang='wml'><br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
id=doubler_event<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
</syntaxhighlight><br />
<br />
Events with the same ID will only be accepted once by the engine no matter how many times they are included, and will only be saved once to the scenario's savefile. Events with an ID can also be removed by using the '''remove''' key, i.e.:<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
id=doubler_event<br />
remove=yes<br />
[/event]<br />
</syntaxhighlight><br />
<br />
After that WML is encountered (at toplevel or after created from another event), the event with this ID is removed from the scenario wml, thus firing it has no effect. After an event is removed, it can still be re-added later.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event] # parent<br />
name=turn 2<br />
# delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event] # child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event] # great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number} # output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=EventWML&diff=59748EventWML2018-06-04T19:58:03Z<p>Vasya: /* unit placed {{DevFeature1.13|3}} */</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of [[ActionWML|actions]] which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
<syntaxhighlight lang='wml'><br />
name=<value><br />
</syntaxhighlight><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
<syntaxhighlight lang='wml'><br />
name=attacker misses,defender misses<br />
</syntaxhighlight><br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. <br />
<br />
Spaces in event names can be interchanged with ''underscores'' (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
==== Predefined Events Without Filters ====<br />
<br />
These events do not take filter parameters (except [filter_condition] which works for all events).<br />
<br />
===== preload =====<br />
<br />
Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
<br />
'''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
===== prestart =====<br />
<br />
Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
<br />
'''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
===== start =====<br />
<br />
Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
<br />
'''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
===== new turn =====<br />
<br />
Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
===== turn end =====<br />
<br />
Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
===== turn ''X'' end =====<br />
<br />
Triggers at the end of turn ''X''.<br />
<br />
===== side turn =====<br />
<br />
Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
===== ai turn =====<br />
<br />
Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
<br />
'''Note:''' ''This event can break replays if it is used improperly. The ai turn event does not fire during replays. The intention is only to guide the AI to make choices (movements, attacks) which are then saved to the replay.''<br />
<br />
===== turn refresh =====<br />
<br />
Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status. WML variable '''side_number''' holds the number of this side.<br />
<br />
Note that the turn refresh event does occur on turn 1, even though healing, income and unit refreshing do not.<br />
<br />
===== turn ''X'' =====<br />
<br />
Triggers at the start of turn ''X''. It's the first side initialization event. <br />
<br />
Side initialization events go in the order of: <br />
<br />
# '''turn ''X''''' <br />
# '''new turn''' <br />
# '''side turn''' <br />
# '''side ''X'' turn''' <br />
# '''side turn ''X''''' <br />
# '''side ''X'' turn ''Y''''' <br />
# '''turn refresh''' <br />
# '''side ''X'' turn refresh''' <br />
# '''turn ''X'' refresh''' <br />
# '''side ''X'' turn ''Y'' refresh'''<br />
<br />
===== side ''X'' turn ''Y'' =====<br />
<br />
This event triggers at the start of turn ''Y'' of side X <br />
<br />
===== side ''X'' turn =====<br />
<br />
This event triggers at the start of any turn of side X<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== side turn ''X'' =====<br />
<br />
This event triggers at the start of any side on turn X<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== side X turn Y refresh =====<br />
<br />
This event triggers at the turn refresh for side X on turn Y<br />
<br />
===== side ''X'' turn refresh =====<br />
<br />
This event triggers at the turn refresh for side X<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== turn ''X'' refresh =====<br />
<br />
This event triggers for any side at the refresh of turn X.<br />
<br />
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
===== side turn end =====<br />
<br />
Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
<br />
# '''side turn end''' <br />
# '''side ''X'' turn end''' <br />
# '''side turn ''X'' end''' <br />
# '''side ''X'' turn ''Y'' end''' <br />
# '''turn end''' <br />
# '''turn ''X'' end''' <br />
<br />
===== time over =====<br />
<br />
Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
===== enemies defeated =====<br />
<br />
Triggers when all sides that are not defeated are allied and if there is at least one human (or human networked) side among them. Especially this event triggers in a situaltion that would normaly cause a victory due to enemies defeated. (regardless of whether this was disabled with victory_when_enemies_defeated=no). <br />
<br />
===== victory =====<br />
<br />
In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]]). This event is not synchonized in networked mp or in replays. The reason is that it is possible to have diffrent results in a mp game (one player wins so a '''victory''' event is fired on that client, other player loses so a '''defeat''' event is fired on his client)<br />
<br />
===== defeat =====<br />
<br />
In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]]). Like '''victory''', this event is not synchonized in networked mp or in replays.<br />
<br />
==== Predefined Events With Filters ====<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables '''unit''' and '''second_unit''' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]. weapon and second_weapon variables are available inside attack, attacker_hits, defender_hits, die and last_breath events. See [[VariablesWML#Automatically_Stored_Variables|automatically stored variables]] for more information.<br />
<br />
===== moveto =====<br />
<br />
Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on. If the unit moves to a village, the capture event will be fired before this event. <br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' $x2 and $y2 refer to the hex the unit came from.<br />
<br />
===== sighted =====<br />
<br />
A '''sighted''' event is triggered by a unit becoming visible to a side (other than the unit's own side). This is mostly useful when the side seeing the unit uses [[fog of war]] or [[shroud]], but they still fire even when fog/shroud is not in use, and they do take into account the {{tag2|AbilitiesWML#The_.5Babilities.5D_tag|hides}} ability (for a moving unit and for ambushers). The ''primary unit'' is the unit that became visible, and the ''secondary unit'' belongs to the side that now sees the primary unit. In some cases, sighted events can be delayed from when they "should" occur. If that happens, the secondary unit will be filtered as if it was at the location where the event "should" have occurred, and ''x2,y2'' will store that location (not the current position of the secondary unit). To understand when sighted events fire, it is helpful to distinguish the times the acting unit sights other units from the times when the acting unit is sighted.<br />
<br />
An acting unit can sight other units when it is recruited, recalled, leveled, or moved, and when fog or shroud is cleared from occupied hexes as a result. In these cases, the acting unit is always the ''secondary unit''. For the first three actions, there are two events associated with the action; clearing occurs between these events, but any sighted events are fired after the second event. (For example, when a unit is recruited, the ''prerecruit'' event fires, then fog is cleared, then the ''recruit'' event fires, then ''sighted'' events fire.) For movement, the sighted events fire between ''enter_hex'' and ''exit_hex'' events, but sometimes sighted events are postponed until the moving unit reaches a good place to stop (e.g. not in an occupied hex). As a major exception to the above, players have the option to delay shroud (and fog) updates. If the player delays shroud updates, sighted events are also delayed until the shroud is updated.<br />
<br />
An acting unit can be sighted by other sides when it is recruited, recalled, leveled (in rare cases), or moved. In these cases, the acting unit is always the ''primary unit''. These events fire after sightings by the acting unit (unless the player delayed shroud updates). For the first two, the sighted event fires for all sides that can see the unit, other than the unit's own side (even if those sides use neither fog nor shroud). For leveling units, sides that could see the unit before it leveled are excluded. (This is why these events are rare &ndash; the leveling unit must have lost a [hides] ability as a result of leveling in order to be seen after, but not before, leveling.) For movement, a sighted event is fired for each side that could see the unit after movement, but not before. In particular, only the starting and ending hexes are considered; a unit that moves through seen hexes but ends movement in a fogged hex does not trigger a sighted event for itself. In all cases where the acting unit is sighted, a (single) ''secondary unit'' is chosen from the sighting team. This choice should be considered arbitrary, but units within their sight range of the acting unit are chosen in preference to units further away. You may want to use [filter_second] in order to restrict a sighted event in a single player scenario to only being triggered by the player and not by other non-allied sides.<br />
<br />
Sighted events are not triggered by a ''hides'' ability becoming inactive, unless it becomes inactive due to that unit's movement or to that unit ambushing another. (To detect a ''nightstalk'' ability becoming inactive due to time of day, use a ''new_turn'' event. Custom ''hides'' abilities might need similar handling.)<br />
<br />
Sighted events have some special caveats for WML authors. First and foremost, {{tag|DirectActionsWML|allow_undo}} should generally be avoided in sighted events. It can be used if current unit positions have no bearing on the event, but otherwise it could cause a replay to go out of sync if a player delays shroud updates and undoes a move. This should not be an onerous restriction, though, as clearing fog will block the ability to undo, regardless of what happens within an event. Secondly, it is currently possible for WML to kill a unit involved in a sighted event before that event fires. If that happens, filters on the killed unit will not match anything and the event may seem to have not fired.<br />
<br />
===== enter_hex =====<br />
<br />
Triggers for each hex entered during movement, with $x1,$y1 identifying the hex entered and $x2,$y2 identifying the previous hex (just exited). In Wesnoth 1.12, the movement will be interrupted, stopping the unit where it is; this behavior can be avoided by using the {{tag|DirectActionsWML|allow_undo}} tag or `NO_INTERRUPT_NO_UNDO` macro. {{DevFeature1.13|11}} movement is not interrupted unless the {{tag|DirectActionsWML|cancel_action}} tag is used.<br />
<br />
'''Note:''' This event behaves a bit unusually if the hex is occupied (and the moving unit is simply passing through). When this happens, $x1,$y1 is still the hex where the event was triggered, but the moving unit (stored in $unit) will be located somewhere earlier in the route (the most recent unoccupied hex). That is, $x1,$y1 will not equal $unit.x,$unit.y (a condition that can be used to detect when the entered hex is occupied). The moving unit will have already spent its movement points to enter the event's hex even though it is has not actually moved from the most recent unoccupied hex.<br />
<br />
'''Note:''' At the time of writing (7ca5a0df, just before 1.13.11), if the hex is occupied then $unit contains the occupying unit, not the moving unit.<br />
<br />
===== exit_hex =====<br />
<br />
Triggers for each hex exited during movement, with $x1,$y1 identifying the hex exited and $x2,$y2 identifying the next hex (to be entered). If this event is handled without using {{tag|DirectActionsWML|allow_undo}}, then movement is interrupted, stopping the unit where it is. {{DevFeature1.13|11}} movement is not interrupted unless the {{tag|DirectActionsWML|cancel_action}} tag is used.<br />
<br />
'''Note:''' This event behaves a bit unusually if the hex is occupied (and the moving unit is simply passing through). When this happens, $x1,$y1 is still the hex where the event was triggered, but the moving unit (stored in $unit) will be located somewhere earlier in the route (the most recent unoccupied hex). That is, $x1,$y1 will not equal $unit.x,$unit.y (a condition that can be used to detect when the exited hex is occupied). The moving unit will have already spent its movement points to enter the event's hex even though it is has not actually moved from the most recent unoccupied hex.<br />
<br />
===== attack =====<br />
<br />
Triggers when the primary unit attacks the secondary unit. Variables $weapon and $second_weapon contain weapons used for this attack by primary and secondary units respectively for all attack-related events (attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, die and last_breath).<br />
<br />
===== attack end =====<br />
<br />
Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
===== attacker hits =====<br />
<br />
Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
===== attacker misses =====<br />
<br />
Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
===== defender hits =====<br />
<br />
Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
===== defender misses =====<br />
<br />
Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
===== petrified =====<br />
Triggers when the primary unit is hit by an attack with the 'petrifies' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'petrifies' ability).<br />
<br />
===== last breath =====<br />
<br />
Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
===== die =====<br />
<br />
Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
===== capture =====<br />
<br />
Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture. This event will be fired before the moveto event. Villages becoming neutral (via [capture_village]) do not fire capture events. The variable $owner_side contains the previous owner side of the village. 0 means neutral.<br />
<br />
===== recruit =====<br />
<br />
Triggers when the primary unit is recruited (by the secondary unit). (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
===== prerecruit =====<br />
<br />
Triggers when the primary unit is recruited (by the secondary unit) but before it is displayed.<br />
<br />
===== recall =====<br />
<br />
Triggers after the primary unit is recalled (by the secondary unit).<br />
<br />
===== prerecall =====<br />
<br />
Triggers when the primary unit is recalled (by the secondary unit) but before it is displayed.<br />
<br />
===== advance =====<br />
<br />
Triggers just before the primary unit is going to advance to another unit, or advance by AMLA. (This is after the player selects which advancement, if there is a choice). If this event removes the unit, changes the unit's type, or reduces the unit's experience below what it needs to advance, then the advancement is aborted. This also applies to advancement by AMLA.<br />
<br />
===== pre advance =====<br />
<br />
{{DevFeature1.13|0}} Triggers before the unit advancement dialog is shown. If this event removes the unit or reduces the unit's experience below what it needs to advance, then the advancement is aborted.<br />
<br />
===== post advance =====<br />
<br />
Triggers just after the primary unit has advanced to another unit, or advance by AMLA.<br />
<br />
===== select =====<br />
<br />
Triggers when the primary unit is selected. Prior to version 1.11, this also triggered when a move was interrupted, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
===== menu item ''X'' =====<br />
<br />
Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
===== unit placed {{DevFeature1.13|3}}=====<br />
<br />
Triggers when the primary unit is placed on the map, regardless of method. This includes but might not be limited to:<br />
* Leaders and units placed in side definitions (fired once for every unit right before prestart events)<br />
* Recruited and recalled units<br />
* Units placed on the map with the [unit] tag ('''not''' units created directly onto a recall list or variable)<br />
* Units placed by the wesnoth.put_unit() Lua function<br />
* Units created via debug mode<br />
* Units created by plague<br />
* Every use of [unstore_unit]<br />
* Units moved on map ([move_unit] and similar)<br />
This event is solely intended for special cases where no other event types suffice, for example if you must immediately apply a modification to every unit that ever appears. The event does '''not''' keep track of which units it has previously fired for, but can fire an unlimited number of times for the same unit as long the unit is "placed" several times and the event filter doesn't prevent it.<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives. Also, custom events come very handy in [[Wml_optimisation]].<br />
<br />
Example:<br />
<syntaxhighlight lang='wml'><br />
# The following is the definition of a custom event "unit recruited"<br />
[event]<br />
name=unit_recruited<br />
first_time_only=no<br />
[message]<br />
speaker=unit<br />
message=_ "Reporting for duty!"<br />
[/message]<br />
[/event]<br />
<br />
# This is a standard recruit event that triggers whenever a unit is recruited by side 1<br />
[event]<br />
name=recruit<br />
first_time_only=no<br />
[filter]<br />
[/filter]<br />
[filter_second]<br />
side=1<br />
[/filter_second]<br />
<br />
# And now a fire_event tag is used to trigger the previously defined event<br />
[fire_event]<br />
name=unit_recruited<br />
[/fire_event]<br />
<br />
# As a result, every time side 1 recruits a unit, this unit says "Reporting for duty!"<br />
[/event]<br />
</syntaxhighlight><br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== id ====<br />
: If an id is specified, then the event will not be added if another event with the same id already exists. An id will also allow the event to be removed, see below. Supplying a non-empty id= is mandatory in case of a [unit_type][event].<br />
<br />
==== remove ====<br />
: Whether to remove an event instead of adding a new one. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; if yes, then the contents of the event are ignored and the event with the specified id is removed instead. {{DevFeature1.13|0}} May be a comma separated list.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
id=id_of_event_to_remove<br />
remove=yes<br />
[/event]<br />
</syntaxhighlight><br />
<br />
<b>Note:</b> {{DevFeature1.13|0}} You can now use [[InternalActionsWML#.5Bremove_event.5D|[remove_event]]] instead (the [event] remove= syntax still works). It also accepts a comma separated list.<br />
<br />
<syntaxhighlight lang='wml'><br />
[remove_event]<br />
id=id_of_event_to_remove<br />
[/remove_event]<br />
</syntaxhighlight><br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria based on the weapon used by the primary unit. This is usable in the events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'', ''attack end'', ''last breath'', and ''die''. For more information and filter keys, see [[FilterWML#Filtering Weapons|Filtering Weapons]]. The most commonly used keys are the following.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the weapon used by the secondary unit.<br />
<br />
==== [filter_condition] ====<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* [[ConditionalActionsWML#Condition_Tags|Condition Tags]]<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== [filter_side] ====<br />
: The current side (usually the side $side_number) must match the passed [[StandardSideFilter]] for the event to fire.<br />
:* SSF tags and keys as arguments as described in [[StandardSideFilter]].<br />
: note: This tag makes most sense in side turn and turn refresh events. However, all wml events have a current side so one could also prevent e.g. a moveto event from firing if you put a [filter_side] tag there and the moving unit's side doesn't match.<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all [[ActionWML|action tags]] within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
More details in [[ActionWML]].<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* enter hex<br />
* exit hex<br />
* sighted<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance<br />
* pre advance<br />
* post advance <br />
* attack<br />
* attack end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* start<br />
* prestart (prestart are synced but [message][option] & [unstore_unit] advancement choices will do a random decision because UI things don't work during prestart events.)<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh<br />
* side turn end<br />
* side X turn end<br />
* side turn X end<br />
* side X turn Y end<br />
* turn end<br />
* turn X end<br />
* {{DevFeature1.13|0}} enemies defeated<br />
* {{DevFeature1.13|0}} time over<br />
* {{DevFeature1.13|10}} victory<br />
* {{DevFeature1.13|10}} defeat<br />
The following are <b>not</b> synced:<br />
* select<br />
* preload<br />
* victory {{DevFeature1.13|10}} local_victory<br />
* defeat {{DevFeature1.13|10}} local_defeat<br />
* ai turn<br />
<br />
If an event is not listed here, ask someone to be sure.<br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
<syntaxhighlight lang='wml'><br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
</syntaxhighlight><br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
=== Event IDs ===<br />
<br />
This problem can be avoided by setting an '''id''' on the event, i.e.:<br />
<br />
<syntaxhighlight lang='wml'><br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
id=doubler_event<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
</syntaxhighlight><br />
<br />
Events with the same ID will only be accepted once by the engine no matter how many times they are included, and will only be saved once to the scenario's savefile. Events with an ID can also be removed by using the '''remove''' key, i.e.:<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
id=doubler_event<br />
remove=yes<br />
[/event]<br />
</syntaxhighlight><br />
<br />
After that WML is encountered (at toplevel or after created from another event), the event with this ID is removed from the scenario wml, thus firing it has no effect. After an event is removed, it can still be re-added later.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event] # parent<br />
name=turn 2<br />
# delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event] # child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event] # great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number} # output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=ScenarioWML&diff=59458ScenarioWML2018-04-19T08:14:58Z<p>Vasya: /* The [multiplayer] tag */</p>
<hr />
<div>{{WML Tags}}<br />
== the toplevel tags [multiplayer], [test], [tutorial], [scenario] ==<br />
<br />
The top level tags '''[multiplayer]''', '''[test]''', '''[tutorial]''' and '''[scenario]''' are all formatted the same way.<br />
The difference between these tags is the way that the scenarios they describe are accessed.<br />
<br />
The keys '''id''' and '''next_scenario''' affect how scenarios can be accessed.<br />
Whenever a scenario is won, the scenario with id=''next_scenario'' of the same tag type will be played.<br />
Units from the first scenario will be available for recall in the second.<br />
<br />
Some scenarios can be played without playing other scenarios first<br />
(in this case there is nothing on the recall list).<br />
These scenarios are called ''initial scenario''s.<br />
<br />
A list of initial scenarios, and how to access them:<br />
<br />
* All '''[multiplayer]''' scenarios (without ''allow_new_game=no'') are initial scenarios listed in the multiplayer scenario selector screen (accessed by the "multiplayer" button).<br />
<br />
* Any '''[test]''' scenario is an initial scenario. A test scenario can be accessed by running the game in test mode. (note: this is NOT the same as debug mode. It can be accessed using -t or --test followed by an optional scenario ID which defaults to 'test'.) {{DevFeature1.13|8}} It can also be accessed by assigning a hotkey to the "Test Scenario" command in hotkey preferences, then pressing that hotkey at the title screen. This will bring up a list of interactive test scenarios to choose from. (Automated test scenarios used for unit testing are excluded from this list but can still be run from the command-line.)<br />
<br />
* The '''[tutorial]''' scenario with the attribute '''id=tutorial''' is an initial scenario. The tutorial is accessed by clicking on the "tutorial" button.<br />
<br />
* Any '''[scenario]''' scenario with an id listed in the value of ''first_scenario'' in a campaign tag (see [[CampaignWML]]) is an initial scenario accessed by selecting that campaign after clicking on the "campaign" button.<br />
<br />
== The [scenario] tag ==<br />
<br />
The following keys and tags are recognized in '''[scenario]''' tags:<br />
<br />
* '''id''': A unique identifier for this scenario. All scenarios must have an id. Can't clash with '''id''' used in '''[multiplayer]''' tags.<br />
<br />
* '''next_scenario''': The id of the scenario to load when the current one is won. This can be changed dynamically, to build non-linear campaigns.<br />
<br />
* '''description''': (translatable) only for multiplayer maps. Will show up as a tooltip when mousing over the minimap in the multiplayer setup screen.<br />
<br />
* '''name''': (translatable) is shown in several places in the level, including the intro screen. It is also the default name for saves on the level.<br />
<br />
* '''map_data''': inputs valid Wesnoth map data. See [[BuildingMaps]] for a description of the Wesnoth map syntax.<br />
<br />
* '''turns''': sets an event on turn ''turns'' causing the player to lose. Use ''-1'' to have no turn limit. Default value is ''-1'' on wesnoth-1.13 and ''100'' on wesnoth-1.12. See also [[EventWML]]<br />
<br />
* '''turn_at''': the turn to start on (default=1)<br />
<br />
: Note that none of the regular start-of-turn behavior, including poison damage, healing, income and refreshing unit movement and status, will occur before the start of turn 2. All start-of-turn [[EventWML|WML events]] will still be fired, however.<br />
<br />
* '''random_start_time''': controls random starting time of day. Possible values are yes and no or list of possible start times; starting from 1 to number of times. for example ''random_start_time=2,3,5,6'' (default depends on version and mp/sp, better include this key)<br />
<br />
* '''music''': the music file relative to ''./music/'' to play during the scenario<br />
<br />
* '''[music]''': specifies the music tracks to play during this scenario, see [[MusicListWML]].<br />
<br />
* '''defeat_music''': specifies a comma-separated list of music tracks which may be chosen to play on defeat. If not provided, the default in [[GameConfigWML]] is used instead. May be overridden by [[DirectActionsWML|endlevel]] clauses.<br />
<br />
* '''victory_music''': specifies a comma-separated list of music tracks which may be chosen to play on victory. If not provided, the default in [[GameConfigWML]] is used instead. May be overridden by [[DirectActionsWML|endlevel]] clauses.<br />
<br />
* '''theme''': the name of the UI theme that should be used when playing this scenario. Valid ids to use can be found in the files in data/themes. Cutscene and Cutscene_Minimal can be useful for dialog only scenarios.<br />
<br />
* '''victory_when_enemies_defeated''': when this is set to '''yes''' (default), the player wins once all non-allied units with '''canrecruit=yes''' (aka leaders) are killed. (Currently this only controls the win condition for when all enemies are defeated; it does not prevent the player from losing if he has no leader.) See Also [[SideWML]]. When this value is true the following keys can be used:<br />
** '''carryover_percentage''': by default 80% of the gold is carried over to the next scenario, with this key the amount can be changed.<br />
** '''carryover_add''': if true the gold will be added to the starting gold the next scenario, if false the next scenario will start with the amount of the current scenario (after taxes) or the minimum in the next scenario. Default is false.<br />
<br />
* '''remove_from_carryover_on_defeat''': when this is set to '''yes''' (default), for sides who got defeated (according to the side.defeat_condition), carryover will be removed.<br />
<br />
* '''disallow_recall''': when this is set to 'no'(default), the player is allowed to recall units from previous scenarios.<br />
<br />
* '''experience_modifier''': the percentage that required XP to level up (for all units in the scenario) is multiplied by. Default 100. Note that when used in a campaign, weird things (like units being above the required XP to level up) can happen if this value is different for different scenarios.<br />
<br />
* '''[story]''': describes the intro screen. See [[IntroWML]]<br />
<br />
* '''[label]''': sets a label<br />
** '''x''', '''y''': location to set label<br />
** '''text''': the label<br />
<br />
* '''[item]''': places an item on map. See [[InterfaceActionsWML#.5Bitem.5D|InterfaceActionsWML]].<br />
<br />
* '''[time]''': how a day should progress. See [[TimeWML]]<br />
<br />
* '''current_time''': The time of day slot number (starting from zero) active at scenario start.<br />
<br />
* '''[time_area]''': how a day should progress in a given area. Everywhere not specified in a [time_area] tag is affected by the [time] tags in the [scenario] tag<br />
** takes x and y coordinates.<br />
** '''[time]''': how a day should progress in those locations. See [[TimeWML]]<br />
** '''current_time''': The time slot number (starting with zero) active at the creation of the area.<br />
** time areas can be used in events, assigned identifiers, and removed at discretion. They also accept complete Standard Location Filters. See [[DirectActionsWML]].<br />
<br />
* '''[side]''': describes one player. See [[SideWML]]<br />
<br />
* '''[event]''': describes an event that may be triggered at a certain point of the scenario. See [[EventWML]]<br />
<br />
* '''map_generation''': another way to generate a map. The map will be generated randomly<br />
** '''default''': the default random map generator<br />
<br />
* '''[generator]''' if this is present, the map and scenario will be generated randomly. See [[MapGeneratorWML]]<br />
<br />
== The [multiplayer] tag ==<br />
<br />
The following keys and subtags are additionally recognized in '''[multiplayer]''' scenarios:<br />
<br />
* '''force_lock_settings''': provides a default value for [[SideWML]] ''lock'' attributes and forces the "Use map settings" to be checked and disabled. This is useful if author wants to limit game customization in order to keep the scenario/campaign balanced. Individual options can still be enabled if this key is set to '''yes'''. E.g. color selection can be enabled by explicitly setting ''color_lock=yes'' in [[SideWML]].<br />
* '''new_game_title''': if provided will be used instead of '''name''' for campaign entry points.<br />
* '''allow_new_game''': (default=yes) allow/prevent the scenario to be listed in the game configuration screen. This is intended for multiplayer campaigns with multiple entry points.<br />
* '''allow_era''': a list of era ids. Only the eras with matching ids will be allowed to be played with this scenario.<br />
* '''disallow_era''': a list of era ids. Eras with matching ids will not be allowed to be played with this scenario. Cannot be used in parallel with allow_era.<br />
* '''ignore_incompatible_era''': a list of era ids. The eras with matching ids will be considered compatible with this scenario regardless their dependencies.<br />
* '''allow_modification''': same as allow_era, but for modifications.<br />
* '''disallow_modification''': same as disallow_era, but for modifications. Cannot be used in parallel with allow_modification.<br />
* '''ignore_incompatible_modification''': same as ignore_incompatible_era, but for modifications.<br />
* '''force_modification''': a list of modification ids (id key in [modification]). The specified modifications must be enabled to play this scenario.<br />
* '''[options]''': custom options. See [[OptionWML]] for details.<br />
* '''require_scenario''': {{DevFeature1.13|0}} In a multiplayer scenario, this indicates that the scenario file is not enough (you have custom assets like terrain or additional unit art) and other player must download the full add-on not just the scenario WML to join a game. This will also mean that the '''addon_min_version''' attribute will control the minimum version number of your add-on which is compatible with this version.<br />
<br />
== The [test] tag ==<br />
<br />
The following keys and subtags are additionally recognized in '''[test]''' scenarios:<br />
<br />
* '''is_unit_test''': {{DevFeature1.13|8}} If set to 'yes', this scenario will not appear in the list of test scenarios. The list of test scenarios can be reached from the titlescreen via the Start Test Scenario hotkey. This hotkey is not set by default.<br />
<br />
== Scenario End Conditions ==<br />
<br />
In this section we will give a more precise explanation of things that can cause a scenario to end.<br />
<br />
* At the '''end of every turn''', the turn number will be compared with the turn limit. <br />
** If we pass the limit, the ''time over'' event will fire. If turns are not added by WML in response to this event, then the scenario will immediately end in defeat. [[EventWML#The_.27name.27_Key_.28Mandatory.29]]<br />
* At the '''beginning of any turn''', and at '''the end of any user or ai action''', the victory conditions will be checked. This will result either in the scenario ending or continuing. The procedure for this is as follows:<br />
** Every side will have its ''defeat_condition'' evaluated based on the units it currently has on the board. [[SideWML]]<br />
*** At this time, villages of defeated sides will be unflagged, and if ''remove_from_carryover_on_defeat = yes'' then their carryover will be cleared as well.<br />
** If any two not-defeated sides are enemies, the scenario will continue.<br />
*** At this time, the ''enemies defeated'' event will fire.<br />
** Furthermore, if ''victory_when_enemies_defeated=no'' and there exists a human controlled side, then the scenario will continue.<br />
*** The human controlled side may be local or remote, for networked mp play.<br />
** If neither of these conditions is met then the scenario will end. <br />
***In victory or defeat according to whether a local human-controlled side is not defeated.<br />
<br />
== See Also ==<br />
<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Units&diff=59372LuaWML/Units2018-04-07T19:11:07Z<p>Vasya: add wesnoth.remove_modification method</p>
<hr />
<div>This page describes the [[LuaWML]] functions for handling units.<br />
<br />
A unit is a proxy table with the following fields:<br />
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map)<br />
* '''side''': integer (read/write)<br />
* '''id''': string (read only)<br />
* '''type''': string (read only)<br />
* '''name''': translatable string (read only)<br />
* '''cost''' {{DevFeature1.13|10}}: integer (read)<br />
* '''max_hitpoints''', '''experience''', '''max_experience''', '''max_moves''': integers (read only)<br />
* '''max_attacks''': integer (read only)<br />
* '''attacks_left''': integer (read/write) Setting below 0 is limited to 0.<br />
* '''extra_recruit''': table (read/write)<br />
* '''advances_to''': table (read/write)<br />
* '''hitpoints''', '''experience''': integer (read/write)<br />
* '''moves''': integer (read/write)<br />
* '''level''': {{DevFeature1.13|5}} integer (read/write)<br />
* '''resting''': boolean (read/write)<br />
* '''hidden''': boolean (read/write)<br />
* '''petrified''', '''canrecruit''': booleans (read only)<br />
* '''role''', '''facing''': strings (read/write)<br />
* '''status''': proxy associative table (read only, read/write fields), provides fields like [[SingleUnitWML#Unit_State|poisoned, slowed, petrified, uncovered, guardian, unhealable, invulnerable]]<br />
* '''image_mods''': string (read only)<br />
* '''upkeep''' {{DevFeature1.13|5}}: one of 'loyal', 'full' or a number (read/writre)<br />
* '''variables''': proxy associative table (read only, read/write fields, including ''variables.__cfg''), only toplevel named fields are proxied. {{DevFeature1.13|2}} subcontainers can be accessed by using the usual variable syntax: <syntaxhighlight inline lang='lua'>unit.variables["a.b.c[6].d"]</syntaxhighlight><br />
* '''attacks''': {{DevFeature1.13|0}}an object to access the units attacks, you can use the attacks index or the attacks name to index an attack. every attack has the following members:<br />
** '''description''': translatable string (read/write)<br />
** '''name''': string (read)<br />
** '''type''': string (read/write)<br />
** '''range''': string (read/write)<br />
** '''damage''': number(read/write)<br />
** '''number''': number(read/write)<br />
** '''movement_used''': number(read/write)<br />
** '''attack_weight''': number(read/write)<br />
** '''defense_weight''': number(read/write)<br />
** '''specials''' wml table(read/write)<br />
* '''valid''': string or nil (read only)<br />
* '''advancements''': {{DevFeature1.13|2}} an array of wml tables (read/write)<br />
* '''__cfg''': WML table (dump) ([[SingleUnitWML]])<br />
* {{DevFeature1.13|2}} The following fields are unit methods synonymous to one of the functions described on this page:<br />
** '''[[#wesnoth.match_unit|matches]]'''<br />
** '''[[#wesnoth.put_recall_unit|to_recall]]'''<br />
** '''[[#wesnoth.put_unit|to_map]]'''<br />
** '''[[#wesnoth.erase_unit|erase]]'''<br />
** '''[[#wesnoth.copy_unit|clone]]'''<br />
** '''[[#wesnoth.extract_unit|extract]]'''<br />
** '''[[#wesnoth.advance_unit|advance]]'''<br />
** '''[[#wesnoth.add_modification|add_modification]]'''<br />
** '''[[#wesnoth.remove_modification|remove_modification]]'''<br />
** '''[[#wesnoth.unit_resistance|resistance]]'''<br />
** '''[[#wesnoth.unit_defense|defense]]'''<br />
** '''[[#wesnoth.unit_movement_cost|movement]]'''<br />
** '''[[#wesnoth.unit_vision_cost|vision]]'''<br />
** '''[[#wesnoth.unit_jamming_cost|jamming]]'''<br />
** '''[[#wesnoth.unit_ability|ability]]'''<br />
** '''[[#wesnoth.transform_unit|transform]]'''<br />
The metatable of these proxy tables appears as '''"unit"'''.<br />
<br />
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same "underlying_id" WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''"map"''', '''"recall"''', '''"private"''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.<br />
<br />
The term "proxy", here in particular "proxy unit", means that the variable retrieved in the lua code (with get_units for example) is an accessor (reference) to the C++ object which represents that unit. This is very different from unit variables obtained by [store_unit] in wml. The fields marked as "writable" above can be modified without the need to use put_unit afterwards. This same reason explains that modifications to the unit from outside the lua code (like [kill] invalidating the proxy unit) have immediate effect on the lua code's proxy unit variable (with the exception of private proxy units).<br />
<br />
<br />
==== wesnoth.get_units ====<br />
<br />
* '''wesnoth.get_units(''filter'')'''<br />
<br />
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters.<br />
<br />
local leaders_on_side_two = wesnoth.get_units { side = 2, canrecruit = true }<br />
local name_of_leader = leaders_on_side_two[1].name<br />
<br />
==== wesnoth.get_unit ====<br />
<br />
* '''wesnoth.get_unit(''x'', ''y'')'''<br />
* '''wesnoth.get_unit(''underlying_id'')'''<br />
<br />
Returns the unit at the given location or with the given underlying ID.<br />
<br />
local args = ...<br />
local unit = wesnoth.get_unit(args.x1, args.y1)<br />
<br />
==== wesnoth.match_unit ====<br />
<br />
* '''wesnoth.match_unit(''unit'', ''filter'')'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''other_unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''other_unit''])'''<br />
* {{DevFeature1.13|2}} '''wesnoth.match_unit(''unit'', ''filter'', ''location'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':matches(''filter'', [''location''])'''<br />
<br />
Returns true if the given unit matches the WML filter passed as the second argument. If ''other_unit'' is specified, it is used for the ''$other_unit'' auto-stored variable in the filter. Otherwise, this variable is not stored for the filter. If an extra ''location'' is specified, the filter matches as if the unit were at that location.<br />
<br />
assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))<br />
<br />
==== wesnoth.put_unit ====<br />
<br />
* '''wesnoth.put_unit(''unit'')'''<br />
* '''wesnoth.put_unit(''x'', ''y'', ''unit'')'''<br />
* '''wesnoth.put_unit(''x'', ''y'')'''<br />
* {{DevFeature1.13|2}} '''wesnoth.put_unit(''unit'', ''x'', ''y'')''' -- The above two forms are also deprecated.<br />
* {{DevFeature1.13|2}} '''''unit'':to_map([''x'', ''y''])<br />
<br />
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead. {{DevFeature1.13|2}} This use is now deprecated; use wesnoth.erase_unit instead.<br />
<br />
-- create a unit with random traits, then erase it<br />
wesnoth.put_unit(17, 42, { type = "Elvish Lady" })<br />
wesnoth.put_unit(17, 42)<br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.<br />
<br />
-- move the leader back to the top-left corner<br />
wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])<br />
<br />
==== wesnoth.erase_unit ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
* '''wesnoth.erase_unit(''unit'')'''<br />
* '''wesnoth.erase_unit(''x'', ''y'')'''<br />
* '''''unit'':erase()'''<br />
<br />
Erases a unit from the map. After calling this on a unit, the unit is no longer valid.<br />
<br />
==== wesnoth.get_recall_units ====<br />
<br />
* '''wesnoth.get_recall_units()'''<br />
<br />
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.<br />
<br />
==== wesnoth.put_recall_unit ====<br />
<br />
* '''wesnoth.put_recall_unit(''unit'', [''side''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':to_recall([''side''])'''<br />
<br />
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.<br />
<br />
-- put the unit at location 17,42 on the recall list for side 2<br />
wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)<br />
<br />
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.<br />
<br />
==== wesnoth.create_unit ====<br />
<br />
* '''wesnoth.create_unit(''unit_info'')'''<br />
<br />
Creates a private unit from a WML table.<br />
<br />
local u = wesnoth.create_unit { type = "White Mage", gender = "female" }<br />
<br />
==== wesnoth.copy_unit ====<br />
<br />
* '''wesnoth.copy_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':clone()'''<br />
<br />
Creates a private unit from another unit.<br />
<br />
-- extract a unit from the map<br />
local u = wesnoth.copy_unit(wesnoth.get_units({ type = "Thug" })[1])<br />
wesnoth.put_unit(u.x, u.y)<br />
-- u is still valid at this point<br />
<br />
==== wesnoth.extract_unit ====<br />
<br />
* '''wesnoth.extract_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':extract()'''<br />
<br />
Removes a unit from the map or from a recall list and makes it private.<br />
<br />
-- remove all the units from the recall list of side 1 and put them in a WML container<br />
local l = {}<br />
for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do<br />
wesnoth.extract_unit(u)<br />
table.insert(l, u.__cfg)<br />
end<br />
helper.set_variable_array("player_recall_list", l)<br />
<br />
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.<br />
<br />
<br />
==== wesnoth.advance_unit ====<br />
<br />
* '''wesnoth.advance_unit(''unit'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':advance()'''<br />
<br />
{{DevFeature1.13|0}} Advances the unit (and shows the advance unit dialog if needed) if the unit has enough xp. This function should be called after modifying the units experience directly. A similar function is called by wesnoth internally after unit combat. The second argument is a boodean value that specifies whether the advancement should be animated. The third agrument is a boodean value that specifies whether advancement related events should be fired.<br />
<br />
<br />
This function only works for units on the map.<br />
<br />
This function can also trigger multiple advancements if the unit has enough xp.<br />
<br />
==== wesnoth.add_modification ====<br />
<br />
* '''wesnoth.add_modification(''unit'', ''type'', ''effects'', [''write_to_mods''])'''<br />
* {{DevFeature1.13|2}} '''''unit'':add_modification(''type'', ''effects'', [''write_to_mods''])'''<br />
<br />
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (one of "trait", "object", or "advance"). The option "advance" applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.<br />
<br />
{{DevFeature1.13|2}} In 1.13.2 and later, the "advance" type is replaced with "advancement", to match the equivalent tag in [[UnitTypeWML|[unit_type]]]. Also, it takes a fourth argument which, if false, causes it to not write the modification tag to the unit's [modifications] (as would be done with an [object] with no_write=true).<br />
<br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
wesnoth.add_modification(u, "object", { { "effect", { apply_to = "image_mod", replace = "RC(red>blue)" } } })<br />
<br />
==== wesnoth.remove_modification ====<br />
<br />
* {{DevFeature1.13|?}} '''wesnoth.remove_modification(''unit'', ''cfg'')'''<br />
* {{DevFeature1.13|?}} '''''unit'':remove_modification(''cfg'')'''<br />
<br />
Modifies a given unit. The unit needs to be a proxy unit. The second argument is the modification to remove. It should be a WML table with an "id" key specifying object id to remove.<br />
<br />
local u = wesnoth.get_units { canrecruit = true }[1]<br />
wesnoth.remove_modification(u, { id = your_object_id })<br />
<br />
==== wesnoth.unit_resistance ====<br />
<br />
* '''wesnoth.unit_resistance(''unit'', ''damage_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':resistance(''damage_type'')'''<br />
<br />
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).<br />
<br />
local fire_resistance = 100 - wesnoth.unit_resistance(u, "fire")<br />
<br />
==== wesnoth.unit_defense ====<br />
<br />
* '''wesnoth.unit_defense(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':defense(''terrain_code'')'''<br />
<br />
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)<br />
<br />
local flat_defense = 100 - wesnoth.unit_defense(u, "Gt")<br />
<br />
==== wesnoth.unit_movement_cost ====<br />
<br />
* '''wesnoth.unit_movement_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':movement(''terrain_code'')'''<br />
<br />
Returns the movement cost of a unit on a particular terrain.<br />
<br />
local move_cost = wesnoth.unit_movement_cost(u, "Gt")<br />
<br />
==== wesnoth.unit_vision_cost ====<br />
<br />
* '''wesnoth.unit_vision_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':vision(''terrain_code'')'''<br />
<br />
Returns the vision cost of a unit on a particular terrain.<br />
<br />
local see_cost = wesnoth.unit_vision_cost(u, "Gt")<br />
<br />
==== wesnoth.unit_jamming_cost ====<br />
<br />
* '''wesnoth.unit_jamming_cost(''unit'', ''terrain_code'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':jamming(''terrain_code'')'''<br />
<br />
Returns the jamming cost of a unit on a particular terrain.<br />
<br />
local jam_cost = wesnoth.unit_jamming_cost(u, "Gt")<br />
<br />
==== wesnoth.unit_ability ====<br />
<br />
* '''wesnoth.unit_ability(''unit'', ''ability_tag'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':ability(''ability_tag'')'''<br />
<br />
Returns true if the unit is currently under effect by an ability with this given TAG NAME. This means that the ability could be owned by the unit itself, or by an adjacent unit.<br />
<br />
function has_teleport(u)<br />
return wesnoth.unit_ability(u, "teleport")<br />
end<br />
<br />
==== wesnoth.unit_types ====<br />
<br />
This is not a function but a read-only table indexed by unit type ids. Its elements are proxy tables with these fields:<br />
<br />
* '''id''': string<br />
* '''name''': translatable string (read only)<br />
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)<br />
* '''abilities''': array of ability keys (strings), e.g. {"curing", "regenerates"}<br />
* {{DevFeature1.13|11}} '''advances_to''': array of unit types to which unit can advance<br />
* {{DevFeature1.13|11}} '''advances_from''': array of unit types from which unit can advance. Note: this is OOS-unsafe in Multiplayer games. Different clients may have additional Era-s with units upgradable to this unit type.<br />
* '''__cfg''': WML table (dump), see [[UnitTypeWML]]<br />
<br />
The metatable of these proxy tables appears as '''"unit type"'''.<br />
<br />
local lich_cost = wesnoth.unit_types["Ancient Lich"].cost<br />
<br />
Note that different clients have different set of available units in a Multiplayer game. It is OOS-unsafe to e.g. count the number of units.<br />
Presuming correctly written add-ons, it is still safe to e.g. access any given unit or its properties.<br />
<br />
==== wesnoth.races ====<br />
<br />
This is not a function but a table indexed by race ids. Its elements are proxy tables for all races the engine knows about.<br />
known fields of each element:<br />
* '''id''': string<br />
* '''description''', '''name''', '''plural_name''' (translatable strings)<br />
* '''num_traits''' (integer)<br />
* '''ignore_global_traits''' (boolean)<br />
* '''undead_variation''' (string)<br />
(all read only)<br />
* '''__cfg''': WML table (dump)<br />
<br />
wesnoth.message(tostring(wesnoth.races["lizard"].name))<br />
<br />
==== wesnoth.get_traits ====<br />
<br />
* '''wesnoth.get_traits()'''<br />
<br />
Returns a table with named fields (trait id strings) holding the wml tables defining the traits. arguments: none. All global traits the engine knows about, race-specific traits are not included.<br />
Known fields and subtags of each element are the ones which were given in the wml definition of the [[SingleUnitWML|trait]].<br />
wesnoth.message(tostring(wesnoth.get_traits().strong.male_name))<br />
<br />
==== wesnoth.simulate_combat ====<br />
<br />
* '''wesnoth.simulate_combat(''attacker'', [''attacker_weapon_index''], ''defender'', [''defender_weapon_index''])'''<br />
<br />
Computes the hitpoint distribution and status chance after a combat between two units. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.<br />
<br />
Optional integers can be passed after each unit to select a particular weapon, otherwise the "best" one is selected. When giving the weapon, the parameter is the weapon number (integer, starting at 1) and not an element from the table returned by helper.child_range(att, "attack").<br />
<br />
local function display_stats(n, t)<br />
wesnoth.message(string.format(<br />
"Chance for the %s\n to be slowed: %f,\n to be poisoned: %f,\n to die: %f.\nAverage HP: %f.",<br />
n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))<br />
end<br />
local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def, def_weapon)<br />
display_stats("attacker", att_stats)<br />
display_stats("defender", def_stats)<br />
<br />
Returns 2 additional tables which contain information about the weapons and the effect of single hits with these keys: num_blows, damage, chance_to_hit, poisons, slows, petrifies, plagues, plague_type, backstabs, rounds, firststrike, drains, drain_constant, drain_percent, attack_num, name. <br />
Name is the wml name not the description. If there is no weapon, then name will be nil<br />
<br />
local att_stats, def_stats, att_weapon, def_weapon = wesnoth.simulate_combat(attacker, att_weapon_number, defender)<br />
wesnoth.message(string.format(<br />
"The attack %s should be countered with %s, which does %d damage, has %d%% chance to hit and forces %d attack rounds due to its berserk ability.",<br />
att_weapon.name, def_weapon.name or "no weapon", def_weapon.damage, def_weapon.chance_to_hit, def_weapon.rounds))<br />
<br />
==== wesnoth.transform_unit ====<br />
<br />
* '''wesnoth.transform_unit(''unit'', ''to_type'')'''<br />
* {{DevFeature1.13|2}} '''''unit'':transform(''to_type'')'''<br />
<br />
Changes the type of a unit and adjust attributes accordingly. Note that hit points are only changed if necessary to accommodate the new maximum hit points. Poison is automatically removed if the transformed unit is immune.<br />
<br />
local ev = wesnoth.current.event_context<br />
local u = wesnoth.get_units{x=ev.x1, y=ev.y1}[1]<br />
wesnoth.transform_unit(u, "Spearman")<br />
-- If a full heal is desired:<br />
u.hitpoints = u.max_hitpoints<br />
u.status.poisoned = false<br />
<br />
==== wesnoth.add_known_unit ====<br />
<br />
* {{DevFeature1.13|10}} '''wesnoth.add_known_unit(''unit_type_id'')'''<br />
<br />
adds the unit type with the given id to the list of known units (so thath they appear in the help)<br />
<br />
==== wesnoth.create_animator ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.create_animator()'''<br />
<br />
Returns an object that can be used to set up and run an animation. The object has three methods:<br />
<br />
* '''animator:run()'''<br />
<br />
Runs the animation.<br />
<br />
* '''animator:clear()'''<br />
<br />
Clears any units previously added to the animation.<br />
<br />
* '''animator:add(''unit'', ''flag'', ''hits'', ''params'')'''<br />
<br />
Adds a unit to the animation. The ''flag'' specifies which animation to play, and the ''hits'' parameter is required for attack animations to specify which variant of the animation to play. Possibly keys in ''params'' are:<br />
<br />
* '''facing''': A location. The animation will be played with the unit facing that location.<br />
* '''value''': Either a number or a list of two numbers. Use this to pass ''value'' and/or ''value_second'' to default animations that use them.<br />
* '''with_bars''': Whether to show HP bars and such while the animation plays.<br />
* '''text''': Text to float as the animation plays.<br />
* '''color''': Color of the floating text - a list of red, green, blue.<br />
* '''primary''': The primary weapon to use for the animation. Must be a Lua unit attack proxy.<br />
* '''secondary''': The secondary weapon to use for the animation.<br />
<br />
Normal usage would be to create it, call '''add''' one or more times, then call '''run'''.<br />
<br />
==== wesnoth.effects ====<br />
<br />
{{DevFeature1.13|2}}<br />
<br />
This table contains the implementation of custom [[EffectWML|[effect]]]s. Each value is a function that takes a unit and the effect config. Note that the default effects defined by the Wesnoth engine are not in this table. <br />
<br />
<syntaxhighlight lang='lua'><br />
function wesnoth.effects.min_resistance(u, cfg)<br />
local resistance_new = {}<br />
local resistance_old = helper.parsed(helper.get_child(cfg, "resistance"))<br />
for k,v in pairs(resistance_old) do<br />
if type(k) == "string" and type(v) == "number" and wesnoth.unit_resistance(u, k) >= v then<br />
resistance_new[k] = v<br />
end<br />
end<br />
--important: use wesnoth.add_modification(..., false) so that the function will only execute the effects of that object and not store the object in the unit.<br />
wesnoth.add_modification(u, "object", {<br />
T.effect {<br />
apply_to = "resistance",<br />
replace = true,<br />
T.resistance (resistance_new),<br />
},<br />
}, false)<br />
end<br />
</syntaxhighlight><br />
<br />
The code above adds a new <code>min_resistance</code> effect that will set the resistances to specific values if they are currently below that value. It can then be used like this (for example, in [[DirectActionsWML#.5Bobject.5D|[object]]]):<br />
<br />
<syntaxhighlight lang='wml'><br />
[effect]<br />
apply_to=min_resistance<br />
[resistance]<br />
cold=50<br />
[/resistance]<br />
[/effect]<br />
</syntaxhighlight><br />
<br />
Note that because currently all Lua code is executed after [unit]s in [side] are created, it is currently not possible to use these effects in [unit]s in [side]<br />
<br />
{{DevFeature1.13|5}}<br />
<br />
Built-in effects are now present in the <code>wesnoth.effects</code> table and can be called by custom effects or by other Lua code. They take the same two arguments that a custom effect function does - the unit, and the effect WML.<br />
<br />
In addition, you can now specify description modifiers to be used if a custom effect is placed in a <code>[trait]</code> tag. Instead of setting a function as the effect, you set a table with a <code>__call</code> metafunction which does what the function would have done. The table can then have an additional <code>__descr</code> metafunction which updates descriptions as necessary. The built-in effects all use this structure. This metafunction takes the same arguments as the regular effect function, but should not modify the unit. Instead, it returns a string to be appended to the trait's effect description.<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML&diff=59371LuaWML2018-04-07T19:09:40Z<p>Vasya: /* Units */</p>
<hr />
<div>{{WML Tags}}<br />
<br />
== The '''[lua]''' tag ==<br />
<br />
This tag is a part of [[ActionWML]], thus can be used inside [event] and at other places where [[ActionWML]] can be used. It makes it possible to write actions with the [http://www.lua.org Lua 5.2] language.<br />
<br />
It is also possible to put this tag inside a [scenario] [[ScenarioWML]], those tags will be executed immediately when the lua engine loads which is even before the scenario preload event is fired.<br />
<br />
{{DevFeature1.13|0}}<br />
[lua] is now also allowed in [era] and [modification] those [lua] tags are then copied into the [scenario]/[multiplayer] when it is played just like [event]s inside [era] or [modification]<br />
<br />
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.<br />
<br />
<syntaxhighlight lang='wml'><br />
[lua]<br />
code = << wesnoth.message "Hello World!" >><br />
[/lua]<br />
</syntaxhighlight><br />
<br />
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:<br />
<br />
:lua local u = wesnoth.get_units({ id = "Konrad" })[1]; u.moves = 5<br />
<br />
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable "'''...'''".<br />
<br />
<syntaxhighlight lang='wml'><br />
[lua]<br />
code = << local t = ...; wesnoth.message(tostring(t.text)) >><br />
[args]<br />
text = _ "Hello world!"<br />
[/args]<br />
[/lua]<br />
</syntaxhighlight><br />
<br />
== Global environment ==<br />
<br />
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = <<<br />
function narrator(t)<br />
-- Behave like the [message] tag.<br />
wesnoth.fire("message",<br />
{ speaker = "narrator", message = t.sentence })<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
[event]<br />
name = turn 1<br />
[lua]<br />
code = << narrator(...) >><br />
[args]<br />
sentence = _ "Hello world!"<br />
[/args]<br />
[/lua]<br />
[lua]<br />
code = << narrator(...) >><br />
[args]<br />
sentence = _ "How are you today?"<br />
[/args]<br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = <<<br />
-- The function is now placed in the wesnoth.wml_actions table<br />
-- The tag is [narrator], same as the function name<br />
function wesnoth.wml_actions.narrator(t)<br />
-- Behave like the [message] tag.<br />
wesnoth.fire("message",<br />
{ speaker = "narrator", message = t.sentence })<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
[event]<br />
name = turn 1<br />
[narrator]<br />
sentence = _ "Hello world!"<br />
[/narrator]<br />
[narrator]<br />
sentence = _ "How are you today?"<br />
[/narrator]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea. The only time assigning global variables (including function definitions) makes sense is in a [lua] block directly in [scenario] or during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.<br />
<br />
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]]. Additionally, the functions clock, date, time and difftime from the [http://www.lua.org/manual/5.1/manual.html#5.8 os] library (keep in mind that they aren't multiplayer- and replay-safe), as well as traceback from the [http://www.lua.org/manual/5.1/manual.html#5.9 debug] library are also available.<br />
<br />
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.<br />
<br />
== Examples ==<br />
<br />
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.<br />
<br />
<syntaxhighlight lang='wml'><br />
# General catch for them moving to the wrong place.<br />
[event]<br />
name=moveto<br />
first_time_only=no<br />
[allow_undo][/allow_undo]<br />
[filter]<br />
side=1<br />
[/filter]<br />
<br />
[if]<br />
[variable]<br />
name=target_hex.is_set<br />
equals=yes<br />
[/variable]<br />
[then]<br />
[if]<br />
[variable]<br />
name=x1<br />
equals=$target_hex.x<br />
[/variable]<br />
[variable]<br />
name=y1<br />
equals=$target_hex.y<br />
[/variable]<br />
[then]<br />
[/then]<br />
[else]<br />
[redraw][/redraw]<br />
[message]<br />
speaker=narrator<br />
message=_ "*Oops!<br />
You moved to the wrong place! After this message, you can press 'u' to undo, then try again." +<br />
_ "<br />
*Left click or press spacebar to continue..."<br />
[/message]<br />
[/else]<br />
[/if]<br />
[/then]<br />
[/if]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
A Lua script that performs the same action is presented below.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=moveto<br />
first_time_only=no<br />
[allow_undo][/allow_undo]<br />
[filter]<br />
side=1<br />
[/filter]<br />
<br />
[lua]<br />
code = <<<br />
local event_data = wesnoth.current.event_context<br />
if V.target_hex.is_set and<br />
(event_data.x1 ~= V.target_hex.x or event_data.y1 ~= V.target_hex.y)<br />
then<br />
W.redraw()<br />
narrator_says(_ "*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.")<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Here is a more detailed explanation of the Lua code. Its first line<br />
<br />
<syntaxhighlight lang='lua'><br />
local event_data = wesnoth.current.event_context<br />
</syntaxhighlight><br />
<br />
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.<br />
<br />
The next two lines then test<br />
<br />
<syntaxhighlight lang='lua'><br />
if V.target_hex.is_set and<br />
(event_data.x1 ~= V.target_hex.x or event_data.y1 ~= V.target_hex.y)<br />
</syntaxhighlight><br />
<br />
whether the variable ''V.target_hex'' matches the event parameters. Since ''V'' is not a local variable, it is taken from the global environment. Usually, variables from the global environment are not persistent (they get lost on reloading), so it shouldn't be used to store data. In order to have an easy way to access the usual persistent Wml variables, the global variable ''V'' was mapped to the storage of WML variables by the following ''preload'' event.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = <<<br />
H = wesnoth.require "lua/helper.lua"<br />
-- skipping some other initializations<br />
-- ...<br />
V = H.set_wml_var_metatable {}<br />
>><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Without a prelude redirecting ''V'', the conditional would have been written<br />
<br />
<syntaxhighlight lang='lua'><br />
if wesnoth.get_variable("target_hex.is_set") and<br />
(event_data.x1 ~= wesnoth.get_variable("target_hex.x") or event_data.y1 ~= wesnoth.get_variable("target_hex.y")<br />
</syntaxhighlight><br />
<br />
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.<br />
<br />
<syntaxhighlight lang='lua'><br />
W.redraw()<br />
</syntaxhighlight><br />
<br />
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.<br />
<br />
<syntaxhighlight lang='lua'><br />
W = H.set_wml_action_metatable {}<br />
</syntaxhighlight><br />
<br />
Without this shortcut, the first statement would have been written<br />
<br />
<syntaxhighlight lang='lua'><br />
wesnoth.fire("redraw")<br />
</syntaxhighlight><br />
<br />
Finally the script displays a message by<br />
<br />
<syntaxhighlight lang='lua'><br />
narrator_says(_ "*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.")<br />
</syntaxhighlight><br />
<br />
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is<br />
<br />
<syntaxhighlight lang='lua'><br />
function narrator_says(m)<br />
W.message { speaker="narrator",<br />
message = m .. _ "\n*Left click or press spacebar to continue..." }<br />
end<br />
</syntaxhighlight><br />
<br />
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:<br />
<br />
<syntaxhighlight lang='lua'><br />
_ = wesnoth.textdomain "wesnoth-tutorial"<br />
</syntaxhighlight><br />
<br />
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].<br />
<br />
== Interface to the engine and helper functions ==<br />
<br />
Functionalities of the game engine are available through the functions contained in the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked "read-only" are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.<br />
<br />
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].<br />
<br />
<syntaxhighlight lang='lua'><br />
helper = wesnoth.require "lua/helper.lua"<br />
</syntaxhighlight><br />
<br />
=== WML variables ===<br />
<br />
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]<br />
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]<br />
* [[LuaWML:Variables#wesnoth.get_all_vars|wesnoth.get_all_vars]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Variables#wesnoth.wml_matches_filter|wesnoth.wml_matches_filter]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]<br />
* [[LuaWML:Variables#helper.get_child|helper.get_child]]<br />
* [[LuaWML:Variables#helper.get_nth_child|helper.get_nth_child]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Variables#helper.child_count|helper.child_count]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Variables#helper.child_range|helper.child_range]]<br />
* [[LuaWML:Variables#helper.child_array|helper.child_array]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]<br />
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]<br />
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]<br />
<br />
=== Events and WML actions ===<br />
<br />
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]<br />
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]]<br />
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_conditionals]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]]<br />
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]<br />
* [[LuaWML:Events#wesnoth.fire_event_by_id|wesnoth.fire_event_by_id]] {{DevFeature1.13|6}}<br />
* [[LuaWML:Events#wesnoth.add_event_handler|wesnoth.add_event_handler]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Events#wesnoth.remove_event_handler|wesnoth.remove_event_handler]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]<br />
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]]<br />
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]<br />
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]<br />
* [[LuaWML:Events#helper.literal|helper.literal]]<br />
* [[LuaWML:Events#helper.parsed|helper.parsed]]<br />
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]]<br />
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]]<br />
* [[LuaWML:Events#on_event.lua|on_event.on_event]] {{DevFeature1.13|6}}<br />
<br />
=== User interface ===<br />
* [[LuaWML:Display#wesnoth.get_viewing_side|wesnoth.get_viewing_side]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]<br />
* [[LuaWML:Display#wesnoth.clear_messages|wesnoth.clear_messages]]<br />
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]<br />
* [[LuaWML:Display#wesnoth.delay|wesnoth.delay]]<br />
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]<br />
* [[LuaWML:Display#wesnoth.select_unit|wesnoth.select_hex]]<br />
* [[LuaWML:Display#wesnoth.select_unit|wesnoth.select_unit]]<br />
* [[LuaWML:Display#wesnoth.highlight_hex|wesnoth.highlight_hex]]<br />
* [[LuaWML:Display#wesnoth.deselect_hex|wesnoth.deselect_hex]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]]<br />
* [[LuaWML:Display#wesnoth.lock_view|wesnoth.lock_view]]<br />
* [[LuaWML:Display#wesnoth.view_locked|wesnoth.view_locked]]<br />
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]]<br />
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]]<br />
* [[LuaWML:Display#wesnoth.music_list|wesnoth.music_list]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.sound_volume|wesnoth.sound_volume]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_dialog|wesnoth.show_message_dialog]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.show_popup_dialog|wesnoth.show_popup_dialog]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.show_story|wesnoth.show_story]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_box|wesnoth.show_message_box]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_menu|wesnoth.show_menu]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_box|wesnoth.alert]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_box|wesnoth.confirm]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]]<br />
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_active|wesnoth.set_dialog_active]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_markup|wesnoth.set_dialog_markup]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_focus|wesnoth.set_dialog_focus]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_visible|wesnoth.set_dialog_visible]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]]<br />
* [[LuaWML:Display#wesnoth.add_dialog_tree_node|wesnoth.add_dialog_tree_node]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Display#wesnoth.remove_dialog_item|wesnoth.remove_dialog_item]] {{DevFeature1.13|1}}<br />
* [[LuaWML:Display#wesnoth.get_displayed_unit|wesnoth.get_displayed_unit]]<br />
* [[LuaWML:Display#wesnoth.theme_items|wesnoth.theme_items]]<br />
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]<br />
* [[LuaWML:Display#wesnoth.is_skipping_messages|wesnoth.is_skipping_messages]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.skip_messages|wesnoth.skip_messages]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.log|wesnoth.log]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Display#wesnoth.zoom|wesnoth.zoom]] {{DevFeature1.13|8}}<br />
<br />
=== Map and terrains ===<br />
<br />
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]<br />
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]<br />
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]<br />
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]<br />
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]<br />
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]]<br />
* [[LuaWML:Tiles#wesnoth.get_villages|wesnoth.get_villages]]<br />
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]]<br />
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]]<br />
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]]<br />
* [[LuaWML:Tiles#wesnoth.add_fog|wesnoth.add_fog]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.remove_fog|wesnoth.remove_fog]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.add_sound_source|wesnoth.add_sound_source]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.remove_sound_source|wesnoth.remove_sound_source]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.get_sound_source|wesnoth.get_sound_source]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.map.get_direction|wesnoth.map.get_direction]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.get_relative_dir|wesnoth.map.get_relative_dir]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.rotate_right_around_center|wesnoth.map.rotate_right_around_center]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.get_adjacent_tiles|wesnoth.map.get_adjacent_tiles]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.tiles_adjacent|wesnoth.map.tiles_adjacent]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.distance_between|wesnoth.map.distance_between]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.label|wesnoth.label]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Tiles#items.place_image|items.place_image]]<br />
* [[LuaWML:Tiles#items.place_halo|items.place_halo]]<br />
* [[LuaWML:Tiles#items.remove|items.remove]]<br />
<br />
=== Time of day schedule ===<br />
<br />
* [[LuaWML:Time#wesnoth.get_time_of_day|wesnoth.get_time_of_day]]<br />
* [[LuaWML:Time#wesnoth.add_time_area|wesnoth.add_time_area]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Time#wesnoth.remove_time_area|wesnoth.remove_time_area]] {{DevFeature1.13|0}}<br />
<br />
=== Units ===<br />
<br />
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]<br />
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]]<br />
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]]<br />
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]<br />
* [[LuaWML:Units#wesnoth.erase_unit|wesnoth.erase_unit]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]]<br />
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]]<br />
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]<br />
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]<br />
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]]<br />
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]]<br />
* [[LuaWML:Units#wesnoth.remove_modification|wesnoth.remove_modification]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]<br />
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]<br />
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_vision_cost|wesnoth.unit_vision_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_jamming_cost|wesnoth.unit_jamming_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]]<br />
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]]<br />
* [[LuaWML:Units#wesnoth.races|wesnoth.races]]<br />
* [[LuaWML:Units#wesnoth.get_traits|wesnoth.get_traits]]<br />
* [[LuaWML:Units#wesnoth.advance_unit|wesnoth.advance_unit]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Units#wesnoth.add_known_unit|wesnoth.add_known_unit]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]<br />
* [[LuaWML:Units#wesnoth.transform_unit|wesnoth.transform_unit]]<br />
* [[LuaWML:Units#wesnoth.create_animator|wesnoth.create_animator]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Units#wesnoth.effects|wesnoth.effects]] {{DevFeature1.13|2}}<br />
<br />
=== Sides ===<br />
<br />
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]]<br />
* [[LuaWML:Sides#wesnoth.get_sides|wesnoth.get_sides]]<br />
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]<br />
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]<br />
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]]<br />
* [[LuaWML:Sides#wesnoth.match_side|wesnoth.match_side]]<br />
* [[LuaWML:Sides#wesnoth.get_starting_location|wesnoth.get_starting_location]]<br />
* [[LuaWML:Sides#wesnoth.set_side_id|wesnoth.set_side_id]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.place_shroud|wesnoth.place_shroud]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.remove_shroud|wesnoth.remove_shroud]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.is_fogged|wesnoth.is_fogged]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.is_shrouded|wesnoth.is_shrouded]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.switch_ai|wesnoth.switch_ai]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.append_ai|wesnoth.append_ai]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.add_ai_component|wesnoth.add_ai_component]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.change_ai_component|wesnoth.change_ai_component]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.delete_ai_component|wesnoth.delete_ai_component]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]<br />
* [[LuaWML:Sides#helper.get_side_variable|helper.get_side_variable]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Sides#helper.set_side_variable|helper.set_side_variable]] {{DevFeature1.13|?}}<br />
<br />
=== Pathfinder ===<br />
<br />
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_cost_map|wesnoth.find_cost_map]]<br />
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]<br />
* [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]]<br />
<br />
=== Lua files ===<br />
<br />
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]<br />
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]<br />
* [[LuaWML:Files#wesnoth.have_file|wesnoth.have_file]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Files#wesnoth.read_file|wesnoth.read_file]] {{DevFeature1.13|5}}<br />
<br />
=== Location sets ===<br />
<br />
* [[LuaWML:Location_set#location_set.create|location_set.create]]<br />
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]]<br />
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]]<br />
* [[LuaWML:Location_set#location_set:empty|location_set:empty]]<br />
* [[LuaWML:Location_set#location_set:size|location_set:size]]<br />
* [[LuaWML:Location_set#location_set:clear|location_set:clear]]<br />
* [[LuaWML:Location_set#location_set:get|location_set:get]]<br />
* [[LuaWML:Location_set#location_set:insert|location_set:insert]]<br />
* [[LuaWML:Location_set#location_set:remove|location_set:remove]]<br />
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]]<br />
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]]<br />
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]]<br />
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]]<br />
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]]<br />
* [[LuaWML:Location_set#location_set:union|location_set:union]]<br />
* [[LuaWML:Location_set#location_set:inter|location_set:inter]]<br />
* [[LuaWML:Location_set#location_set:iter|location_set:iter]]<br />
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]]<br />
* [[LuaWML:Location_set#location_set:filter|location_set:filter]]<br />
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]]<br />
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]]<br />
<br />
=== Miscellaneous ===<br />
<br />
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]<br />
* [[LuaWML:Misc#wesnoth.get_era|wesnoth.get_era]]<br />
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]<br />
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]]<br />
* [[LuaWML:Misc#wesnoth.synchronize_choices|wesnoth.synchronize_choices]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Misc#wesnoth.unsynced|wesnoth.unsynced]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Misc#wesnoth.get_image_size|wesnoth.get_image_size]]<br />
* [[LuaWML:Misc#wesnoth.compare_versions|wesnoth.compare_versions]]<br />
* [[LuaWML:Misc#wesnoth.have_file|wesnoth.have_file]]<br />
* [[LuaWML:Misc#wesnoth.debug|wesnoth.debug]]<br />
* [[LuaWML:Misc#wesnoth.get_time_stamp|wesnoth.get_time_stamp]]<br />
* [[LuaWML:Misc#wesnoth.random|wesnoth.random]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Misc#wesnoth.eval_formula|wesnoth.eval_formula]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.compile_formula|wesnoth.compile_formula]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.name_generator|wesnoth.name_generator]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.set_next_scenario|wesnoth.set_next_scenario]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.format|wesnoth.format]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Misc#wesnoth.format_conjunct_list|wesnoth.format_conjunct_list]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Misc#wesnoth.format_disjunct_list|wesnoth.format_disjunct_list]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Misc#wesnoth.wesnoth.end_turn|wesnoth.end_turn]] {{DevFeature1.13|ß}}<br />
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]<br />
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]<br />
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]<br />
* [[LuaWML:Misc#helper.rand|helper.rand]]<br />
* [[LuaWML:Misc#helper.round|helper.round]]<br />
* [[LuaWML:Misc#helper.shuffle|helper.shuffle]]<br />
<br />
=== Functions that should not be used ===<br />
<br />
If you take a look at Wesnoth's own lua files, you might find some undocumented functions use in the implementations of WML tags. Where possible, you should avoid using them, as they might be changed or removed with no compatibility for further releases. Instead, use the corresponding wml tags (in lua you can use <tt>wesnoth.wml_actions.tag_name(cfg)</tt>, though keep in mind that this won't substitute variables in the config).<br />
<br />
If uncertain whether an undocumented feature is safe to use, ask on the forums, Discord, or IRC. It may turn out that someone simply forgot to add it to the wiki.<br />
<br />
* wesnoth.redraw<br />
* wesnoth.set_menu_item<br />
* wesnoth.clear_menu_item<br />
* wesnoth.modify_ai<br />
* wesnoth.print<br />
* wesnoth.end_level<br />
<br />
== Encoding WML objects into Lua tables ==<br />
<br />
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.<br />
<br />
Scalar fields are transformed into WML attributes. For instance, the following Lua table<br />
<br />
<syntaxhighlight lang='lua'><br />
{<br />
a_bool = true,<br />
an_int = 42,<br />
a_float = 1.25,<br />
a_string = "scout",<br />
a_translation = _ "Hello World!"<br />
}<br />
</syntaxhighlight><br />
<br />
is equivalent to the content of the following WML object<br />
<br />
<syntaxhighlight lang='wml'><br />
[dummy]<br />
a_bool = "yes"<br />
an_int = "42"<br />
a_float = "1.25"<br />
a_string = "scout"<br />
a_translation = _ "Hello World!"<br />
[/dummy]<br />
</syntaxhighlight><br />
<br />
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table "layer" in the corresponding WML table of the form <code>{[1] = "tag_name", [2] = {}}</code> which is equivalent to <code>{"tag_name", {}}</code>. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table<br />
<br />
<syntaxhighlight lang='lua'><br />
{<br />
foo = 42,<br />
{ "bar", { v = 1, w = 2 } },<br />
{ "foo", { x = false } },<br />
{ "bar", { y = "foo" } },<br />
{ "foobar", { z = 5, { "barfoo", {} } } }<br />
}<br />
</syntaxhighlight><br />
<br />
is equivalent to the content of the following WML object<br />
<br />
<syntaxhighlight lang='wml'><br />
[dummy]<br />
foo = 42<br />
[bar]<br />
v = 1<br />
w = 2<br />
[/bar]<br />
[foo]<br />
x = no<br />
[/foo]<br />
[bar]<br />
y = foo<br />
[bar]<br />
[foobar]<br />
z = 5<br />
[barfoo]<br />
[/barfoo]<br />
[/foobar]<br />
[/dummy]<br />
</syntaxhighlight><br />
<br />
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:<br />
<br />
<syntaxhighlight lang='lua'><br />
{<br />
foo = 42,<br />
[1] = { [1] = "bar", [2] = { v = 1, w = 2 } },<br />
[2] = { [1] = "foo", [2] = { x = false } },<br />
[3] = { [1] = "bar", [2] = { y = "foo" } },<br />
[4] = { [1] = "foobar", [2] = { z = 5, [1] = { [1] = "barfoo", [2] = {} } } }<br />
}<br />
</syntaxhighlight><br />
<br />
So assuming ''cfg'' contains the above WML object, the following accesses are possible:<br />
<br />
<syntaxhighlight lang=lua><br />
a_int = cfg.foo -- "dummy.foo", 42<br />
a_string = cfg[3][2].y -- "dummy.bar[1].y", "foo"<br />
a_table = cfg[4][2] -- "dummy.foobar", { z = 5, { "barfoo", {} } }<br />
</syntaxhighlight><br />
<br />
For creating valid wml table in lua it is usully easier to use ''T = helper.set_wml_tag_metatable {}'' asuming you did that you can create the above wml document with<br />
<syntaxhighlight lang=lua><br />
{<br />
foo = 42,<br />
T.bar {<br />
v = 1,<br />
w = 1,<br />
},<br />
T.foo {<br />
x = false,<br />
},<br />
T.bar {<br />
y = "foo",<br />
},<br />
T.foobar {<br />
z = 5,<br />
T.barfoo {<br />
},<br />
},<br />
}<br />
</syntaxhighlight><br />
<br />
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.<br />
<br />
{{DevFeature1.13|5}} As a convenience, attributes with array values (tables with only integer keys) are concatenated into a string when converting a Lua table into WML. For example, the following Lua code:<br />
<br />
<syntaxhighlight lang=lua><br />
{<br />
x = {1, 2, 3, 4},<br />
y = {7, 8, 9, 10}<br />
}<br />
</syntaxhighlight><br />
<br />
produces the following WML table:<br />
<br />
<syntaxhighlight lang=wml><br />
[dummy]<br />
x=1,2,3,4<br />
y=7,8,9,10<br />
[/dummy]<br />
</syntaxhighlight><br />
<br />
Functions registered in [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.<br />
<br />
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.<br />
<br />
<syntaxhighlight lang=lua><br />
local old_event_handler = wesnoth.wml_actions.event<br />
function wesnoth.wml_actions.event(cfg)<br />
-- Get the plain text from the user.<br />
local new_cfg = cfg.__literal<br />
-- The expression below is equivalent to cfg.__parsed.first_time_only,<br />
-- only faster. It is needed, since the first_time_only attribute may<br />
-- reference variables.<br />
local first = cfg.first_time_only<br />
-- Modify the default behavior of first_time_only.<br />
if first == nil then first = false end<br />
new_cfg.first_time_only = first<br />
-- Call the engine handler.<br />
old_event_handler(new_cfg)<br />
end<br />
</syntaxhighlight><br />
<br />
(Note: The above example will only affect nested events. Toplevel events will still default to ''first_time_only=yes''.)<br />
<!-- This should probably be replaced with a better example. --><br />
<br />
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:<br />
<br />
<syntaxhighlight lang=lua><br />
function get_child(cfg, name)<br />
for i = 1, #cfg do<br />
local v = cfg[i]<br />
if v[1] == name then return v[2] end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
{{DevFeature1.13|2}} '''pairs''' and '''ipairs''' now work on vconfig objects (contrary to the above statement). However, '''pairs''' works a little differently than on plain configs (tables) - it returns only string keys (attributes in WML terms) and not integer keys (tags in WML terms).<br />
<br />
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:<br />
<br />
<syntaxhighlight lang=lua><br />
if getmetatable(cfg) == "wml object" then cfg = cfg.__parsed end<br />
</syntaxhighlight><br />
<br />
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal'''. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.<br />
<br />
== Skeleton of a preload event ==<br />
<br />
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It sets up a table ''T'' so be used for easier creation of valid WML tables. It also sets up a table ''V'' so that any access to it is redirected to the persistent WML storage. Finally, it loads a textdomain to be accessed through the ''_'' variable.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = <<<br />
H = wesnoth.require "lua/helper.lua"<br />
W = H.set_wml_action_metatable {}<br />
T = H.set_wml_tag_metatable {}<br />
V = H.set_wml_var_metatable {}<br />
_ = wesnoth.textdomain "my-campaign"<br />
<br />
-- Define your global constants here.<br />
-- ...<br />
<br />
<br />
-- Define your global functions here.<br />
-- ...<br />
>><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = << wesnoth.dofile "~add-ons/Whatever/file.lua" >><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
== Remarks on Random Numbers ==<br />
<br />
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should use the [[LuaWML:Misc#helper.rand|helper.rand()]] function to synchronize random values. It takes the same argument in the same format as [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] rand=.<br />
<br />
<syntaxhighlight lang='lua'><br />
local random_variable = helper.rand("1,2,3")<br />
</syntaxhighlight><br />
<br />
Also available is [[LuaWML:Misc#wesnoth.random|wesnoth.random]], which has the same interface as math.random but is multiplayer-safe.<br />
<br />
== Random Lua table iteration ==<br />
<br />
Table iteration order ('''pairs''') is not strictly defined in Lua. If your code depends on the order of iteration, different clients may have different data in a multiplayer game. For example:<br />
<br />
<syntaxhighlight lang='lua'><br />
local table = { ["Mage"] = true, ["Wose"] = true }<br />
local concat = ""<br />
local bad_usage = next(table) -- wrong, leads to OOS<br />
for k, _ in pairs(table) do -- wrong, leads to OOS<br />
concat = concat .. k<br />
end<br />
</syntaxhighlight><br />
<br />
To avoid the problem, sort the table keys before iterating. Or alternatively, use Lua "arrays" and the '''ipairs''' function, which have a strictly defined order and never lead to OOS. Example of correct code:<br />
<br />
<syntaxhighlight lang='lua'><br />
local array = { "Mage", "Wose" }<br />
local good_usage = table[1] -- correct<br />
local concat = ""<br />
for _, v in ipairs(array) do -- correct<br />
concat = concat .. v<br />
end<br />
</syntaxhighlight><br />
<br />
[[Category: Lua Reference|*]]<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML&diff=59370LuaWML2018-04-07T19:04:20Z<p>Vasya: /* Units */</p>
<hr />
<div>{{WML Tags}}<br />
<br />
== The '''[lua]''' tag ==<br />
<br />
This tag is a part of [[ActionWML]], thus can be used inside [event] and at other places where [[ActionWML]] can be used. It makes it possible to write actions with the [http://www.lua.org Lua 5.2] language.<br />
<br />
It is also possible to put this tag inside a [scenario] [[ScenarioWML]], those tags will be executed immediately when the lua engine loads which is even before the scenario preload event is fired.<br />
<br />
{{DevFeature1.13|0}}<br />
[lua] is now also allowed in [era] and [modification] those [lua] tags are then copied into the [scenario]/[multiplayer] when it is played just like [event]s inside [era] or [modification]<br />
<br />
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.<br />
<br />
<syntaxhighlight lang='wml'><br />
[lua]<br />
code = << wesnoth.message "Hello World!" >><br />
[/lua]<br />
</syntaxhighlight><br />
<br />
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:<br />
<br />
:lua local u = wesnoth.get_units({ id = "Konrad" })[1]; u.moves = 5<br />
<br />
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable "'''...'''".<br />
<br />
<syntaxhighlight lang='wml'><br />
[lua]<br />
code = << local t = ...; wesnoth.message(tostring(t.text)) >><br />
[args]<br />
text = _ "Hello world!"<br />
[/args]<br />
[/lua]<br />
</syntaxhighlight><br />
<br />
== Global environment ==<br />
<br />
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = <<<br />
function narrator(t)<br />
-- Behave like the [message] tag.<br />
wesnoth.fire("message",<br />
{ speaker = "narrator", message = t.sentence })<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
[event]<br />
name = turn 1<br />
[lua]<br />
code = << narrator(...) >><br />
[args]<br />
sentence = _ "Hello world!"<br />
[/args]<br />
[/lua]<br />
[lua]<br />
code = << narrator(...) >><br />
[args]<br />
sentence = _ "How are you today?"<br />
[/args]<br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = <<<br />
-- The function is now placed in the wesnoth.wml_actions table<br />
-- The tag is [narrator], same as the function name<br />
function wesnoth.wml_actions.narrator(t)<br />
-- Behave like the [message] tag.<br />
wesnoth.fire("message",<br />
{ speaker = "narrator", message = t.sentence })<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
[event]<br />
name = turn 1<br />
[narrator]<br />
sentence = _ "Hello world!"<br />
[/narrator]<br />
[narrator]<br />
sentence = _ "How are you today?"<br />
[/narrator]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea. The only time assigning global variables (including function definitions) makes sense is in a [lua] block directly in [scenario] or during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.<br />
<br />
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]]. Additionally, the functions clock, date, time and difftime from the [http://www.lua.org/manual/5.1/manual.html#5.8 os] library (keep in mind that they aren't multiplayer- and replay-safe), as well as traceback from the [http://www.lua.org/manual/5.1/manual.html#5.9 debug] library are also available.<br />
<br />
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.<br />
<br />
== Examples ==<br />
<br />
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.<br />
<br />
<syntaxhighlight lang='wml'><br />
# General catch for them moving to the wrong place.<br />
[event]<br />
name=moveto<br />
first_time_only=no<br />
[allow_undo][/allow_undo]<br />
[filter]<br />
side=1<br />
[/filter]<br />
<br />
[if]<br />
[variable]<br />
name=target_hex.is_set<br />
equals=yes<br />
[/variable]<br />
[then]<br />
[if]<br />
[variable]<br />
name=x1<br />
equals=$target_hex.x<br />
[/variable]<br />
[variable]<br />
name=y1<br />
equals=$target_hex.y<br />
[/variable]<br />
[then]<br />
[/then]<br />
[else]<br />
[redraw][/redraw]<br />
[message]<br />
speaker=narrator<br />
message=_ "*Oops!<br />
You moved to the wrong place! After this message, you can press 'u' to undo, then try again." +<br />
_ "<br />
*Left click or press spacebar to continue..."<br />
[/message]<br />
[/else]<br />
[/if]<br />
[/then]<br />
[/if]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
A Lua script that performs the same action is presented below.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=moveto<br />
first_time_only=no<br />
[allow_undo][/allow_undo]<br />
[filter]<br />
side=1<br />
[/filter]<br />
<br />
[lua]<br />
code = <<<br />
local event_data = wesnoth.current.event_context<br />
if V.target_hex.is_set and<br />
(event_data.x1 ~= V.target_hex.x or event_data.y1 ~= V.target_hex.y)<br />
then<br />
W.redraw()<br />
narrator_says(_ "*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.")<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Here is a more detailed explanation of the Lua code. Its first line<br />
<br />
<syntaxhighlight lang='lua'><br />
local event_data = wesnoth.current.event_context<br />
</syntaxhighlight><br />
<br />
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.<br />
<br />
The next two lines then test<br />
<br />
<syntaxhighlight lang='lua'><br />
if V.target_hex.is_set and<br />
(event_data.x1 ~= V.target_hex.x or event_data.y1 ~= V.target_hex.y)<br />
</syntaxhighlight><br />
<br />
whether the variable ''V.target_hex'' matches the event parameters. Since ''V'' is not a local variable, it is taken from the global environment. Usually, variables from the global environment are not persistent (they get lost on reloading), so it shouldn't be used to store data. In order to have an easy way to access the usual persistent Wml variables, the global variable ''V'' was mapped to the storage of WML variables by the following ''preload'' event.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = <<<br />
H = wesnoth.require "lua/helper.lua"<br />
-- skipping some other initializations<br />
-- ...<br />
V = H.set_wml_var_metatable {}<br />
>><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
Without a prelude redirecting ''V'', the conditional would have been written<br />
<br />
<syntaxhighlight lang='lua'><br />
if wesnoth.get_variable("target_hex.is_set") and<br />
(event_data.x1 ~= wesnoth.get_variable("target_hex.x") or event_data.y1 ~= wesnoth.get_variable("target_hex.y")<br />
</syntaxhighlight><br />
<br />
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.<br />
<br />
<syntaxhighlight lang='lua'><br />
W.redraw()<br />
</syntaxhighlight><br />
<br />
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.<br />
<br />
<syntaxhighlight lang='lua'><br />
W = H.set_wml_action_metatable {}<br />
</syntaxhighlight><br />
<br />
Without this shortcut, the first statement would have been written<br />
<br />
<syntaxhighlight lang='lua'><br />
wesnoth.fire("redraw")<br />
</syntaxhighlight><br />
<br />
Finally the script displays a message by<br />
<br />
<syntaxhighlight lang='lua'><br />
narrator_says(_ "*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.")<br />
</syntaxhighlight><br />
<br />
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is<br />
<br />
<syntaxhighlight lang='lua'><br />
function narrator_says(m)<br />
W.message { speaker="narrator",<br />
message = m .. _ "\n*Left click or press spacebar to continue..." }<br />
end<br />
</syntaxhighlight><br />
<br />
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:<br />
<br />
<syntaxhighlight lang='lua'><br />
_ = wesnoth.textdomain "wesnoth-tutorial"<br />
</syntaxhighlight><br />
<br />
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].<br />
<br />
== Interface to the engine and helper functions ==<br />
<br />
Functionalities of the game engine are available through the functions contained in the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked "read-only" are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.<br />
<br />
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].<br />
<br />
<syntaxhighlight lang='lua'><br />
helper = wesnoth.require "lua/helper.lua"<br />
</syntaxhighlight><br />
<br />
=== WML variables ===<br />
<br />
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]<br />
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]<br />
* [[LuaWML:Variables#wesnoth.get_all_vars|wesnoth.get_all_vars]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Variables#wesnoth.wml_matches_filter|wesnoth.wml_matches_filter]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]<br />
* [[LuaWML:Variables#helper.get_child|helper.get_child]]<br />
* [[LuaWML:Variables#helper.get_nth_child|helper.get_nth_child]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Variables#helper.child_count|helper.child_count]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Variables#helper.child_range|helper.child_range]]<br />
* [[LuaWML:Variables#helper.child_array|helper.child_array]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]<br />
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]<br />
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]<br />
<br />
=== Events and WML actions ===<br />
<br />
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]<br />
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]]<br />
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_conditionals]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]]<br />
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]<br />
* [[LuaWML:Events#wesnoth.fire_event_by_id|wesnoth.fire_event_by_id]] {{DevFeature1.13|6}}<br />
* [[LuaWML:Events#wesnoth.add_event_handler|wesnoth.add_event_handler]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Events#wesnoth.remove_event_handler|wesnoth.remove_event_handler]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]<br />
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]]<br />
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]<br />
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]<br />
* [[LuaWML:Events#helper.literal|helper.literal]]<br />
* [[LuaWML:Events#helper.parsed|helper.parsed]]<br />
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]]<br />
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]]<br />
* [[LuaWML:Events#on_event.lua|on_event.on_event]] {{DevFeature1.13|6}}<br />
<br />
=== User interface ===<br />
* [[LuaWML:Display#wesnoth.get_viewing_side|wesnoth.get_viewing_side]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]<br />
* [[LuaWML:Display#wesnoth.clear_messages|wesnoth.clear_messages]]<br />
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]<br />
* [[LuaWML:Display#wesnoth.delay|wesnoth.delay]]<br />
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]<br />
* [[LuaWML:Display#wesnoth.select_unit|wesnoth.select_hex]]<br />
* [[LuaWML:Display#wesnoth.select_unit|wesnoth.select_unit]]<br />
* [[LuaWML:Display#wesnoth.highlight_hex|wesnoth.highlight_hex]]<br />
* [[LuaWML:Display#wesnoth.deselect_hex|wesnoth.deselect_hex]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]]<br />
* [[LuaWML:Display#wesnoth.lock_view|wesnoth.lock_view]]<br />
* [[LuaWML:Display#wesnoth.view_locked|wesnoth.view_locked]]<br />
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]]<br />
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]]<br />
* [[LuaWML:Display#wesnoth.music_list|wesnoth.music_list]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.sound_volume|wesnoth.sound_volume]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_dialog|wesnoth.show_message_dialog]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.show_popup_dialog|wesnoth.show_popup_dialog]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.show_story|wesnoth.show_story]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_box|wesnoth.show_message_box]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_menu|wesnoth.show_menu]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_box|wesnoth.alert]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_message_box|wesnoth.confirm]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]]<br />
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_active|wesnoth.set_dialog_active]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_markup|wesnoth.set_dialog_markup]]<br />
* [[LuaWML:Display#wesnoth.set_dialog_focus|wesnoth.set_dialog_focus]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_visible|wesnoth.set_dialog_visible]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]]<br />
* [[LuaWML:Display#wesnoth.add_dialog_tree_node|wesnoth.add_dialog_tree_node]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Display#wesnoth.remove_dialog_item|wesnoth.remove_dialog_item]] {{DevFeature1.13|1}}<br />
* [[LuaWML:Display#wesnoth.get_displayed_unit|wesnoth.get_displayed_unit]]<br />
* [[LuaWML:Display#wesnoth.theme_items|wesnoth.theme_items]]<br />
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]<br />
* [[LuaWML:Display#wesnoth.is_skipping_messages|wesnoth.is_skipping_messages]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.skip_messages|wesnoth.skip_messages]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Display#wesnoth.log|wesnoth.log]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Display#wesnoth.zoom|wesnoth.zoom]] {{DevFeature1.13|8}}<br />
<br />
=== Map and terrains ===<br />
<br />
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]<br />
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]<br />
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]<br />
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]<br />
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]<br />
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]]<br />
* [[LuaWML:Tiles#wesnoth.get_villages|wesnoth.get_villages]]<br />
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]]<br />
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]]<br />
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]]<br />
* [[LuaWML:Tiles#wesnoth.add_fog|wesnoth.add_fog]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.remove_fog|wesnoth.remove_fog]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.add_sound_source|wesnoth.add_sound_source]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.remove_sound_source|wesnoth.remove_sound_source]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.get_sound_source|wesnoth.get_sound_source]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Tiles#wesnoth.map.get_direction|wesnoth.map.get_direction]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.get_relative_dir|wesnoth.map.get_relative_dir]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.rotate_right_around_center|wesnoth.map.rotate_right_around_center]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.get_adjacent_tiles|wesnoth.map.get_adjacent_tiles]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.tiles_adjacent|wesnoth.map.tiles_adjacent]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.map.distance_between|wesnoth.map.distance_between]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Tiles#wesnoth.label|wesnoth.label]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Tiles#items.place_image|items.place_image]]<br />
* [[LuaWML:Tiles#items.place_halo|items.place_halo]]<br />
* [[LuaWML:Tiles#items.remove|items.remove]]<br />
<br />
=== Time of day schedule ===<br />
<br />
* [[LuaWML:Time#wesnoth.get_time_of_day|wesnoth.get_time_of_day]]<br />
* [[LuaWML:Time#wesnoth.add_time_area|wesnoth.add_time_area]] {{DevFeature1.13|0}}<br />
* [[LuaWML:Time#wesnoth.remove_time_area|wesnoth.remove_time_area]] {{DevFeature1.13|0}}<br />
<br />
=== Units ===<br />
<br />
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]<br />
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]]<br />
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]]<br />
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]<br />
* [[LuaWML:Units#wesnoth.erase_unit|wesnoth.erase_unit]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]]<br />
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]]<br />
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]<br />
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]<br />
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]]<br />
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]]<br />
* [[LuaWML:Units#wesnoth.remove_modification|wesnoth.remove_modification]]<br />
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]<br />
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]<br />
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_vision_cost|wesnoth.unit_vision_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_jamming_cost|wesnoth.unit_jamming_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]]<br />
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]]<br />
* [[LuaWML:Units#wesnoth.races|wesnoth.races]]<br />
* [[LuaWML:Units#wesnoth.get_traits|wesnoth.get_traits]]<br />
* [[LuaWML:Units#wesnoth.advance_unit|wesnoth.advance_unit]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Units#wesnoth.add_known_unit|wesnoth.add_known_unit]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]<br />
* [[LuaWML:Units#wesnoth.transform_unit|wesnoth.transform_unit]]<br />
* [[LuaWML:Units#wesnoth.create_animator|wesnoth.create_animator]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Units#wesnoth.effects|wesnoth.effects]] {{DevFeature1.13|2}}<br />
<br />
=== Sides ===<br />
<br />
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]]<br />
* [[LuaWML:Sides#wesnoth.get_sides|wesnoth.get_sides]]<br />
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]<br />
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]<br />
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]]<br />
* [[LuaWML:Sides#wesnoth.match_side|wesnoth.match_side]]<br />
* [[LuaWML:Sides#wesnoth.get_starting_location|wesnoth.get_starting_location]]<br />
* [[LuaWML:Sides#wesnoth.set_side_id|wesnoth.set_side_id]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.place_shroud|wesnoth.place_shroud]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.remove_shroud|wesnoth.remove_shroud]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.is_fogged|wesnoth.is_fogged]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.is_shrouded|wesnoth.is_shrouded]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.switch_ai|wesnoth.switch_ai]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.append_ai|wesnoth.append_ai]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.add_ai_component|wesnoth.add_ai_component]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.change_ai_component|wesnoth.change_ai_component]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#wesnoth.delete_ai_component|wesnoth.delete_ai_component]] {{DevFeature1.13|7}}<br />
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]<br />
* [[LuaWML:Sides#helper.get_side_variable|helper.get_side_variable]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Sides#helper.set_side_variable|helper.set_side_variable]] {{DevFeature1.13|?}}<br />
<br />
=== Pathfinder ===<br />
<br />
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_cost_map|wesnoth.find_cost_map]]<br />
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]<br />
* [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]]<br />
<br />
=== Lua files ===<br />
<br />
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]<br />
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]<br />
* [[LuaWML:Files#wesnoth.have_file|wesnoth.have_file]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Files#wesnoth.read_file|wesnoth.read_file]] {{DevFeature1.13|5}}<br />
<br />
=== Location sets ===<br />
<br />
* [[LuaWML:Location_set#location_set.create|location_set.create]]<br />
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]]<br />
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]]<br />
* [[LuaWML:Location_set#location_set:empty|location_set:empty]]<br />
* [[LuaWML:Location_set#location_set:size|location_set:size]]<br />
* [[LuaWML:Location_set#location_set:clear|location_set:clear]]<br />
* [[LuaWML:Location_set#location_set:get|location_set:get]]<br />
* [[LuaWML:Location_set#location_set:insert|location_set:insert]]<br />
* [[LuaWML:Location_set#location_set:remove|location_set:remove]]<br />
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]]<br />
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]]<br />
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]]<br />
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]]<br />
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]]<br />
* [[LuaWML:Location_set#location_set:union|location_set:union]]<br />
* [[LuaWML:Location_set#location_set:inter|location_set:inter]]<br />
* [[LuaWML:Location_set#location_set:iter|location_set:iter]]<br />
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]]<br />
* [[LuaWML:Location_set#location_set:filter|location_set:filter]]<br />
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]]<br />
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]]<br />
<br />
=== Miscellaneous ===<br />
<br />
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]<br />
* [[LuaWML:Misc#wesnoth.get_era|wesnoth.get_era]]<br />
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]<br />
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]]<br />
* [[LuaWML:Misc#wesnoth.synchronize_choices|wesnoth.synchronize_choices]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Misc#wesnoth.unsynced|wesnoth.unsynced]] {{DevFeature1.13|?}}<br />
* [[LuaWML:Misc#wesnoth.get_image_size|wesnoth.get_image_size]]<br />
* [[LuaWML:Misc#wesnoth.compare_versions|wesnoth.compare_versions]]<br />
* [[LuaWML:Misc#wesnoth.have_file|wesnoth.have_file]]<br />
* [[LuaWML:Misc#wesnoth.debug|wesnoth.debug]]<br />
* [[LuaWML:Misc#wesnoth.get_time_stamp|wesnoth.get_time_stamp]]<br />
* [[LuaWML:Misc#wesnoth.random|wesnoth.random]] {{DevFeature1.13|2}}<br />
* [[LuaWML:Misc#wesnoth.eval_formula|wesnoth.eval_formula]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.compile_formula|wesnoth.compile_formula]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.name_generator|wesnoth.name_generator]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.set_next_scenario|wesnoth.set_next_scenario]] {{DevFeature1.13|5}}<br />
* [[LuaWML:Misc#wesnoth.format|wesnoth.format]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Misc#wesnoth.format_conjunct_list|wesnoth.format_conjunct_list]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Misc#wesnoth.format_disjunct_list|wesnoth.format_disjunct_list]] {{DevFeature1.13|8}}<br />
* [[LuaWML:Misc#wesnoth.wesnoth.end_turn|wesnoth.end_turn]] {{DevFeature1.13|ß}}<br />
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]<br />
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]<br />
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]<br />
* [[LuaWML:Misc#helper.rand|helper.rand]]<br />
* [[LuaWML:Misc#helper.round|helper.round]]<br />
* [[LuaWML:Misc#helper.shuffle|helper.shuffle]]<br />
<br />
=== Functions that should not be used ===<br />
<br />
If you take a look at Wesnoth's own lua files, you might find some undocumented functions use in the implementations of WML tags. Where possible, you should avoid using them, as they might be changed or removed with no compatibility for further releases. Instead, use the corresponding wml tags (in lua you can use <tt>wesnoth.wml_actions.tag_name(cfg)</tt>, though keep in mind that this won't substitute variables in the config).<br />
<br />
If uncertain whether an undocumented feature is safe to use, ask on the forums, Discord, or IRC. It may turn out that someone simply forgot to add it to the wiki.<br />
<br />
* wesnoth.redraw<br />
* wesnoth.set_menu_item<br />
* wesnoth.clear_menu_item<br />
* wesnoth.modify_ai<br />
* wesnoth.print<br />
* wesnoth.end_level<br />
<br />
== Encoding WML objects into Lua tables ==<br />
<br />
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.<br />
<br />
Scalar fields are transformed into WML attributes. For instance, the following Lua table<br />
<br />
<syntaxhighlight lang='lua'><br />
{<br />
a_bool = true,<br />
an_int = 42,<br />
a_float = 1.25,<br />
a_string = "scout",<br />
a_translation = _ "Hello World!"<br />
}<br />
</syntaxhighlight><br />
<br />
is equivalent to the content of the following WML object<br />
<br />
<syntaxhighlight lang='wml'><br />
[dummy]<br />
a_bool = "yes"<br />
an_int = "42"<br />
a_float = "1.25"<br />
a_string = "scout"<br />
a_translation = _ "Hello World!"<br />
[/dummy]<br />
</syntaxhighlight><br />
<br />
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table "layer" in the corresponding WML table of the form <code>{[1] = "tag_name", [2] = {}}</code> which is equivalent to <code>{"tag_name", {}}</code>. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table<br />
<br />
<syntaxhighlight lang='lua'><br />
{<br />
foo = 42,<br />
{ "bar", { v = 1, w = 2 } },<br />
{ "foo", { x = false } },<br />
{ "bar", { y = "foo" } },<br />
{ "foobar", { z = 5, { "barfoo", {} } } }<br />
}<br />
</syntaxhighlight><br />
<br />
is equivalent to the content of the following WML object<br />
<br />
<syntaxhighlight lang='wml'><br />
[dummy]<br />
foo = 42<br />
[bar]<br />
v = 1<br />
w = 2<br />
[/bar]<br />
[foo]<br />
x = no<br />
[/foo]<br />
[bar]<br />
y = foo<br />
[bar]<br />
[foobar]<br />
z = 5<br />
[barfoo]<br />
[/barfoo]<br />
[/foobar]<br />
[/dummy]<br />
</syntaxhighlight><br />
<br />
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:<br />
<br />
<syntaxhighlight lang='lua'><br />
{<br />
foo = 42,<br />
[1] = { [1] = "bar", [2] = { v = 1, w = 2 } },<br />
[2] = { [1] = "foo", [2] = { x = false } },<br />
[3] = { [1] = "bar", [2] = { y = "foo" } },<br />
[4] = { [1] = "foobar", [2] = { z = 5, [1] = { [1] = "barfoo", [2] = {} } } }<br />
}<br />
</syntaxhighlight><br />
<br />
So assuming ''cfg'' contains the above WML object, the following accesses are possible:<br />
<br />
<syntaxhighlight lang=lua><br />
a_int = cfg.foo -- "dummy.foo", 42<br />
a_string = cfg[3][2].y -- "dummy.bar[1].y", "foo"<br />
a_table = cfg[4][2] -- "dummy.foobar", { z = 5, { "barfoo", {} } }<br />
</syntaxhighlight><br />
<br />
For creating valid wml table in lua it is usully easier to use ''T = helper.set_wml_tag_metatable {}'' asuming you did that you can create the above wml document with<br />
<syntaxhighlight lang=lua><br />
{<br />
foo = 42,<br />
T.bar {<br />
v = 1,<br />
w = 1,<br />
},<br />
T.foo {<br />
x = false,<br />
},<br />
T.bar {<br />
y = "foo",<br />
},<br />
T.foobar {<br />
z = 5,<br />
T.barfoo {<br />
},<br />
},<br />
}<br />
</syntaxhighlight><br />
<br />
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.<br />
<br />
{{DevFeature1.13|5}} As a convenience, attributes with array values (tables with only integer keys) are concatenated into a string when converting a Lua table into WML. For example, the following Lua code:<br />
<br />
<syntaxhighlight lang=lua><br />
{<br />
x = {1, 2, 3, 4},<br />
y = {7, 8, 9, 10}<br />
}<br />
</syntaxhighlight><br />
<br />
produces the following WML table:<br />
<br />
<syntaxhighlight lang=wml><br />
[dummy]<br />
x=1,2,3,4<br />
y=7,8,9,10<br />
[/dummy]<br />
</syntaxhighlight><br />
<br />
Functions registered in [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.<br />
<br />
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.<br />
<br />
<syntaxhighlight lang=lua><br />
local old_event_handler = wesnoth.wml_actions.event<br />
function wesnoth.wml_actions.event(cfg)<br />
-- Get the plain text from the user.<br />
local new_cfg = cfg.__literal<br />
-- The expression below is equivalent to cfg.__parsed.first_time_only,<br />
-- only faster. It is needed, since the first_time_only attribute may<br />
-- reference variables.<br />
local first = cfg.first_time_only<br />
-- Modify the default behavior of first_time_only.<br />
if first == nil then first = false end<br />
new_cfg.first_time_only = first<br />
-- Call the engine handler.<br />
old_event_handler(new_cfg)<br />
end<br />
</syntaxhighlight><br />
<br />
(Note: The above example will only affect nested events. Toplevel events will still default to ''first_time_only=yes''.)<br />
<!-- This should probably be replaced with a better example. --><br />
<br />
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:<br />
<br />
<syntaxhighlight lang=lua><br />
function get_child(cfg, name)<br />
for i = 1, #cfg do<br />
local v = cfg[i]<br />
if v[1] == name then return v[2] end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
{{DevFeature1.13|2}} '''pairs''' and '''ipairs''' now work on vconfig objects (contrary to the above statement). However, '''pairs''' works a little differently than on plain configs (tables) - it returns only string keys (attributes in WML terms) and not integer keys (tags in WML terms).<br />
<br />
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:<br />
<br />
<syntaxhighlight lang=lua><br />
if getmetatable(cfg) == "wml object" then cfg = cfg.__parsed end<br />
</syntaxhighlight><br />
<br />
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal'''. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.<br />
<br />
== Skeleton of a preload event ==<br />
<br />
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It sets up a table ''T'' so be used for easier creation of valid WML tables. It also sets up a table ''V'' so that any access to it is redirected to the persistent WML storage. Finally, it loads a textdomain to be accessed through the ''_'' variable.<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = <<<br />
H = wesnoth.require "lua/helper.lua"<br />
W = H.set_wml_action_metatable {}<br />
T = H.set_wml_tag_metatable {}<br />
V = H.set_wml_var_metatable {}<br />
_ = wesnoth.textdomain "my-campaign"<br />
<br />
-- Define your global constants here.<br />
-- ...<br />
<br />
<br />
-- Define your global functions here.<br />
-- ...<br />
>><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:<br />
<br />
<syntaxhighlight lang='wml'><br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = << wesnoth.dofile "~add-ons/Whatever/file.lua" >><br />
[/lua]<br />
[/event]<br />
</syntaxhighlight><br />
<br />
== Remarks on Random Numbers ==<br />
<br />
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should use the [[LuaWML:Misc#helper.rand|helper.rand()]] function to synchronize random values. It takes the same argument in the same format as [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] rand=.<br />
<br />
<syntaxhighlight lang='lua'><br />
local random_variable = helper.rand("1,2,3")<br />
</syntaxhighlight><br />
<br />
Also available is [[LuaWML:Misc#wesnoth.random|wesnoth.random]], which has the same interface as math.random but is multiplayer-safe.<br />
<br />
== Random Lua table iteration ==<br />
<br />
Table iteration order ('''pairs''') is not strictly defined in Lua. If your code depends on the order of iteration, different clients may have different data in a multiplayer game. For example:<br />
<br />
<syntaxhighlight lang='lua'><br />
local table = { ["Mage"] = true, ["Wose"] = true }<br />
local concat = ""<br />
local bad_usage = next(table) -- wrong, leads to OOS<br />
for k, _ in pairs(table) do -- wrong, leads to OOS<br />
concat = concat .. k<br />
end<br />
</syntaxhighlight><br />
<br />
To avoid the problem, sort the table keys before iterating. Or alternatively, use Lua "arrays" and the '''ipairs''' function, which have a strictly defined order and never lead to OOS. Example of correct code:<br />
<br />
<syntaxhighlight lang='lua'><br />
local array = { "Mage", "Wose" }<br />
local good_usage = table[1] -- correct<br />
local concat = ""<br />
for _, v in ipairs(array) do -- correct<br />
concat = concat .. v<br />
end<br />
</syntaxhighlight><br />
<br />
[[Category: Lua Reference|*]]<br />
[[Category: WML Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Sides&diff=59287LuaWML/Sides2018-03-19T18:05:06Z<p>Vasya: /* wesnoth.sides */</p>
<hr />
<div>This page describes the [[LuaWML]] functions and helpers for handling sides and villages.<br />
<br />
==== wesnoth.sides ====<br />
<br />
This is not a function but a table indexed by side numbers. Its elements are proxy tables with these fields:<br />
* '''side''': the side number<br />
* '''gold''', '''village_gold''', '''base_income''': integers (read/write)<br />
* '''total_income''': integer (read only)<br />
* '''objectives''', '''user_team_name''': translatable strings (read/write)<br />
* '''objectives_changed''': boolean (read/write)<br />
* '''team_name''': string (read/write)<br />
* '''is_local''' {{DevFeature1.13|8}}: boolean (read). Whether the side is local. Careless use will cause OOS errors.<br />
* '''controller''': string (read/write) :<br />
:''note: In networked multiplayer, the controller attribute is ambiguous (won't be the same on all clients). Be very careful or you'll have OOS errors.''<br />
: The controller attribute has 6 possible values: human, network, ai, network_ai, null, idle. (Or less, see below.)<br />
<br />
: A local human should always be "human", a local ai should always be "ai", a remote human should always be "network". and a remote ai should always be "network_ai". An empty side should be null on all clients. <br />
<br />
: An idle side should appear similarly as a "human" side for all sides that don't own the idle side, i.e. as "network".<br />
<br />
: These values may be checked using lua, or the :controller command in game.<br />
<br />
: This value can only be set to 'human', 'ai' or 'null'.<br />
<br />
{{DevFeature1.13|8}} Remote and local are no longer differentiated by this field. For example, remote humans will be shown as "human". Use 'is_local' field if you need to differentiate.<br />
* '''fog''': boolean (read {{DevFeature1.13|7}}/write)<br />
* '''shroud''': boolean (read {{DevFeature1.13|7}}/write)<br />
* '''hidden''': boolean (read/write)<br />
* '''name''': string (read)<br />
* '''faction''': {{DevFeature1.13|5}} id of the selected faction, string (multiplayer-only, read)<br />
* '''faction_name''': {{DevFeature1.13|5}} name of the selected faction, string (multiplayer-only, read)<br />
* '''color''': string (read/write)<br />
* '''recruit''': table of strings (read/write)<br />
* '''scroll_to_leader''': boolean (read/write)<br />
* '''village_support''': string (read/write)<br />
* '''flag''': string (read {{DevFeature1.13|7}}/write)<br />
* '''flag_icon''': string (read {{DevFeature1.13|7}}/write)<br />
* '''defeat_condition''': string (read/write) See description at [[SideWML]], [[ScenarioWML#Scenario_End_Conditions]]<br />
* '''lost''': bool (read/write) If lost=true this side will be removed from the persitent list at the end of the scenario. This key can also be used to stop the engine from removing a side by setting it to false. Writing this key only works in a victory/defeat event.<br />
* '''persistent''' {{DevFeature1.13|5}}: boolean (read/write)<br />
* '''suppress_end_turn_confirmation''' {{DevFeature1.13|7}}: boolean (read/write)<br />
* '''share_vision''' {{DevFeature1.13|7}}: string (read/write)<br />
* '''share_maps''' {{DevFeature1.13|7}}: boolean (read)<br />
* '''share_view''' {{DevFeature1.13|7}}: boolean (read)<br />
* '''num_units''' {{DevFeature1.13|7}}: integer (read)<br />
* '''num_villages''' {{DevFeature1.13|7}}: integer (read)<br />
* '''total_upkeep''' {{DevFeature1.13|7}}: integer (read)<br />
* '''expenses''' {{DevFeature1.13|7}}: integer (read)<br />
* '''net_income''' {{DevFeature1.13|7}}: integer (read)<br />
* '''__cfg''': WML table (dump)<br />
<br />
The metatable of these proxy tables appears as '''"side"'''.<br />
<br />
local side = wesnoth.sides[1]<br />
side.gold = side.gold + 50<br />
wesnoth.message(string.format("%d sides", #wesnoth.sides))<br />
<br />
==== wesnoth.get_sides ====<br />
<br />
* '''wesnoth.get_sides(''filter'')'''<br />
<br />
Returns a table array containing proxy tables for these sides matching the passed [[StandardSideFilter]]. The output is the same format as the wesnoth.sides table, above.<br />
--set gold to 0 for all sides with a leader<br />
local sides = wesnoth.get_sides({ {"has_unit", { canrecruit = true }} })<br />
for i,v in ipairs(sides) do<br />
v.gold = 0<br />
end<br />
<br />
==== wesnoth.get_village_owner ====<br />
<br />
* '''wesnoth.get_village_owner(''x'', ''y'')'''<br />
<br />
Returns the side that owns the village at the given location.<br />
<br />
local owned_by_side_1 = wesnoth.get_village_owner(12, 15) == 1<br />
<br />
==== wesnoth.set_village_owner ====<br />
<br />
* '''wesnoth.set_village_owner(''x'', ''y'', ''side'', [''fire_events''])'''<br />
<br />
Gives ownership of the village at the given location to the given side (or remove ownership if none). Ownership is also removed if nil or 0 is passed for the third parameter, but no capture events are fired in this case.<br />
An optional 4th parameter (boolean true|false, default: false) can be passed determining whether to fire any capture events.<br />
<br />
wesnoth.set_village_owner(12, 15, 1)<br />
<br />
==== wesnoth.is_enemy ====<br />
<br />
* '''wesnoth.is_enemy(''side1'', ''side2'')'''<br />
<br />
Returns true if side A is enemy of side B, false otherwise.<br />
<br />
local enemy_flag = wesnoth.is_enemy(1, 3)<br />
<br />
==== wesnoth.match_side ====<br />
<br />
* '''wesnoth.match_side(''side'', ''filter'')'''<br />
<br />
Matches a side against a given [[StandardSideFilter]].<br />
<br />
wesnoth.message(tostring(wesnoth.match_side(1, {{"has_unit", { type = "Troll" }}})))<br />
<br />
==== wesnoth.get_starting_location ====<br />
<br />
* '''wesnoth.get_starting_location(''side'')'''<br />
<br />
Returns the starting location of the given side.<br />
<br />
local loc = wesnoth.get_starting_location(1)<br />
wesnoth.message(string.format("side 1 starts at (%u, %u)", loc[1], loc[2]))<br />
<br />
==== wesnoth.get_side_variable ====<br />
<br />
* '''wesnoth.get_side_variable(''side'', ''name'')'''<br />
<br />
Returns a variable stored in the side<br />
<br />
local loc = wesnoth.get_side_variable(1, "a.c[7].d")<br />
<br />
<br />
==== wesnoth.set_side_variable ====<br />
<br />
* '''wesnoth.set_side_variable(''side'', ''name'', ''content'')'''<br />
<br />
Sets a variable stored in the side<br />
<br />
local loc = wesnoth.set_side_variable(1, "a.c[7].d", 5)<br />
<br />
==== wesnoth.set_side_id ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.set_side_id(''side'', ''color'', ''flag'')'''<br />
<br />
Changes the visual identification of a side. Pass an empty string if you only want to change one of these two attributes.<br />
<br />
==== wesnoth.place_shroud ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.place_shroud(''side'', ''shroud'')'''<br />
<br />
Shrouds the specified hexes. You can pass a shroud_data string (which will be merged with existing shroud), a list of specific locations (where each location is a two-element list of x and y coordinates), or the special string "all" to shroud all hexes.<br />
<br />
==== wesnoth.remove_shroud ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.remove_shroud(''side'', ''shroud'')'''<br />
<br />
Unshrouds the specified hexes. Hexes are specified as with place_shroud, except that a shroud_data string will not work.<br />
<br />
==== wesnoth.is_fogged ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.is_fogged(''side'', ''location'')'''<br />
<br />
Tests if the given location is under fog from the point of view of the given side.<br />
<br />
==== wesnoth.is_shrouded ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.is_shrouded(''side'', ''location'')'''<br />
<br />
Tests if the given location is under shroud from the point of view of the given side.<br />
<br />
==== wesnoth.switch_ai ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.switch_ai(''side'', ''file'')'''<br />
<br />
Replaces a side's AI with the configuration from a specified file.<br />
<br />
==== wesnoth.append_ai ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.append_ai(''side'', ''params'')'''<br />
<br />
Appends AI parameters (aspects, stages, goals) to the side's AI. The syntax for the parameters to be appended is the same as that supported by [modify_side].<br />
<br />
==== wesnoth.add_ai_component ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.add_ai_component(''side'', ''path'', ''component'')'''<br />
<br />
Adds a component to the side's AI. The path syntax is the same as that used by [modify_ai]. The component is the content of the component - it should not contain eg a toplevel [facet] tag.<br />
<br />
==== wesnoth.change_ai_component ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.change_ai_component(''side'', ''path'', ''component'')'''<br />
<br />
Like add_ai_component, but replaces an existing component instead of adding a new one.<br />
<br />
==== wesnoth.delete_ai_component ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.delete_ai_component(''side'', ''path'')'''<br />
<br />
Like add_ai_component, but removes a component instead of adding one.<br />
<br />
==== helper.all_teams ====<br />
<br />
* '''helper.all_teams()'''<br />
<br />
Returns an iterator over sides that can be used in a for-in loop.<br />
<br />
Note that the method name "teams" is a historical mistake, currently left out for backwards compatibility. It has no relation to [team] tag.<br />
<br />
for side in helper.all_teams() do side.gold = 200 end<br />
<br />
[[Category: Lua Reference]]</div>Vasyahttps://wiki.wesnoth.org/index.php?title=LuaWML/Sides&diff=59286LuaWML/Sides2018-03-19T16:06:25Z<p>Vasya: /* wesnoth.sides */</p>
<hr />
<div>This page describes the [[LuaWML]] functions and helpers for handling sides and villages.<br />
<br />
==== wesnoth.sides ====<br />
<br />
This is not a function but a table indexed by side numbers. Its elements are proxy tables with these fields:<br />
* '''side''': the side number<br />
* '''gold''', '''village_gold''', '''base_income''': integers (read/write)<br />
* '''total_income''': integer (read only)<br />
* '''objectives''', '''user_team_name''': translatable strings (read/write)<br />
* '''objectives_changed''': boolean (read/write)<br />
* '''team_name''': string (read/write)<br />
* '''is_local''' {{DevFeature1.13|8}}: boolean (read). Whether the side is local. Careless use will cause OOS errors.<br />
* '''controller''': string (read/write) :<br />
:''note: In networked multiplayer, the controller attribute is ambiguous (won't be the same on all clients). Be very careful or you'll have OOS errors.''<br />
: The controller attribute has 6 possible values: human, network, ai, network_ai, null, idle. (Or less, see below.)<br />
<br />
: A local human should always be "human", a local ai should always be "ai", a remote human should always be "network". and a remote ai should always be "network_ai". An empty side should be null on all clients. <br />
<br />
: An idle side should appear similarly as a "human" side for all sides that don't own the idle side, i.e. as "network".<br />
<br />
: These values may be checked using lua, or the :controller command in game.<br />
<br />
: This value can only be set to 'human', 'ai' or 'null'.<br />
<br />
{{DevFeature1.13|8}} Both remote and local sides will appear as 'human'. Combine this value with 'is_local' to differentiate "network human" from "local human" if you need to.<br />
* '''fog''': boolean (read {{DevFeature1.13|7}}/write)<br />
* '''shroud''': boolean (read {{DevFeature1.13|7}}/write)<br />
* '''hidden''': boolean (read/write)<br />
* '''name''': string (read)<br />
* '''faction''': {{DevFeature1.13|5}} id of the selected faction, string (multiplayer-only, read)<br />
* '''faction_name''': {{DevFeature1.13|5}} name of the selected faction, string (multiplayer-only, read)<br />
* '''color''': string (read/write)<br />
* '''recruit''': table of strings (read/write)<br />
* '''scroll_to_leader''': boolean (read/write)<br />
* '''village_support''': string (read/write)<br />
* '''flag''': string (read {{DevFeature1.13|7}}/write)<br />
* '''flag_icon''': string (read {{DevFeature1.13|7}}/write)<br />
* '''defeat_condition''': string (read/write) See description at [[SideWML]], [[ScenarioWML#Scenario_End_Conditions]]<br />
* '''lost''': bool (read/write) If lost=true this side will be removed from the persitent list at the end of the scenario. This key can also be used to stop the engine from removing a side by setting it to false. Writing this key only works in a victory/defeat event.<br />
* '''persistent''' {{DevFeature1.13|5}}: boolean (read/write)<br />
* '''suppress_end_turn_confirmation''' {{DevFeature1.13|7}}: boolean (read/write)<br />
* '''share_vision''' {{DevFeature1.13|7}}: string (read/write)<br />
* '''share_maps''' {{DevFeature1.13|7}}: boolean (read)<br />
* '''share_view''' {{DevFeature1.13|7}}: boolean (read)<br />
* '''num_units''' {{DevFeature1.13|7}}: integer (read)<br />
* '''num_villages''' {{DevFeature1.13|7}}: integer (read)<br />
* '''total_upkeep''' {{DevFeature1.13|7}}: integer (read)<br />
* '''expenses''' {{DevFeature1.13|7}}: integer (read)<br />
* '''net_income''' {{DevFeature1.13|7}}: integer (read)<br />
* '''__cfg''': WML table (dump)<br />
<br />
The metatable of these proxy tables appears as '''"side"'''.<br />
<br />
local side = wesnoth.sides[1]<br />
side.gold = side.gold + 50<br />
wesnoth.message(string.format("%d sides", #wesnoth.sides))<br />
<br />
==== wesnoth.get_sides ====<br />
<br />
* '''wesnoth.get_sides(''filter'')'''<br />
<br />
Returns a table array containing proxy tables for these sides matching the passed [[StandardSideFilter]]. The output is the same format as the wesnoth.sides table, above.<br />
--set gold to 0 for all sides with a leader<br />
local sides = wesnoth.get_sides({ {"has_unit", { canrecruit = true }} })<br />
for i,v in ipairs(sides) do<br />
v.gold = 0<br />
end<br />
<br />
==== wesnoth.get_village_owner ====<br />
<br />
* '''wesnoth.get_village_owner(''x'', ''y'')'''<br />
<br />
Returns the side that owns the village at the given location.<br />
<br />
local owned_by_side_1 = wesnoth.get_village_owner(12, 15) == 1<br />
<br />
==== wesnoth.set_village_owner ====<br />
<br />
* '''wesnoth.set_village_owner(''x'', ''y'', ''side'', [''fire_events''])'''<br />
<br />
Gives ownership of the village at the given location to the given side (or remove ownership if none). Ownership is also removed if nil or 0 is passed for the third parameter, but no capture events are fired in this case.<br />
An optional 4th parameter (boolean true|false, default: false) can be passed determining whether to fire any capture events.<br />
<br />
wesnoth.set_village_owner(12, 15, 1)<br />
<br />
==== wesnoth.is_enemy ====<br />
<br />
* '''wesnoth.is_enemy(''side1'', ''side2'')'''<br />
<br />
Returns true if side A is enemy of side B, false otherwise.<br />
<br />
local enemy_flag = wesnoth.is_enemy(1, 3)<br />
<br />
==== wesnoth.match_side ====<br />
<br />
* '''wesnoth.match_side(''side'', ''filter'')'''<br />
<br />
Matches a side against a given [[StandardSideFilter]].<br />
<br />
wesnoth.message(tostring(wesnoth.match_side(1, {{"has_unit", { type = "Troll" }}})))<br />
<br />
==== wesnoth.get_starting_location ====<br />
<br />
* '''wesnoth.get_starting_location(''side'')'''<br />
<br />
Returns the starting location of the given side.<br />
<br />
local loc = wesnoth.get_starting_location(1)<br />
wesnoth.message(string.format("side 1 starts at (%u, %u)", loc[1], loc[2]))<br />
<br />
==== wesnoth.get_side_variable ====<br />
<br />
* '''wesnoth.get_side_variable(''side'', ''name'')'''<br />
<br />
Returns a variable stored in the side<br />
<br />
local loc = wesnoth.get_side_variable(1, "a.c[7].d")<br />
<br />
<br />
==== wesnoth.set_side_variable ====<br />
<br />
* '''wesnoth.set_side_variable(''side'', ''name'', ''content'')'''<br />
<br />
Sets a variable stored in the side<br />
<br />
local loc = wesnoth.set_side_variable(1, "a.c[7].d", 5)<br />
<br />
==== wesnoth.set_side_id ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.set_side_id(''side'', ''color'', ''flag'')'''<br />
<br />
Changes the visual identification of a side. Pass an empty string if you only want to change one of these two attributes.<br />
<br />
==== wesnoth.place_shroud ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.place_shroud(''side'', ''shroud'')'''<br />
<br />
Shrouds the specified hexes. You can pass a shroud_data string (which will be merged with existing shroud), a list of specific locations (where each location is a two-element list of x and y coordinates), or the special string "all" to shroud all hexes.<br />
<br />
==== wesnoth.remove_shroud ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.remove_shroud(''side'', ''shroud'')'''<br />
<br />
Unshrouds the specified hexes. Hexes are specified as with place_shroud, except that a shroud_data string will not work.<br />
<br />
==== wesnoth.is_fogged ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.is_fogged(''side'', ''location'')'''<br />
<br />
Tests if the given location is under fog from the point of view of the given side.<br />
<br />
==== wesnoth.is_shrouded ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.is_shrouded(''side'', ''location'')'''<br />
<br />
Tests if the given location is under shroud from the point of view of the given side.<br />
<br />
==== wesnoth.switch_ai ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.switch_ai(''side'', ''file'')'''<br />
<br />
Replaces a side's AI with the configuration from a specified file.<br />
<br />
==== wesnoth.append_ai ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.append_ai(''side'', ''params'')'''<br />
<br />
Appends AI parameters (aspects, stages, goals) to the side's AI. The syntax for the parameters to be appended is the same as that supported by [modify_side].<br />
<br />
==== wesnoth.add_ai_component ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.add_ai_component(''side'', ''path'', ''component'')'''<br />
<br />
Adds a component to the side's AI. The path syntax is the same as that used by [modify_ai]. The component is the content of the component - it should not contain eg a toplevel [facet] tag.<br />
<br />
==== wesnoth.change_ai_component ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.change_ai_component(''side'', ''path'', ''component'')'''<br />
<br />
Like add_ai_component, but replaces an existing component instead of adding a new one.<br />
<br />
==== wesnoth.delete_ai_component ====<br />
<br />
{{DevFeature1.13|7}}<br />
<br />
* '''wesnoth.delete_ai_component(''side'', ''path'')'''<br />
<br />
Like add_ai_component, but removes a component instead of adding one.<br />
<br />
==== helper.all_teams ====<br />
<br />
* '''helper.all_teams()'''<br />
<br />
Returns an iterator over sides that can be used in a for-in loop.<br />
<br />
Note that the method name "teams" is a historical mistake, currently left out for backwards compatibility. It has no relation to [team] tag.<br />
<br />
for side in helper.all_teams() do side.gold = 200 end<br />
<br />
[[Category: Lua Reference]]</div>Vasya