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.
As of PR #4963, the engine ignores all global tags defined by add-ons that are not active, that is, that are not used in the current game. Whether an add-on counts as active is determined based on a list of possible tags with add-on ids. The [test] tag is not included in this list, resulting in test scenarios in add-ons not working any more.
Still a lot of work left to do, but this initial commit focuses on
bringing the UI layout on par with mainline standards.
Notable remaining layout issues:
* Training pages don't have a proper caption.
* The Items page (previously Artifacts, relabeled Items for consistency
with the rest of the help text) has individual items grow the list
horizontally out of the page's bounds, resulting in a horizontal
scrollbar on the item list right now, or one on the whole window if
anything is done to prevent the former. There is currently no simple
way to fix this since labels in listboxes and treeviews grow
unchecked, rendering `wrap = true` moot.
* The Factions page seems to be designed to display a list of factions
but this doesn't seem to be used or working right now?
* The Settings page has some evidence of this having been user-made
content. We probably want to do away with some of it in mainline.
Maybe.
* The Feedback page screams UMC all over. It is also a bit useless
without gfgtdf around right now...
* Lots of questionable English or UI language around still.
* I don't like tree views.