- 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.
* Add a Wesnoth natvis file
The change to t_string is just to make the textdomain map visible to the debugger, since it can't see variables with static linkage.
* Update tstring.hpp
* Update tstring.cpp
This includes several improvements to the retreat hex evaluation:
- Enemy threats are not the dominant rating contribution any more
- Enemy threats are based mostly on HP balance, rather than simply enemy number
- Enemy threat assessment can be modified with the retreat_enemy_weight aspect
- By default, only healing locations are considered as retreat locations, but this can be overridden with the retreat_enemy_weight aspect
The main problem was that the previous calculation was based on the 'caution' aspect. While that is not technically wrong, caution is also used for other purposes and there are mainline (and presumably UMC) scenarios that use large values for caution. In those cases, units retreated that were barely injured. This, again, might even be desirable for some use cases, but it needs to be decoupled from the other uses of caution. Thus, the new 'retreat_factor' aspect is used now.
In addition, the calculation is now based on a unit's maximum hitpoints, rather than its level.
Re-add the popup that appears when "Load" is pressed on the title screen if
there are no files, but now check for files from previous versions too.
Improve handling of switching from a version with files to a version without
files, disabling buttons on the load dialog when there are no files in the
current directory. Versions with no files will still be shown in the drop-down.
This adds a todo about the error path at the start of evaluate_summary_string,
this path is reached by creating empty files in the save dir. The dialog's state
is reasonable, so it seemed a low priority and I don't want to introduce new
bugs by refactoring this path now.
Deleting all files now doesn't automatically close the dialog.