* Konrad on a sand hex ends the scenario (previously he needed to reach flat terrain)
* Adjust the map so there's more water before reaching the sand hexes.
scons/lua.py makes use of the vestigial luadir option from commit
e94dcecf17.
Like FindLua.cmake, scons/lua.py searches for the Lua headers and
library, instead of using pkg-config like the old scons/lua.py (removed
in commit 9929d3ca1c) did, because even though distributions typically
provide .pc files for Lua, upstream Lua doesn't. It's likely that all
distributions that compile Lua as a C++ library will also provide .pc
files, but this check doesn't rely on that (just as the CMake module
doesn't).
Unfortunately, SCons.Conftest.CheckLib() prints up to eight messages
like "Checking for C++ library lua54-c++... no" until a working library
name is found.
Also conditionally include system Lua headers in src/lua/*.h and update
documentation in src/modules/lua_README.md, src/wesnoth_lua_config.h,
and src/wesnoth_lua_config.md. The two lines about "The primary commit,
after replacing the sources," in src/wesnoth_lua_config.md don't make
sense since the instructions were updated for submodule Lua in commit
d32cfb88c4 and make even less sense now with preceding commits for
updating CMake modules.
These will be changed to conditionally include system Lua headers,
e.g. "lua.h", instead of submodule Lua headers, e.g. "module/lua/lua.h".
If a header named "lua.h" includes "lua.h", the build will fail due to
recursion.
This can't be solved using angle brackets to include system headers,
because macos builds won't find them:
In file included from /Users/runner/work/wesnoth/wesnoth/src/ai/registry.cpp:30:
In file included from /Users/runner/work/wesnoth/wesnoth/src/ai/composite/aspect.hpp:24:
In file included from /Users/runner/work/wesnoth/wesnoth/src/ai/lua/lua_object.hpp:25:
/Users/runner/work/wesnoth/wesnoth/src/lua/lua.h:4:14: error: 'lua.h' file not found with <angled> include; use "quotes" instead
#include <lua.h>
^~~~~~~
"lua.h"
Renamed with (requires GNU sed):
$ for f in src/lua/*.h; do
> git mv "${f}" "src/lua/wrapper_${f#src/lua/}";
> done
$ git grep -El -- '#[ \t]*include[ \t]+"lua/[^"]+[.]h"' src | \
> xargs sed -Ei -- '
> s|(#[ \t]*include[ \t]+"lua/)(lua[.]h")( )?|\1wrapper_\2|;
> s|(#[ \t]*include[ \t]+"lua/)(lualib[.]h")( )?|\1wrapper_\2|;
> s|(#[ \t]*include[ \t]+"lua/)(lauxlib[.]h")( )?|\1wrapper_\2|;
> '
LUAI_TRY() is an internal part of Lua that may not exist forever, and
reliance on overriding it prevents the use of system copies of Lua.
Document in lua_jailbreak_exception this requirement to call
this->store() in derived class constructors.
Also, count the luaW_pcall_internal() recursion depth and store and
rethrow jailbreak exceptions until the recursion depth reaches 0,
because:
1. luaW_pcall_internal() sometimes runs recursively (C++ calls Lua
calls C++ calls Lua calls C++), so the middle C++ layer needs to
rethrow exceptions instead of clearing them. LUAI_TRY() previously
stored them each time, but now lua_jailbreak_exception::rethrow()
needs to know when not to clear().
2. Jailbreak exceptions can be thrown while no Lua code is running.
Now that constructors store() all exceptions instead of LUAI_TRY()
storing only those caught by Lua, lua_jailbreak_exception::store()
needs to know when not to store them. Otherwise, for example,
leaving a game to return to the menu while no Lua code is running
throws and needlessly stores an exception that isn't cleared, with
two possible effects:
a. If another jailbreak exception is thrown and the constructor
tries to store it, we abort from assert() because one is already
stored.
b. Otherwise, if luaW_pcall_internal() runs without a new jailbreak
exception being thrown, the stored one is rethrown and handled a
second time (e.g. immediately leaving a new game).
The documentation for IMPLEMENT_LUA_JAILBREAK_EXCEPTION() says, "This
macro needs to be placed in the definition of the most derived class,
which uses lua_jailbreak_exception as baseclass." Storing exceptions
in constructors will require this to mean that classes that derive
from lua_jailbreak_exception must be treated as final, because of the
"assert(!jailbreak_exception);" in lua_jailbreak_exception::store().
Specifying overridden clone() and execute() functions as final in
IMPLEMENT_LUA_JAILBREAK_EXCEPTION() enforces this.
leavegame_wesnothd_error is derived from a class that derives from
lua_jailbreak_exception, so also fix this inheritance and a block that
might catch leavegame_wesnothd_error.
Wesnoth's Lua submodule is built with LUAI_TRY() defined to catch a
std::exception, push its what() string onto the Lua stack, and call the
error handler given via lua_pcall() (which push_error_handler() and
luaW_pcall_internal() set to Lua's debug.traceback()) or in Lua via
xpcall().
If lua_pcall() returns an error code, luaW_pcall() logs an error, but
only if it finds an exception string on the stack (due to an apparent
oversight in commit 3820b14eb8, version 1.9.5) and that exception
string doesn't contain "~lua:" (oversight in commit e5562a1b52,
version 1.9.0). But stock LUAI_TRY() doesn't push an exception string
onto the stack, so luaW_pcall() won't log the error.
Either way, luaW_pcall() always returns false when lua_pcall() returns
an error, so the calling C++ code works the same with either Wesnoth
or stock LUAI_TRY(). The only consequence is that strict mode doesn't
break, because the error isn't logged.
This will cause the filter_formula_unit_error test to return a result
of "PASS TEST (0)" instead of "BROKE STRICT (PASS) (9)" with stock
LUAI_TRY(). In other words, the test passes normally either way, but
strict mode doesn't break.
Fix this by making luaW_pcall() log all errors, including those without
exception strings on the stack, as well as those with exception strings
containing "~lua:".
Jailbreak exceptions thrown in Wesnoth C++ code called under Lua pcall()
or xpcall() aren't handled immediately, allowing such exceptions to
potentially accumulate and cause a failed assertion.
For example, if a user tries to quit while Lua code is running under
pcall() or xpcall(), LUAI_TRY() stores and consumes the jailbreak
exception and the rest of the Lua code continues running. If the user
tries to quit again before the Lua code finishes, LUAI_TRY() attempts to
store another jailbreak exception, which causes wesnoth to abort.
This is a longstanding bug (since jailbreak exceptions were introduced
in commit d6512a0ef5, version 1.9.5) that could affect World Conquest
and 16 of the 588 addons in 1.16 and 7 of the 141 in 1.17.
Fix this by wrapping pcall() and xpcall() to rethrow jailbreak
exceptions.
This update is just removing auto-generated text. When the empty .po files were
created, the tool filled in msgstrs for both en_GB and en@shaw. However, while
Shavian is English it uses a different alphabet with phonetic spellings.
Each [teleport] tag should have exactly one each of [source],
[target] and [filter]. Missing any of those is caught immediately
above the new conditional block, so this makes having two or more
of any of them be treated the same.
The log should maybe be made more visible, but it's a case that
can already be detected by schema validation, so validate it
there instead.
The code in teleport.cpp uses assert() in the cases that the
newly-added code in this commit catches. That's bug 8175, and
it's probably still reachable for units with teleport abilities,
so this doesn't close that bug.
The intro to this map shows Rugnur running into the stronghold, with the
elves not far behind. Those moves were running into shroud, which
generated "could not find move_unit_fake route" warnings because the
animation prefers routes that moving side can already see.
Also, have the conversation between Alanin and Rugnur take place with
Alanin on a road hex, because if he starts on the keep then he takes a
long route to avoid cave terrain.
This should prevent accidental uses of commas in fields without quotes.
It would have caught the previous issue of str.join() not quoting fields
that contain commas. For now though, it found a different issue: three
rows added in commit c631345314 had duplicated MD5 fields.
str.join() isn't smart enough to quote CSV fields when necessary, so
a field containing field separators (commas) would get parsed by the
second update_copyrights run as multiple fields. Upon finding some rows
containing an extra field, the csv.reader() object then added an extra
blank field to each of all the other rows.
Use csv.writer() instead of str.join() to write proper CSV output.
This commit also undoes the removal of commas from fields that was
necessary in commit 676c1fa2b9.
This is probably rather unfortunate in the case of the unit fields, as it may now interpret it as meaning the fields can be nil. We'll see if this causes issues.
Version 13 of GCC added the -Wdangling-reference option, however
due to false positives it had to be moved from -Wall to -Wextra.
Discussion about its status in GCC-14 is in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110075
The warning is for C++ only and the flag will generate a warning
when compiling C files if the flag is set in Scon's CCFLAGS.
The docs don't explain exactly what triggers the warning, but here's the
explanation from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106393#c1
> The warning works by checking if a reference is initialized with a function
> that returns a reference, and at least one parameter of the function is a
> reference that is bound to a temporary. It assumes that such a function
> actually returns one of its arguments! ... suppress the warning when we've
> seen the definition of the function and we can say that it can return a
> variable with static storage duration.
Consistent with that, we're getting warnings on functions of the form
find(container, const std::string&). All of the things triggering it
seem to be false positives:
* Calls to find_widget<...>.
* Calls to theme::get_theme_config.
* Calls to race::gender_value.
* In src/actions/attack.cpp, any `attacker->attacks()[i]`.
Although there's an iterator in there, the eventual reference
is to a member of the array, not the iterator.
* In src/gui/dialogs/unit_advance.cpp, `cfg.child_range("...").back()`
That returns an object indirectly owned by cfg.
We'd like the other warnings of -Wextra, so turn off -Wdangling-reference.
Standing on the runes changes some hexes to impassable,
so it's a change to the game state. It isn't a random
event, so it would be possible to add an [on_undo], but
that seems unnecessary, and would need to handle
multiple runes.
* doesn't clutter unit help tree when a unit variation is displayed
* when displaying a unit variation in the help, it displays the links
below the unit image at the same line as when displaying the base unit
patch from #6011