This updates filtering for:
* Game Load dialogue
* MP lobby
* In-game label and unit search
* Add-ons client (now used consistently)
(cherry picked from commit b316ee518b)
this is a bachport of https://github.com/wesnoth/wesnoth/commits?author=stevecotton4afdc92f13 comit because one change of behavior is to prevent crashes of game
This adds a recursion counter which runs on a per-weapon basis; if the
recursion limit is reached then the last level of recursion is assumed
to have returned false. A warning is printed (with error severity).
At the user-visible layer, that gives the following logic:
* Abilities that depend on another ability being active will be
inactive.
* Pairs of abilities, where X depends on Y being inactive and Y
depends on X being inactive, will end up with them both inactive.
The limit is defined by ATTACK_RECURSION_LIMIT in attack_type.cpp.
The minimum for passing all the unit tests is 2, but I've left some
headroom by setting it to 4.
With the recursion limit set to 1, the following tests fail, which
seems reasonable because they're checking that the special is on
a particular type of weapon.
* event_test_filter_attack_specials
* event_test_filter_attack_opponent_weapon_condition
* event_test_filter_attack_student_weapon_condition
Output from the four_cycle_recursion_branching test:
```
error unit: Recursion limit reached for weapon 'melee_attack' while checking filter 'special_type_active = parry'
error unit: Recursion limit reached for weapon 'melee_attack' while checking filter 'special_type_active = poison'
error unit: Recursion limit reached for weapon 'melee_attack' while checking filter 'special_type_active = damage'
```
There's deduplication to prevent the logfiles getting spammed during
AI turns. As implemented, the two tests mentioned below print 3
messages each; these tests are added in separate commits because the
tests are shared between PRs while we discuss the right mechanism for
guarding against recursion.
With no rate limit:
* four_cycle_recursion_branching prints 1280 logs
* event_test_filter_attack_student_weapon_condition prints 320
With a rate limit via a flag that's reset in recursion_guard's destructor:
* four_cycle_recursion_branching prints 80 logs
* event_test_filter_attack_student_weapon_condition prints 160
Resetting the flag in specials_context_t's destructor gets better numbers,
but splits the logic across .cpp files. I think the trade-off isn't worth it:
* four_cycle_recursion_branching prints 40 logs
* event_test_filter_attack_student_weapon_condition prints 132
Co-authored-by: newfrenchy83
When the user types something into the filter box and then changes to
a different version, apply the filter immediately instead of showing
the full list of files.
The drop-down to switch between directories is hidden unless savegames
from other versions are detected. The button will appear at the
bottom-left in master, and at the top of the dialog in 1.18.
(cherry picked from commit 17c202d3fb)
If a mouse click causes a delay and then a message to appear, for example
when moving a unit triggers an `[event]name=moveto`, then the message
would sometimes flash on screen and then disappear with barely enough time
to see which character's portrait was used, let alone to read it.
Although there's already logic to not be triggered by the same mouseclick that
caused the unit to move, it had a race condition if the MOUSE_UP happened
around the time the the dialog's pre_show() function was running.
Give .jpg files the same logic that .png files were given in
8f06da1974, because many files
were renamed in 51b58ad218.
UMC using the old name for images will trigger a warning, but
the player will still see the image file.
This is just a cosmetic change that doesn't change compatibility,
because have_asset("images", "blah.jpg") won't be automatically
redirected to "blah.webp".
This enables the client to show the [server_id] info (for 1.16+
campaignd instances that provide the relevant fields) in the UI so
the user can more easily know which instance they are connected to
in case they do not handle that information directly themselves (e.g.
when entering a port number of their own).
The server info shown in the bottom left is changed from "<encryption
status> <server address>" to add "— <server id> (<server version>)"
right after it, with the server version in parentheses being included
only if debug mode is enabled to avoid redundancy or confusing values
(such as "wesnoth.org — 1.18 (1.17.19+dev)").
This version uses SDL_GetTicks() as a monotonic source to avoid the
previous version's pitfalls, namely the fact that the game's framerate
may not necessarily be a constant, and in particular, the old code
assumed a completely different framerate than what we ended up with
after the texture-based rendering changes in 1.17.x, resulting in an
almost-unnoticeable text fade due to the update() function being
called WAY more often than before.
Note that the reliance on SDL_GetTicks() means the timings break
at some point after 49 days of game runtime, exactly once. This
should result in a visible "jitter" effect if the 32-bits ticks value
wraps around in the middle of a fade sequence, but other than that
it's not that big of a deal to warrant requiring SDL 2.0.18+ for the
64-bit version.
I for one hope players wouldn't be running Wesnoth for that long
anyway. The game isn't exciting enough to justify it.
This will automatically record the gender (if specified) of each
[unit], [unit_type] and [side].
The hint "gender=male,female" is often applied to [unit_type]name=,
although that's usually the male name. I believe that's the only
downside of this change.
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.
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).
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.
* units/ war harbinger: +3 HP, +2g cost, -50 XP
* units/war harbinger: removed village and forest def
* units/Dark Omen: removed village and forest def
* Units/Raven: removed village and forest def
* add changelog entry file
Fixes the display of topic headings, including unit names, in right to left
languages (Arabic and Hebrew).
The GUI1 menu code is only kept to support one UI feature, the help browser.
However, the code supported multiple columns and multiple things in each
column; to do the latter it handled each column as a string with embedded
separators. To support the help GUI, all that's needed is for each row to have
an indent, an icon, and a text field. Traces of the multiple-column support are
still in the code, but the drawing code is simplified.
The logic for working out whether mouse clicks are on the icon or the text has
moved from the subclass to the main menu class, as it's a subset of the logic
for drawing the UI.
In LTR languages, this looks almost identical.
In RTL languages, the book icons now appear in the right place, and the text
placement is reasonable.
The replaced first line added facts into canon that didn't need to be there.
Also, that text felt too similar to some real-world racism, which is why I'm
pushing this change during the string freeze.
In discussion during review, the last two lines felt more like the start of
another story than part of WoF itself.
man 5 sysuses.d recommends:
It is strongly recommended to pick user and group names that are unlikely to clash with normal users created by the administrator.
A good scheme to guarantee this is by prefixing all system and group names with the underscore, and avoiding too generic names.
Looks better without underscore. wesnoth is unique enough to not clash, most daemons on Arch don't have an underscore either.
The group is created implicitely when the user is created.
Avoids two to four function calls on each SDL_MouseWheelEvent.
Also update code comment and changelog entry based on @vgaming's report
of issue #3362 being fixed.
Slightly improves commit ab4001d. Tested again with SDL 2.0.14 and
2.28.5.
selected schedule will write to utils/schedule.cfg on scenario save
HOTKEY_EDITOR_CUSTOM_TODS is disabled unless user loads scenario
custom_tod:Preview button and associated callback added.
editor:translatable attributes now written with leading underscore
editor:support for multiple custom time schedules
The required number is already in a WML variable, herbs_needed. However, the
string is used in an `[objective]` tag, which means we're not necessarily in
an ActionWML block when it's shown, and thus can't use the Lua API to look up
plural strings. Instead, brute force it by making 6 separate strings.
Also, use the mainline `ALTERNATIVE_OBJECTIVE_CAPTION` macro instead
of a campaign-specific translatable string.
* S04b start-of-scenario saves since 1.17.21 will be broken
* S03 mid-scenario saves since 1.17.21 will show a warning,
and players will only be able to go west
* Saves from earlier versions are already broken by the campaign rewrite
The changed function is only called when using --preprocess, but calls itself
recursively. This moves the filename filter to be around the recursive call,
thus skipping the check for the top-level call.
If a unit type has male and female versions, then two images of the unit are
displayed at the top-left of the help page. However, it did this even if the
two images were the same, which made the duplication look like a bug.
The Naga Fighter is one of the affected unit types.
At the suggestion of @stevecotton, I propose a special 'replacement_type' and 'alternative_type' attribute capable of modifying the type of attack used when the conditions are met.
Also make Holy water combine arcane damage with native type of weapon
Like holy water imbued ordinary weapon, it's seem logic what arcane damage dominant what if more efficient what original type(water can't altered pierce or blading of spear or sword)
With this it puts the player back to the title screen after showing
an error dialog, so it's not much better, but at least it's not a
crash.
Fixes issue 7164. We weren't able to work out what caused the file corruption
reported, but I believe it's a race condition about saving while the AI is
recruiting. The file in the bug report has a `[snapshot]` tag with
`init_side_done=yes` but without a `playing_team` attribute, which must be the
result of `game_state::write()` when not in the `PLAY` phase. Loading such a
file causes `game_state::start_event_fired_ == false`, and triggers
`play_controller::start_game` to call `replay::add_start_if_not_there_yet`.
The i18n'd string is reused from `game_launcher.cpp`.
using overwrite_specials alone means that we have only two possibilities, either one_side is chosen and in this case if the ability used as a weapon carrying the attribute is applied to the unit (apply_to=self), the other abilities are the same type applied also to 'self' not carrying the attribute will be overwritten, but those of the opponent with apply_to=opponent will be kept in the list; or else both_sides is chosen and all abilities of the same type that do not carry the attribute will be overwritten. To be able to use the attribute in abilities like [damage] for example, it is necessary to be able to be even more selective as for a 'charge' type leadership with multiply=2.5 but which must not be combined with the classic charge and without overwriting the aute [damage] as backstab, [overwrite_filter] to only match damage with apply_to=both and active_on=offense is then interesting.
adding priority allows you to select that it ability can use its overwrite_specials attribute while the others can be overwritten in the same way as an ability without the attribute. Finally, this system makes it unnecessary to limit the use of the attribute to abilities used as weapons but also to special weapons.
give abilities support of halo or overlay so that the unit benefits from a second halo or overlay when conditions are matched
One of the things that bothers me is the permanent character of the halos of the Mage of Light and other units with the "illuminates" ability, which forces them to program only a permanent illumination applied only to the possessor of the ability.
Adding the halo attribute to ability does not change anything about the behavior of the unit, but can be used in several cases:
1 allowing the use of ""illuminates" whose activity would be variable, in this case encoding the halo in [illuminates] ability and not in the unit_type allows to modulate the appearance of the halo under the same conditions
2. Applying illumination to adjacent units, I know it's pretty cheesy but a set developer might consider it easier if the hlo display follows the same logic.
3 The halo used to illustrate the possession in the unit of a special weapon used as leadership, the halo would be used to raise the possessor of the ability.
for overlay, same logic for illustrate possession of a special weapon used as leadership, or influence on student
with the "halo_image" attribute, it is now possible to give Sun Sylph units an illumination ability with an activity depending on the incarnate sun attack instead of giving the ability and the halo via obect and therefore allowing the player to have access to the description of the ability even when it is inactive.