You just know sooner or later someone's going to try to use "random" for
something other than gender and some translations will end up looking
wrong as a result.
The _ locals are there to ensure that if _ is overridden anywhere else
in the enclosing scope (which I haven't properly determined *where* it
is yet) it gets overridden again with the right textdomain object.
It *does* tell wmlxgettext what the correct textdomain is without using
the `-- #textdomain` hack anyway, so might as well just do it this way
regardless of the global-looking _ in map/main.lua.
CC #5311
By default, the MAI removes movement points from units even when they cannot find a hex to move to. When this option is set to 'no' (default is 'yes'), this step is skipped, so that other candidate actions can take over.
This implements feature request #5580
In general, the units specified in the MAI setup should be on the AI side. However, that might change during a scenario, for example when there is an event that switches units to other sides.
- get_terrain and set_terrain replaced with direct indexing operations
- get_map_size mostly replaced with either the iterator or an on_board call.
Only a few cases really needed to know the size of the map for some other purpose.
- shroud and fog operations, village owner, time areas, and location filters
- get_terrain_info replaced with terrain_types table
- Map generation functions create_map and create_filter
The method of accessing terrain on the map has drastically changed.
- wesnoth.get_terrain and wesnoth.set_terrain are both deprecated
- wesnoth.terrain_mask still works but is moved into the wesnoth.map module and now takes the map object as the first parameter
- The map's terrain is now accessed exclusively via indexing on the map object, ie map[{x,y}]
- You set terrain by assigning a terrain code; the position of ^ in the terrain code now determines the merge mode
- The replace_if_failed option is now manifested as a function that converts any terrain code into a special value that, when assigned to a location on the map, uses the replace if failed logic.
The map object has a few attributes in it:
- width and height are the total size, including borders
- playable_width and playable_height are the values returned from wesnoth.get_map_size, which is now deprecated
- border_size is the third value from wesnoth.get_map_size
- data converts the map to a string
- Special locations are now part of the map object. The length operator is deprecated.
- other than that, wesnoth.map is treated as if it were the metatable of the map object
The purpose of this is to make it easy for functions implemented in Lua to handle locations
in the same way as functions implemented in C++.
The location_set module has been updated to make use of this functionality in its setter functions.
Usage example:
Imagine a function foo with the following signature:
foo(bar : string, home : location, mode : string, target : location, moo : boolean) -> boolean
With the new read_location function it could be implemented as follows:
function foo(...)
-- First argument goes in bar
local bar = ...
-- Read location starting at the second argument
local home, n = wesnoth.mP.read_location(select(2, ...))
-- note: n will be 0 if a location wasn't found at that position
-- This could be an error, or it could be handled as an optional parameter
-- Next argument after that goes in mode
local mode = select(n + 2, ...)
-- Then read a location into target
local target, m = wesnoth.map.read_location(select(n + 2, ...))
-- Finally, read a parameter into moo
local moo = select(m + n + 2, ...)
-- Do stuff with all these parameters
return true
end
With that code, all the following invocations of foo work:
foo('a', 'b', true) -- both optional locations omitted
foo('a', 1, 2, 'q', 5, 6, false) -- locations given as separate integer parameters
foo('a', 'm', {1, 7}, true) -- first location omitted, second given as 2-element array
foo('a', some_unit, 'z', {x = 5, y = 10}, false) -- a unit also functions as a location
foo('a', 7, 12, 'q', my_leader, true) -- mixing different forms also works
There were two issues with the previous method:
- ai_helper.get_avoid_map() never returns nil, but at most an empty location set. Thus, the 'else' clause in that conditional was never reached.
- The presence of an [avoid] tag should not prevent the keys ignoring enemies from taking effect. Instead, [avoid] needs to be taken into account for all possible code paths.
The final determination of the hex to move to must take enemies into account, otherwise the MAI might try to move the unit to a hex it cannot actually reach.
Numerical values are sometimes transferred from WML to Lua using the string type. This applies, for example, to very small numbers, such as 0.0000000000001. This needs to be taken into account when checking whether avoid_enemies is a number.