Ensure that there is no coroutine yield between confirmation of login
and update of player_connections_. Otherwise another login under same
name could succeed if it happened before handle_player() which resulted
in an assert later.
Copy and paste from 1.18.2's setup. The other platforms are left
unchanged, except for using new versions of Github Actions
scripts, so there's still a docker.sh and a ubuntu.sh in the
directory that macos.sh is removed from.
Only the debug and translations builds are done on MacOS. The
release build would need signing to be set up.
Prefixing all system and group names with the underscore is
recommended by the systemd developers.
This reverts commit 8b6ef6aeeb.
(cherry picked from commit 91bd96b319)
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 e628e27. Tested again with SDL 2.0.14 and
2.28.5.
The old issue #2218 was actually a bug in SDL, fixed on X11 in version
2.0.18 and on Wayland in version 2.0.20. The hardcoded workaround in
pull #2481 (commit 4bc4373) caused a regression in fixed SDL versions.
This fix is similar to the workaround in widelands/widelands#5394
committed as widelands/widelands@67db32a.
Also make mouse handler use same coordinate signs as map and fix
mouse_wheel_*() virtual method calls, which have been wrong in the X
axis since commit dfe2f33 (and unused since commit c912f7e).
Tested with SDL 2.0.14 and 2.28.5.
Cherry picked from commit ab4001d (pull #8137) in the master branch
(1.17).
Works around #7543 for developers but does not resolve it as the official Wesnoth Windows builds do not use MSVC or vcpkg.
Only necessary for 1.16 because 1.17+ uses fontconfig.
Switching to a different item cleared the data, but didn't clear the
cache of where the page breaks are located. The subsequent call to
`get_data_paged(int which_page)` has a bounds check for the page number,
so it's sufficient to just clear the page breaks, which is already ok
as it resets the object to the same state as a newly-created instance.
The files in the changelog_entries/ directory weren't processed
for 1.16.9, which resulted in them getting added to 1.16.10.
Checked for missing entries in 1.16.10 and added them too.
previously the code that tried to activate the whiteboard failed because it checks `can_modify_game_state` which checks for `!synced_context::is_unsynced`.
This moves init_side_end() further down to be called after check_victory and do_final_checkup for technical reasons. But this is safe to do since these functions only set unrelated variables and don't throw (except in case of a gamebreaking error ofc)
This fixes the window size in the dropdown menu becoming completely
out of sync as the game window gets resized by the player with the
Display section visible.
po: The rest of this commit message is for the translators' changelog, because it's notes about
what changed recently, as found by looking at fuzzies while updating the German translation.
S01 "Come on, Kaleh, we have to go see if anyone is hurt or needs help. ..." was just a grammar fix,
of "answer to the call".
UtBS S08's dialogue had Esanoo refer to Melusand as "my master" repeatedly. That changed to
"leader" or "wise leader" in 1.15.4, mainly without other changes in the text.
Other lines should have changed "master" to "leader". Will be fixed in 1.17 but not backported:
* S08 Zhul's "You don’t know where to find your master?"
* S08 Kaleh's two game-over lines because "too many merfolk have died"
UtBS S08 "You dare defy me?!..." : the change is just a typo fix
UtBS S10 "This will go much faster if you don’t interrupt me. ..." the one-word change is from "the
many" to "many" in the last sentence.
UtBS unit type Dawarf: the unit description had a grammar correction of "it's isn't"
It needs to be translatable because it needs to match the other strings that
call him by name. It was translatable until 1.15.4, and several of the .po
files that are already in the 1.16 still include it as an obsolete message, so
the next pot-update run will turn this back into a translated text in
Bulgarian, Greek, Irish, Galician, Latin, Lithuanian, Russian, Serbian and
Traditional Chinese.
C++ source files are considered to be in textdomain "wesnoth" by default.
The 1.16 CMake scripts that sort files into textdomains miss this file,
because it treats files with no `GETTEXT_DOMAIN` as being in "wesnoth",
but not ones that explicitly declare themselves in "wesnoth".
Doing a pot-update with SCons includes this file anyway, so the official
"pot-update and regenerate doc files" commits already include it, even
without this fix.
Cherry-picks the important part of 5b53be5d2a from master, making
the script use `PO4A-UPDATEPO_EXECUTABLE` instead of
`PO4A-GETTEXTIZE_EXECUTABLE`. In contrast to the master branch's
commit, this makes no changes to FindTranslationTools.cmake, so
`PO4A-GETTEXTIZE_EXECUTABLE` will still be defined in that script.
It's simply that that script has been extensively rewritten in
master, and I don't see a point in porting that part of the change.
The design of po4a seems to expect it to act as a build system,
running with a config file telling it which files to build. In
version 0.68-1, the po4a-gettextize tool has changed to error out
with a comment that it's not being run the way it expects.
See https://bugs.debian.org/1020821
po4a-updatepo works for now with 0.68-1, although it prints a deprecation
message.
Current Linux distributions tend to use udisks2 for storage device
management, which uses /run/media/USERNAME instead of /media for
gathering mount points. This commit makes this the first candidate for
enumeration of mount point collections.
This version doesn't rely on custom parsing of the version number from
the (notably *not meant to be parsed*) operatingSystemVersionString
property, and explicitly appends the version number components to the
reported string instead so we don't get weirdness like "Apple macOS
13.3.1 ((Build" from an operatingSystemVersionString value like
"Version 13.3.1 (a) (Build 22E772610a)" (found after the early May
2023 rapid response patch to Ventura).
Additionally, this replaces the clunky version comparison to decide
whether to use the macOS or OS X branding with the @available syntax.
<https://developer.apple.com/library/archive/releasenotes/AppKit/RN-AppKit/index.html>
(Under "Runtime Version Check")
Fixes#5302, planning mode now no longer tries to set the
defendings unit animation to "standing" during an attack when
there were planned moves for the defender.
This fixes:
- "Destruction mechanic line 73 bug"
- [traits] in artifacts not working
- custom effects being lost in next scenario
- artifacts reduce HP
- Promoted commander have the wrong id
The fixed are not exactly pretty, in particular the one that uses a
preload event to workaround and engine bug.
Since we are already replacing artifacts.give_item We could in theory
also explicitly fix certain Items here, should we really need to.
This caused multiple bugs:
1) custom effects were not working on recall list units because units
were created before lua initialisation (see issue #7234). This can
cause OOS when the MP "Back to turn" feature is used.
2) (rare) Possible OOS causes by unsynced traits, see the comment
in game_state.cpp before tb.build_team_stage_two()
This, instead of killing Grüü, moves him along with the others to participate
in the conversation, and also switches him to side 1 (this side is temporary
and only for narrative purposes, later on turn 7 he switches to side 4 again).
Grüü is correctly stored on the variable when the conversation ends, and
restored later on turn 7.
(cherry picked from commit cccd562cc5)
(cherry picked from commit 34a5cce2b0)
(cherry picked from commit f231348900)
(cherry picked from commit 89dbd2d373)
If the northmost hexes of the map are visible, put the text on the bottom; if
the southmost are visible, put it on the top. Also, make the text smaller if
it's very wide.
It used to be fixed to the bottom of the screen, but this meant that it always
obscured the southmost hexes of the map, and the only way to avoid that is to
scroll east/west, or to add an extra row on the south. Similarly, having it at
the very top obscures the northmost hexes.
Moving it to any fixed location that isn't the edge of the screen makes it
possible to edit all the hexes, but also makes it more annoying when working
elsewhere on the map; that trade-off was rejected in review.
For very small maps, it will be at the bottom of the screen in the border
outside the map area. For any screen resolution there will be a specific
map-height that still has the old issue, but that's an improvement on it
happening for every map size.
This function shows a tooltip-like text at the bottom of the editor's screen,
for example when the paint tool is active it shows which terrains are assigned
to the left and right mouse buttons. There is similar functionality in GUI2,
for example when hovering over the title screen's buttons, which is handled via
event::MESSAGE_SHOW_TOOLTIP.
In the 1.17 branch's 3900419f92, I checked that
nothing outside the editor was calling the function. However, that analysis was
done after 1.17's refactoring of the graphics system. For 1.16 I'm not going to
repeat that analysis; the copy that's left in video.cpp is probably dead code,
but I see little reason to remove it from the stable branch.
These orbs no longer look the same as the player's own orbs, so they
won't cause confusion in multiplayer.
The relevant part of the advanced preference now shows:
```
[ ] - Show ally orb
[ ] - During ally’s turn, use a two-color orb to show movement
Radio buttons for colors: ( ) ( ) ( ) ( ) ( ) ( ) ( )
```
That offers these choices:
* Don't show ally orbs at all
* Always use the one-color (with ally color, not status)
* Use the two-color when that ally is playing, single color at other times
* Use the two-color when that ally is playing, no orb at other times
Rename some `allied_orb` functions to be `ally_orb`. This makes them consistent
with both the names of the corresponding `enemy_orb` functions and the WML
attribute that's used in the preferences file.
This probably doesn't need a change to the in-game help, at least for the en_US
version of the documentation. The current text in data/core/help.cfg is:
* Blue for allied units, except during that ally's own turn.
* During the ally's own turn, their units will be shown with the colors showing
whether the units can still move and attack; however their moves, and the
corresponding orb changes, are delayed as explained in "Shroud and Fog of War'.
(cherry picked from commit 686e35e0e3)
Add some spacing to make it clearer what is grouped with what, move the
disengage orb's setting to be part of the partial orb's group, and add
a tooltip for it.
This dialog uses checkbox labels as section headers to indicate what the rows
of colors refer to. This commit doesn't change that, but it makes the grouping
clearer. Actual section headers would take additional space and probably not
look any better.
(cherry picked from commit d35ea2f2dc)
This is a partial cherry-pick of b9e4fdffb4,
merely reflecting that the removal has been postponed from 1.17 to 1.19 along
with updating some outdated comments.
The motivation for backporting this is to make other warnings that are printed
to stdout/stderr more visible, instead of being scrolled offscreen by the
SPECIAL_NOTES messages.
The previous bugfix fixed a crash when loading savegames with units whose
abilities accessed the map while the display_context was still being
constructed, however it reintroduced a bug in the scenario editor. Using the
unit tool always crashed when adding any unit.
This commit uses 4d1fc268b1's code path whenever possible, however it falls
back to 6a21fdc675's code path when 4d1fc268b1 would assert. In practise one
path is used in game and the other is used in the scenario editor, but doing
the logic in this way ensures that any edge cases are going to affect the
scenario editor rather than the game itself.
The island gives the player two fronts to progress on, and it's early enough
to give the player time to prepare for the SoE. Hint to them about improving
their recall list.
When trying to add that hint as a single-line change to the dialogue, I
reviewed the existing text and felt it didn't flow well. Reading the feedback
thread, Delfador should have more emotion about finding his childhood home
overrun; however I've gone for practical thoughts first.
The hint isn't #ifdef to only appear on easy, because the text wouldn't flow
without it - take that line out and it goes from "there are more orcs than I
thought" to "we must fight these orcs, who aren't the ones at the SoE". Also,
players who are already doing XP management can feel knowledgeable when they
see it.
(cherry picked from commit 9f780903ab)
Add a useful identifier to the message
error config: Skipping duplicate unit variation ID: ''
This warning is generally shown because the variation_id is completely
missing, and so the message appeared as above, without any hint of which
unit was causing the problem.
In contrast to 19a5ce83's warning, this one is printed multiple times to
stdout even if the messages are identical; therefore backporting this to
1.16 seems reasonable.
(cherry picked from commit 323ce6ec26)
The vital commit is fd766eba2b4cf59c7123d46189be373e2cee959d, but
I'm taking the most recent version of vcpkg as the new baseline
because it might as well use the latest.
The collector_base class has been deprecated in Boost 1.81, and we're compiling
with Werror on the Windows CI so it needs an immediate fix for the new vcpkg.
See 4ea7e3a7b7
(cherry picked from commit d473176f86)
Phoenix has been a separate library since Boost 1.56, and Wesnoth 1.16
already requires Boost 1.65.
* Escape < and > even if only one of them exists
In python negative index counts from the end, so without this change or another solution
"example with only < one side" would be converted to
"example with only < one sid>example with only < one side"
* Escape < and > even if found multiple times
The cause is that somehow, during regular play, MP campaigns can end up with duplicate values in the [content] data for each [addon]. A very similar issue was fixed in 6c980d1, but there's apparently some other way to trigger it that I haven't been able to reproduce. Since the error itself is harmless, it'll just be avoided server-side to avoid the spurious errors in the server log file.
Partially reverts 6a21fdc675Fixes#5643Fixes#7238
There's a bunch of global things that can be accessed either via global
pointers in the `resource` namespace, or via `display::get_singleton()`. The
singleton and these global pointers are set up in `play_controller::init`,
however there's a section where things are available via the global pointers
but the `display` singleton doesn't exist yet. During that time, checking
whether an ability is active can crash the game.
Removing the global pointers is a good goal, but detouring through a GUI class
to access the data causes its own problems.
The "has already been confirmed valid by both callers" comment is replaced with
an assert, because there's currently at least three callers.
(cherry picked from commit 7ddf691e13)
"campaign_name" is not an existing attribute in the given config anymore.
An addon should only contain a single toplevel dir tag with the name of the addon anyway.
When given a string that includes newlines but doesn't end with a newline,
the old code would get stuck in an infinite loop.
Fixes#7194.
(cherry picked from commit b5ff5c3ddc)
The movetype's special notes were becoming a new note for the individual unit.
Clean up the documentation on some of movetype's functions, as they had
documentation in both the .hpp and the .cpp.
(cherry picked from commit 38fdf06fa9)
For example, `run_wml_tests --filter backstab` runs only the tests listed
in `wml_test_schedule` that have `backstab` somewhere in their name.
(cherry picked from commit 34ae0490b1)
* Fix wmllint translation mark errors
* Added wesnoth-help domain
* Try to give better labels for the WC map generator settings which are now marked for translation.
Co-authored-by: Wedge009 <wedge009@wedge009.net>
(cherry picked from commit a667740fe5)
- coro_ read function returns empty unique_ptr on error
- coro_ write functions close socket on error
- caller does need only to handle empty unique_ptr from reads, generally
with immediate return
* DiD S8: Handle situations where factions have not yet appeared (resolves#7005).
* Convert 'arrived' flags to booleans.
* DiD S8: po hint to clarify 'Dela's men'.
* Accommodate feedback by getting rid of all the new work and just removing any reference to paladins or Dela altogether. Conversion of flag to boolean remains, however.
(cherry picked from commit 1cfb982a3c)
If it's another player's turn, then movement points will be reset in a refresh
phase and it's not useful to show current movement.
Partially reverts 978229c247 (af0968d9c3 on 1.16), using the old logic for
the movement range but the allies-based logic for goto_x,goto_y information.
Fixes#6716.
(cherry picked from commit ae4ecd17e4)
The method used in the battle_outcome() function is somewhat simplified compared to the default engine calculation and faster in the vast majority of cases, but it can become extremely slow when the combined number of strikes of the attacker and defender is very large.
When loading into different screens prior to actually starting or joining a game, Wesnoth loads the configs of all add-ons, otherwise it wouldn't know to display eras, campaigns, etc for selection. However starting with a4e8ac339e, when loading all add-ons the `active_addons_` variable was no longer being populated with any of the the add-ons that were active. This meant that when checking to see if any of the active add-ons had changed it could falsely determine that nothing had changed and therefore could skip the step where it actually deactivated add-ons.
As an example of the current state prior to this fix:
* Player starts Wesnoth and joins the multiplayer lobby -> all add-ons are active, but `active_addons_` is empty.
* Player joins a game with no add-on content required -> Wesnoth checks the add-ons required for the game (none) against the contents of active_addons_ (empty).
* Wesnoth therefore determines that it doesn't need to deactivate any add-ons since it thinks no add-ons are active, when in fact all add-ons are active.
* Out of sync errors then happen if any of the players that join have add-ons installed that can globally affect other unit_types, such as [resistance_defaults], since those add-ons haven't been correctly deactivated.
The fix then is to make sure that game_config_manager::set_enabled_addon_all() correctly populates active_addons_ when it's called.
Fixes#6650
It did not match the actual animation placement... the code was both
duplicated and wrong. I guess one part got updated and the other part
didn't.
It still needs to be deduplicated...
(cherry picked from commit 49e75f0e89)
The new method avoids a lot of path finding that the previous method did, esp. on large maps with many units and/or enemies, leading to significant speed improvements in some cases.
This fixes#6504
Events during attacks may modify either of the units involved. If, as a result, one of the units does not have a weapon of the type used any more, this previously caused a segmentation fault in unit_attack() in udisplay.cpp. The solution is to set the remaining number of strikes for the unit to zero. This prevents that unit from striking again, but lets the opponent continue its attack.
Fixes#4927 and #5914
This fixes#4924. Note, however, that the recruit rushers CA is set up for single-leader sides and does not work with multiple leaders, so this is of limited use.
While most data in recruit_data can stay persistent from turn to turn, some of recruit_data.recruit, such as enemy_types, needs to be updated each turn.
This removes the need for the Generic Recruit Engine and makes Recruit Rushers a "clean" candidate action. In the process, it fixes a bug of data leakage between the Experimental AIs of different sides.
The castle switch CA stores the leader move because the evaluation is expensive. If the leader was killed in between storing and reevaluation of the CA, this would previously cause an on-screen error message and the CA to be blacklisted for the turn.
This fixes#6440.
The probabilities being combined here are additive, not multiplicative. The two terms in the equations are the probabilities that either unit in a fight is already dead before the strike currently being evaluated. As a result, this only affected fights in which both units can die before the last round of combat. It also only affected the chance of being unscathed, the HP distributions shown were correct.
This fixes#6590.
An integral part of this MAI is that it moves weaker units out of the way for stronger ones. Units without moves are taken into account by giving them a very high rating. This was previously only done on what's considered the AI's territory (the AI side of the bottleneck) which works fine most of the time since the AI does not try to move onto enemy territory. However, it breaks down on more open maps, where there are way for units to move around the bottleneck, as AI territory is not always well defined on them. However, there is no need to restrict this to AI territory only.
This fixes#6599.
The passed filter needs to be enclosed in an [and] tag, otherwise the check for visibility might not work correctly, for example if the filter contains a top level [or] tag.
When finding the vision path for a unit, that unit's team's vision needs to be used. This had the potential of causing OOS errors in rare cases on maps with tunnels and at least three sides that do not share vision.
Fixes#6724, where scrolling with the mousewheel could reach the last row, but
scrolling with keys or buttons couldn't. Although can_scroll_up() and
can_scroll_down() already existed, can_scroll_down() didn't allow access to the
last line when that line had less than the full number of items. The mousewheel
still worked, because it ignored that logic.
Remove a feature that was seen when the last row is visible - things jumped
between columns to fill the spaces. If you have 10 items, with 4 columns and 2
visible rows then it will appear like this:
a b c d
e f g h
when scrolling down it used to move items sideways to fill the last line, which
seems bad UI because it made items harder to find:
c d e f
g h i j
the new code is simpler, and will instead show the following when scrolling down:
e f g h
i j
Move the layout code into adjust_size(), so that it runs one time when the number
of buttons changes. That could be separated from this commit, but the code
would still be touched in this commit (`counter_from_zero` would still be
replaced by `i`), so doing it and testing the changes together made sense.
(cherry picked from commit 8edd8f2292)
* Enforce encounter with the Cloaked Figure
* Revert "Avoid counting encounters with 'Cloaked Figure'."
This reverts commit ada454b20a.
(cherry picked from commit 7e87826303)
This flag was supposed to disable repair attempts for newlines in messages, however it never did so, even when the non-standard word wrap check was still available. Instead, it just disabled repair attempts for double spaces after sentence ends.
po: In SoF S09, many strings involving Krawg (a gryphon) assumed that Krawg was
the only flying unit. Similar texts have been added that are used when the player
has gryphon riders too; most of these will be marked as fuzzy versions of the
Krawg-only strings.
Things in the scenario didn't quite make logical sense considering the presence of Gryphon Riders. This resolves the issue by allowing them to trigger an event, and by acknowledging them in the endlevel dialog. Additionally, one translator hint is added for the "Smash" text when the rune is smashed.
(cherry picked from commit f82079bcc0)
The problem with this warning was that it didn't include any clue about what
had triggered it - just that there's a broken event somewhere, and it could be
in a scenario, macro, unit_type or even from another add-on if you're using a
non-default era.
When run with `--log-debug=wml`, this makes Wesnoth print out whatever the
contents of the affected [event] tag are.
Here `apply_to=opponent` means that the weapon special gives the opponent the
ability, the unit that should get poisoned or slowed is the unit that has the
weapon special.
There's a known bug in 1.16, that `apply_to=opponent` check the wrong unit to
see it it's `unpoisonable`, `undrainable` etc. It also checks the wrong unit to
see if it's already poisoned or slowed, so a battle between two units that both
have reverse-poison results in at most one being poisoned.
As 1.16 has already been released, to avoid OOS the test is checking that the
current behavior's known bug is preserved. For the 1.17 branch, the five lines
labelled `preserving known bug` will be changed to test the reverse.
Most of the credit for this is Newfrenchy's, as he's already written a fix
and a WML based test. This commit uses a Lua test instead to test more
combinations of statuses.
This adds a `COMMON_KEEP_A_B_UNIT_TEST` macro, which is a counterpart to the
`GENERIC_UNIT_TEST` macro that starts the leaders next to each other, ready
to attack. The `A_B` is because I'm planning a multiple-side variant too, and
the main reason for using separate files is Git's fuzzy-patch matching when
merging and rebasing. Having large blocks of identical text in
`wml_unit_test_macros.cfg` can mean the wrong section gets patched.
There's no test for [petrify], as simulate_combat doesn't provide a stat for it.
This tests only 3 of the 6 abilities whose behavior will change in 1.17's
equivalent of 1.16's 7b39b65606. That's sufficient to prevent any accidental
copy of the 1.17 fix to 1.16, and my thoughts on testing the others are:
* [firststrike]'s test is in 7b39b65606. It crashed, so is fixed in 1.16.
* [drains], [poison] and [slow] are tested here.
* [petrify] ends combat, it's also not exposed in simulate_combat's stats.
* [plague] triggers after combat ends.
Sadly, this takes the campaign up to 100 string changes between 1.16.2 and
1.16.3. The only one of these that was already going to change for 1.16.3 is
S04t's volcanic forge one.
As reported on the forums at https://forums.wesnoth.org/viewtopic.php?p=672374#p672374, if a unit with "last strike" ([firststrike] special with apply_to=opponent, on any of its attacks) is targeted by other unit for attack, wesnoth crashes.
Fixes#6575.
Some users of wmlxgettext have scripts that already provide the file list in
a deterministic order, and the sorting added in 2adcb92fab was choosing a
different order to the one desired.
Previously this code assumed that all add-ons would have a _server.pbl or an _info.cfg. When neither was the case, it tried to dereference the begin() of an empty set, causing the crash.
This allows storing add-on passwords for uploading in the same credentials file as is currently used by the client when connecting to a multiplayer server. For add-on authors that don't keep their passwords as plaintext in their _server.pbl, this removes the need for them to manually enter their password each time they upload an add-on.
I don't like the explanation of the tools being made of unobtainium, so changed
it to use a convenient plot device. I think this also solves a plot hole about
the forge; instead of it being near the Shorbear Caves by random chance, this
gives a reason for the Shorbear Clan to live there (even if they haven't been
in there in living memory).
(cherry picked from commit 1f41893f18)
This changes it to use the function that attack_type::get_value already uses,
thus removing a call to attack_type::weapon_specials. The latter is being
refactored by newfrenchy83 (and that refactor is expected to be backported as
it allows UI improvements).
This code is part of the object used for [filter_weapon]formula=, however the
implementation of that filter creates exactly one attack_type_callable, so
doesn't trigger this code. For testing I called it via a debugger.
(cherry picked from commit 6ccac5a5e8)
Fix another instance of issue #3059, where code assumes that all parts of the
add-ons manager's UI are accessible, an assumption that fails when the dialog
uses a stacked widget to handle small window sizes.
The up and down arrow keys select the previous or next add-on in the list,
even when the small-window layout is hiding the list. That feels like a feature
rather than a bug, as it's useful and an understandable UX; however it needs
the fix in this commit so that on_addon_select() doesn't throw an exception
and close the dialog. The new code is the same as the fix that 050feb623b
applied to on_selected_version_change, traversing the stacked widget to get the
info.
Originally this simply checked for whether the add-on's directory existed to avoid downloading the same add-on multiple times when migrating from one major release to another. However this then causes add-ons to not get updated when joining a multiplayer game where to person joining has the add-on (so the directory exists) but needs an updated version of it.
Fixes#6383
The existing code searched for `[units][advancefrom]` instead of
`[unit_type][advancefrom]`, so wasn't triggering. It was planned
for removed in 1.17, so simply mark it as already-removed instead.
The deprecation warning is shown on stdout/stderr, but not in the
in-game UI, so it's generally not visible to players. I think it
would be better if it was visible, but OTOH it's something that's
easy for someone to check all add-ons for with a simple grep.
Arguably, references to generic sceptres, as is the case with references to the Sceptre of Fire before its completion throughout the rest of this campaign, ought to use the default US English spelling of 'scepter'. This was the case in The Rise of Wesnoth where Haldric quips that the Ruby of Fire should be made into a 'scepter'.
[ci skip]
(cherry picked from commit 101359b06c)
* SoF Proofread Pass and Campaign Prose edits
This is a proofread pass. But this also has edits that are more than just minor edits which try to improve the campaign text.
commit
* SoF Proofread Second Draft
This is a changelog relative to the first draft:
- Fixed up "nor" in S1.
- reverted the ellipsis I added to indicate pause in story part of S2.
- Reworded my edit in S3 to be closer to the original.
- Followed Wedge's suggestion for S4.
- S5: Exchanged Shorbear dwarves and elves, removed introductory clause in ln 560, rewording in ln 592.
- Reverted my edit in S6.
- in S8, converted comma into ellipsis to indicate pause.
- S9: Reworded exposition of Thursagan, changed wording in ln1221, changed a period to a semi-colon.
* SoF Proofread Third Draft
* Update 4t_The_Jeweler.cfg
* Update 1_A_Bargain_is_Struck.cfg
removed a comma
* Update 1_A_Bargain_is_Struck.cfg
* More prose edits (SoF)
* Update 4t_The_Jeweler.cfg
* SoF Proofread Pass edits
* Capitalize Sceptre
* S5 and S9 small dialog change
* S6 change semicolon to period
* S9 change semicolon to exclamation
(cherry picked from commit ec66a0a832)
The notes are automatically added based on the terrain's properties,
there isn't a way to add or remove them in WML.
Any questions about negative values for gives_healing() are issue #4232.
(cherry picked from commits 1afb7effc4
and d3e1c73ca1)
The failure mode caused it to overwrite the es_ES stats
with the es_419 ones. Skipping the CI step, as this script
is only run by the pot-update targets.
[ci_skip]
Fixes the minor part of issue #6292, that functionality showing the path
to a selected hex was active after continuing an interrupted move. That
feature is completely separate to the main bug of #6292, but it looks
confusingly similar in testing. The intended way to activate this feature is
via the "Select Hex" hotkey, which doesn't have any keybinding by default, so
should only be reachable by people who want the feature.
It would be good to refactor the movement handling so that it's not split
between mouse-handling and menu-handling files, but it would also need a lot of
work and would be out-of-scope for backporting to 1.16.
Fixes#6292, that the planned final destination from multi-turn moves and
interrupted moves was visible to enemies. There are three side-numbers involved
in this logic, listed below; the GUI code was checking whether the move should
be visible to the player whose turn it is, rather to the viewing team.
* un->side(), the owner of the unit
* mouse_handler::side_num_, the side whose turn it is
* viewing_team(), the side of the player whose computer this wesnoth-client is
running on, thus which side's shroud and fog should be applied.
The plans are still hidden for units belonging to local AI sides, to hide any
goto_x,goto_y settings by campaign authors. The edge case in multiplayer of
allied network AI sides isn't tested here, but I think it's a trivial matter
whether or not those plans are shown.
Units on the recall list might have x,y coordinates that are on the map, which
therefore need to be replaced with "recall,recall" within [store_unit]. The
existing code created a temporary variable, changed the coordinates, and then
returned the unchanged original instead of the temporary.
Add a new test that `[put_to_recall_list]` followed by `[modify_unit]`
doesn't move the unit back to the map.
The current issue is that, when loading a replay that requires addons from the main menu, it's checking for which addons can be enabled with game_classification.active_addons(...) before it reloads the cache to contain addons (such as eras) that are behind the #ifdef MULTIPLAYER define. It is of course impossible to find addon content before it has been loaded, which results in things like OOS errors due to unknown unit types.
Fixes#6283
if by example, formation affect a dark Adept, and he is defender, then formation name appear in defender attack.(if name and description of formation in chance_to_hit abilities)
The MAI was set up to be blacklisted if no attacks were found, but that did not always work. In addition, removing attacks from the wolves also means that no other CA can use them for other attacks instead.
I tried to use the Wiki docs, and found the Wiki docs were outdated compared to
our codebase, which prompted this code review.
(cherry picked from commit 59df683484)
Whether or not it's the campaign being played, this warning
gets printed if any add-on has a [campaign]extra_defines=
attribute with one of the deprecated strings (a hardcoded
list about 20 lines above the line that's changed here).
Fix 'add', 'sub', 'multiply' and 'divide' not added in leadership schema validation(1.16)
* also add 'multiply' and 'divide'
This is equivalent to cherry-picking these five commits, which I intended to squash-and-merge
instead of rebase-and-merge when merging that PR to master:
* 3e70b335da
* 0813c60142
* 17e0c244ab
* 0deb6dcce2
* a202146b89
* Avoid 'punishing' the player for avoiding bloodshed by giving rebels zero upkeep costs for the scenario upon reuniting with Kaleh's side.
Resolves#6229.
Co-authored-by: Descacharrado <Luis_koopa@hotmail.com>
(cherry picked from commit 594f0cd293)
Resolves#6355.
The 'Cloaked Figure' that hounds Kaleh and friends can be encountered up to three times:
* S4 - guaranteed as his appearance is triggered by Kaleh entering the cave which is a scenario requirement.
* S5 - appearance is at a random turn during the battle between the dwarves and the trolls.
* S8 - final appearance is triggered when moving through the narrow passage.
It is possible to miss the encounter in S5 due to the randomised turn mechanic. Thus, it can be confusing when Kaleh says 'third time'.
This is just a quick work-around - another option may be to make the appearance in S5 more deterministic.
[ci skip]
(cherry picked from commit ada454b20a)
* Enforce Quenoth race to exclude Elyssa - it sounds strange for her to complain about the dark tunnels and then boast about her fireballs.
* Exclude Kaleh otherwise he can complain about the darkness and then tell himself 'we have no choice'.
Potentially could exclude Zhul as well, but it sounds fine if she complains about the darkness and then reminds Kaleh about the elves' disadvantage.
(cherry picked from commit a2a13c547e)
Add a sort inside wmlxgettext so that the order of filenames on the command
line doesn't affect the output. The sort is run unconditionally, because I
don't see a usecase for not enabling it. For consistency with xgettext and
msgcat, if there was an option to enable it then it would be called
`--sort-by-file`.
The aim of this change is to reduce the number of changes in .po files caused
by a pot-update. When multiple comments refer to the same translatable string,
separate runs of pot-update could generate them in a random order. If I've
understood the root cause correctly, wmlxgettext itself was deterministic, but
the order of the files on wmlxgettext's command line was not deterministic.
For testing, I tried reversing the sort order; the resulting reordering hit
lines that commonly swap order during pot-updates.
This affects the ordering of the lines beginning `#.` that are generated from
`#po:` comments and also those auto-generated from `[message]speaker=`, etc.
(cherry picked from commit 3761faf925)
* Ogre now dissappears before Nym starts moving/talks
* Changed the adjacency filter to fit the changes to the event
* Updated comment with a proper explanation of what occurs
(cherry picked from commit d9ea4105a6)
The statue Ras-Tabahn refers to is on the 'left' (west) from the player's perspective. However, the party is heading south, and still facing south, when this line is spoken.
Thus, the line really should say to 'our right'. Additionally, there is an animation of the statue being broken straight afterwards so it should be pretty unambiguous as to what is being referred to.
[ci skip]
(cherry picked from commit f2203a48da)
It's possible, however unlikely, for none of Ardonna's bats to have died before killing the hostile bats in 'Following the Shadow'.
In such a case, when the 'You can now raise bat corpses!' event triggers, Ardonna will still refer to the enemy bat as her 'pet' so add this condition to avoid it.
(cherry picked from commit aa6b45ee9f)
Two changes in the theme config for 1024x600, which is inherited by the config
for 800x600. Both are the same line but otherwise only loosely related to each
other; together these fix issue #6264, which was that trigger areas for some
tooltips overlapped.
Reduce the width for the unit's name, thus giving the side-flag and side-number
(which get the remaining horizontal space) enough space to display themselves.
128 pixels wide is the same as the name gets in larger themes, even though
those larger themes use larger font sizes. This means that the side number
doesn't get ellipsed, at least for games with up to 9 sides, with the
side-effect that the tooltip can be displayed when hovering over the flag.
Move the name, and thus the flag and side-number down by 1 pixel, so that they
don't overlap with the tooltip trigger areas for movement points and terrain
defense. The name's location is based on the placement of `unit-box-botleft`;
the theme for larger screen-sizes similarly adds 5 pixels of padding because
the `unit-box` is only 72x72 for the image, and the text areas for movement
points and defense go lower than that.
Removed:
* Two linux jobs - now only two combinations of the gcc/clang + scons/cmake matrix are run.
* Two macOS jobs - the Release configuration is now only run on ARM, and the Debug configuration is only run on Intel.
Also pinned vcpkg to a particular commit so it doesn't ignore the cache when new versions of dependencies come out. This does mean though that when dependencies or dependency versions change that the vcpkg commit and the cache ID will need to be manually updated. And while it's *probably* safe to have stable and master share the same vcpkg cache, this may become problematic if their dependencies and/or versions become incompatible.
Should help to address the issue with gendered verb forms or noun cases in some languages as described in #4436 . This reuses the same preexisting mechanism as in the latter part of httt_utils.cfg.
Backport of 536d6a226c
The lines about bats were converted to typographic quotes in 3fcba6aa,
which has already been cherry-picked to 1.16 as 8fcd08fc.
(cherry picked from commit d1bd5991cf
and with the fixup from 77cb1de312)
* SotA S6 Provide better tomato surprise hint. (fix#6120)
* SotA S2 Add objective note about guardhouse. (fix#6121)
* SotA S4 Add objective note. (fix#6123)
(cherry picked from commit 750d5457e0)
For the campaign The Rise of Wesnoth. For Approval. Minor edits and proofreads. `wmlxgettext` was used so as to ensure all text was reviewed.
(cherry picked from commit ef932b939f)
Only proofreading. No major edits to tone, meaning or dialog. The `wmlxgettext` module was used so that no text would be overlooked.
(cherry picked from commit dd3baa4881)
This allows switching between producing full detailed output like "2
days, 3 months, 1 seconds", and only mentioning the largest time unit,
e.g. "2 days". The default is false.
CC #6036
This uses N_n() in combination with VNGETTEXT() to get the plural forms
written to po files by xgettext.
NOTE: This is NOT a string-freeze-compliant change. Changing the strings
from being standalone to being part of a plural form set causes them to
be automatically fuzzied by the pot-update target. Merging this in 1.16
will have to wait until after 1.16.0 is released.
CC #6036
This is intended to allow xgettext to extract plural forms from the code
without actually altering the input. Basically, this is to _n() as N_()
is to _(), and doesn't actually call any gettext functions.
Was written 13 years ago. While 'the many' could be acceptable as well, there is no precedent for its use elsewhere in this dialogue. Plus the prior sentence just says 'some'.
[ci skip]
(cherry picked from commit 3ff8afa160)
Previously the invalid variable would just be rendered blank, leaving the remaining text as 'which way should we go?' which is still sensible albeit with a lack of starting capital letter.
[ci skip]
(cherry picked from commit dac45d3eb5)
According to the bonus objective as it stands, it should be possible to end the scenario early by simply destroying the 'generator' stones even if leaving a few skeletons around.
However, the way victory condition is established simply by counting the number of enemy units at the start of a turn - if there are no units left, then the stones are assumed to be destroyed. (No generator stones active -> no enemy units)
As a work-around, simply update the objectives to make it clear that all enemies need to be eliminated for victory to be achieved.
Avoid use of 'cool' and 'guys' (closes#6107)
Have left 'guys' in Camerin's lines as it's justifiable in his informal crazy talk - Northern Rebirth is supposed to be rather informal in parts and light-hearted in tone.
[ci skip]
(cherry picked from commit 1b48ace4f3)
Otherwise contradicts desert mechanic explanation: '...at the *beginning* of each your turns, every unit... will suffer from thirst...'
(cherry picked from commit b5fa99c5a3)
* Revise capitalisation as per https://wiki.wesnoth.org/ProseStyle
Capitalisation of race names was inconsistent in parts, even within the same scenario in some cases.
As per https://wiki.wesnoth.org/ProseStyle, race names are generally lower-case unless part of unit or place names, or a specific group (such as 'Quenoth Elves'):
* Elf/Elves/Elvish/Elven
* Drakes
* Dwarf/Dwarves/Dwarvish/Dwarven
* Goblins
* Gryphons
* Humans
* Mer/Merfolk
* Nagas
* Ogres
* Orcs
* Saurians
* Trolls
* Woses
I substitute 'human' for 'men' on occasion, not for PC-ness, but to make it clear it's a reference to the race, not males (non-humans sometimes say 'men' when speaking to fellow male soldiers, for example).
Capitalisation of titles is a little less straightforward. Clearly cases such as King Haldric, Queen Asheviere, Prince of Wesnoth, Great Chief, etc, are capitalised.
However, use of a title alone can be valid with or without capital, eg 'the king/King'. I try to be consistent and consider the context:
* Title is used in place of the name, eg compare 'by the King's order' with 'by Garard's order'
* Would the speaker show respect to the person concerned as their leader, or a foreign dignitary? Contrast, 'Asheviere, that vile queen'.
* Compare 'my king' with 'my father' (latter is not usually capitalised in everyday English)
* Occasionally, when the speaker may not otherwise know a character's name or the correct protocol to address, may say something like 'Sir Elf'.
I apologise if I run counter to previous revisions - removal of 'princess' as a direct address in Northern Rebirth, for example, also dealt with the capitalisation issue, if I recall correctly.
Miscellaneous changes:
* Magi, as plural of mage, is not usually capitalised.
* Council may be capitalised when referring to a specific instance, such as the Elvish High Council in the Ka'lian, but not in instances such as 'making council'.
The review focused solely on campaign prose - there may be cases in other data files where capitalisation needs revising too.
* Capitalise proper noun use of 'kingdom'.
Just as England may be referred to as such on its own, it was also known as the Kingdom of England.
In the same way, Wesnoth is usually referred to simply as Wesnoth, but it would be formally called the Kingdom of Wesnoth.
* Capitalise 'majesty' when used as an address.
For consistency with existing instances of 'Your Majesty'.
* Capitalise 'Land of the Dead'.
While we might not normally refer to such as a place as a proper noun, Delfador's Memoirs seems to establish this as a specific location in Wesnoth lore.
For consistency, also capitalise a few references to this place in Northern Rebirth and Son of the Black-Eye.
(Granted, this does make Iliah-Malal's line in DM S18 seem a bit awkward, contrasting with 'land of the living', but the precedent has been set throughout the rest of the campaign.)
* Capitalise instances of the Book of Crelanu.
I leave book as lower-case when it's not yet famously known as the Book of Crelanu, such as in Legend of Wesmere, as well as in DM S15, where it is simply described as a book belonging to the old mage Crelanu.
* Harbour of Tirigaz does not appear to be a formal (capitalised) name.
In S12, Tirigaz is only described as a 'harbour'. Other instances of Tirigaz describes it as (lower-case) a port city.
[ci skip]
(cherry picked from commit 9cd5503338)
This string appears to be untouched for 13 years so hard to ask for the original intent but it doesn't appear to be an intentional attempt to sound archaic.
(cherry picked from commit 71ebeb8eb4)
I don't really like this solution, since as mentioned in #3729, while this works for players
in the lobby, since lobby_info.users isn't updated while a player is in staging/join, anyone
who joins the lobby (or your game) after your create or join a game won't get included in the
autocomplete list. BEeides, I don't like the idea of exposing the full lobby_info object here
just for the user list, but it at least gets ac working and not crashing.
I haven't added changelog entries for:
* 297ee3d1 campaignd more args to setattr - not sure what to say here
* 08f1890b and 5f0d1848 - they're just clean-ups
* 02db53c9 UI for abilities with apply_to=opponent - I'm calling for it to be reverted
* 100045c0 string changes for MP - PR already opened to revert this
Change back to handling the height in our code instead of expecting Pango to
handle it. Pango is still expected to handle the maximum width, as Pango needs
to handle the word-wrapping.
While writing f282eb7, I had noticed that set_maximum_height called
PangoLayout's pango_layout_set_height, and removed the apparently unnecessary
enforcement of the maximum height from our wrapper code. The documentation
added in this commit explains why that was incorrect.
This fixes the bug that some tooltips on the sidebar stopped working. The text
on that sidebar is densely packed, and while this commit makes no visual
change, it removes a few blank pixels of padding below the text. That extra
padding was sufficient for the next line's area to overlap, making
tooltips::add_tooltip remove the previously-added tooltip.
It's undefined behavior to access an iterator after calling std::map::erase(),
the correct method is to use the new iterator that erase() returns instead.
Generally if we catch exception but continue the loop the player
associated with it would be automatically disconnected either due to
socket_ptr going out of scope or scope_exit calling remove_player().
This fixes crash in response to server_shutdown exception getting
thrown, as well as any other exception, that happens if there are any
players logged on.
With these two lists emptied, is_simple() will always return false, and the
code will always use the slow path. The slow path is slow because it stores and
unstores the unit, triggering the desired side effects of unstoring a unit.
Fixes issue #5133, and tests that with the new unit test.
Fixes bug #4978, that changing the facing wasn't updating the display.
I can't reproduce the issue (it selects the first option by default for me even
without this), but this probably fixes#6038 "When you have a long list of
[message][option], it will default to highlighting the 3rd entry for some
reason."
Reportedly Windows 10 20H2 and later record the feature release id into
DisplayVersion and leave ReleaseId stuck at 2009 for some mysterious
reason. Windows 11 currently will identify itself as Windows 11 21H2
based on this information.
Previously, a corrupt .mo file caused the game to exit immediately. This meant
that a broken add-on could stop the user from reaching the main menu, a
situation that could only be recovered by editing the preferences file or by
deleting the add-on with a file browser.
The engine generates the locale 3 times:
* once with no .mo files loaded
* once with only the mainline .mo files loaded
* once with all .mo files loaded
This means that:
* starting Wesnoth with a corrupt .mo file in mainline will make the engine run
showing en_US text
* changing language with a corrupt .mo file in mainline will make the engine
stay in whatever language it had successfully loaded
* a corrupt .mo file in an add-on will disable .mo files in all add-ons, but
leave mainline translations active, and will let the user play the game
Steam's scout image provides way too old openssl library version which doesn't
doesn't properly handle recent expiry of one of root Let's Encrypt
certs.
Set game::owner_ to past-the-end iterator when game is being destroyed
to avoid comparison with invalid iterator when remove_player() is called
for other players after game host has disconnected making game::owner_
invalid.
Those changes are in master but not in 1.16 due to the string freeze (pending #5973).
Unfortunately these changes are already published in places like Steam...
[ci skip]
Issue #6125 - UtBS S2 Across the Harsh Sands Pinnacle Rock is covered during dialog fix. Now the camera will scroll to the tile where the "Pinnacle Rock" map label is.
(cherry picked from commit ade778cab0)
* some tent variations
* dead great tree variations
* Stone tile (Irs) to water/swamp transition, and raise Irs transition layers over swamp water and underground paths
* change when muted-blue waterfalls are applied
Also shows campaign-specific difficulty for MP games.
* Test scenario: No difficulty -> —
* Pre-1.15 Tutorial: No difficulty -> —
* SP Campaigns: Custom difficulty -> no change
* MP Campaigns: Plain difficulty -> Custom difficulty
* MP Scenario: No difficulty -> —
Save Game Before After
--------- ------ -----
Test scenario Medium —
Tutorial (1.14 Tutorial) Medium —
Tutorial (1.17 Campaign) Tutorial (Beginner) Tutorial (Beginner)
MP single scenario Medium —
SP campaign (HttT) Commander (Normal) Commander (Normal)
MP campaign (HttT) Medium Commander (Normal)
SP campaign (LoW) Lord (Challenging) Lord (Challenging)
MP campaign (LoW) Medium Lord (Challenging)
Using — follows precedent in MP Staging, plus has the benefit of not breaking the string freeze in lead-up to 1.16 release.
It appears double zoom_factor scaling results in units being drawn way off their actual hex at high zoom, for tiles with a large (~20 pixels) unit height offset parameter.
For consistency. Also because square brackets are ugly and not standard
punctuation in English.
This is not a string freeze-breaking change. Ironic, I know.
This makes the Language button use one of the new title screen button
definitions so it has an actual label in addition to its icon. However,
it also makes the label dynamic to reflect the current language choice.
More specifically, it reflects the current locale's language name, which
turns out requires a surprising amount of effort on our part to obtain.
These buttons have an icon like normal action buttons do, but they also
keep their text label and use a smaller font. Currently only one
instance is provided, for the Language button.
When a unit has an ability that's a weapon special (ie: firststrike as an ability), and when that ability affects the opponent, the ability's name is shown on the attacking unit's weapons in the attack dialog.
* Pango changed its definition of 'green' in version 1.32.2 to align with CSS specifications (see #4348 for details).
* This change focuses only on instances of '<span color="green">', leaving instances of named colours that don't use 'green'.
* Problem: Cannot use this approach with '<format>' (at least not that I'm currently aware) so it breaks time-of-day bonus colour consistency.
(cherry picked from commit 57cfcf87d7)
Even though units are not dehydrated in subsequent scenarios, the dehydration icon may otherwise still appear in the side-bar without this.
(cherry picked from commit 4c9e016fa3)
This affects operation of dsngettext() and its users (e.g. _n() and
VNGETTEXT()) specifically when the plural version of a string is chosen.
Apparently back in 2007 in commit 4852283ab3,
this function and its late sibling were made to only strip carets from
singular forms under the probable assumption that disambiguation won't
be needed for plurals because of the way GNU gettext pairs them with
their singular msgid under a single unique entry. Like everything else
related to our gettext functionality, this wasn't documented in the C++
code.
However, there's no guarantee that this will remain the case forever if
we some day decide to replace the GNU gettext format with something
without this guarantee. It's also likely to confuse more people later
down the line (especially now that the Lua API exposes this
functionality).
Closes#6093.
* Ignore auto-generated Steam file in save directory
'The file steam_autocloud.vdf will be created in each location specified by your Steamworks cloud paths. This file file is used by Steam, and can be ignored by your game.'
Reference: https://partner.steamgames.com/doc/features/cloud
* Rephrase commentary to avoid any allegation of copyright infringement.
(cherry picked from commit 52c6d7eafe)
Macros with very generic names such as "STR_CASTLE" were defined and not
undefined. This prefixes all of them to be WC_STR_CASTLE, etc.
Either fixes or reduces the severity of #6062.
Fixes the currently suspected root cause of #5108, but requires further testing
to confirm that it fixes that issue.
Closes#6501 (the question of how to test the mapgen filter).
This reverts commit a9906226a7.
It turns out that this breaks simple_wml, so even though it's an improvement for
offline serialization, it can't be done at this time.
If this is non-explicit, then the following code:
optional_reference<config> ref = ...;
auto str = ref["key"]
results in ref being converted to bool and used as an index into the key string.
Until a proper solution is found for #5228 , this will have to do. It suppresses the appearance of the era in the era selection list for other scenarios.
Hmm, I guess the [campaign] tag should support the allow_era= key in future but for the moment, this will do.
This foreshadows that the player will need to attack the north-west after
defeating the north-east enemy, which is a bit fairer to anyone playing this
scenario for the first time.
Removes a now-unused string (Darius' pre-sacrifice speech). There are no new
strings here, the others are just being moved around.
For clearing shroud, change to using radius= because clearing a circle looks
better than clearing a square.
There's no significance to whether the new plan is "Plan B" or "Plan C" - back
in Wesnoth 1.10 it seems to have been dependent on whether all the merfolk had
been rescued.
Fixes issue #5540 about Hekuba spawning on a water hex.
This doesn't scale the campaign image (and the campaign images are generally
350x350 images anyway), so it looks a bit wrong, but it's a lot more useable
on HDPI than putting a 1050x750 limit on a treeview with a text panel.
(cherry picked from commit 62a8bad97c)
Remove the maximum size for the character-select dialog, the window will
automatically choose the minimum size that fits the text.
Extend the map 1 hex south. This means that, if the full map fits on screen,
the horizontal center of the map (where the print statements appear) is between
the keep and the south village, thus their labels don't overlap the print
statements.
(cherry picked from commit 25052e967e)
This dialog works by setting variables in the postshow function,
so the code had to be moved around to ensure that those variables
were synchronised, not just the return value of the dialog.
The message about not having enough gold isn't necessary for the
replay, so that gets moved into the synchronised code too.
(cherry picked from commit 9369b520e7)
This avoids showing the dialog during replays, and thus avoids an
OOS if the person watching the replay chooses the other character.
(cherry picked from commit 3d50320369)
This additionally:
* Makes all copyright notices identical aside from the starting year for Wesnoth-specific source files. Files not included: mariadbpp, lua, spirit po, xbrz, and bcrypt (crypt_blowfish).
* Removes all attribution from the files, since the vast majority of them are outdated or seemingly just outright incorrect. For example, I would guess that Dave is no longer the sole author of the majority of Wesnoth's current code.
A player can follow Dacyn's instructions to the letter, yet get
killed if they choose a village 2 hexes away from the Quintain on
turn 2.
There are better suggestions about handling this in
https://r.wesnoth.org/t54644 , however during the string-freeze
let's simply make the Quintain stay on its starting spot on turn 1.
Add a CLEAR_PRINT because the player has just completed the
"End your turn" instruction.
The old ai.synced_command function always set the AI-context game state to changed when executing such a command. This was inadvertently omitted when the implementation was changed to invoke_synced_command in fef953a4. While custom synced commands may or may not change the game state and the engine has no means of determining this correctly in all cases (meaning that neither behavior is technically wrong), the fact that the behavior was changed should be considered a bug. This commit changes it back to how it was before fef953a4.
Prior to this, if any .po file included a \v (vertical tab), then the game
exited before reaching the title screen. It didn't have to be in a mainline
translation - any add-on could break the game, and would do so before the title
screen appeared, thus preventing the user from using the add-on manager or
language selection to avoid the problem.
Instead, treat a parsing error similarly to the .po file simply not existing.
Fixes#5923.
(cherry picked from commit 23a0377b56)
The edge-case of calling evaluate_single within an unsynced event was
surprising, and I'm not sure it's correct. However, as we're about to
release the 1.16 branch I think it's better to include that as a test
that the API doesn't change during the stable branch.
(cherry picked from commit f9fc806fd2)
Bug #5923 is that a broken .po file can make Wesnoth fail to start, not
even reaching the title screen. Additionally, the error message printed
to the console just said "*timestamp* error general:", and then missed
the details of what had broken.
This commit fixes the error message to show which add-on and which line
are causing the problem.
(cherry picked from commit eaa39d653b)
xcodebuild CODE_SIGN_IDENTITY=""CODE_SIGNING_REQUIRED=NO -project "The Battle for Wesnoth.xcodeproj" -target "The Battle for Wesnoth" -configuration "$CFG"
set(CMAKE_CXX_FLAGS "/W3 /WX /wd4503 /wd4351 /wd4250 /wd4244 /wd4267 /we4239 /wd4275 /EHsc /utf-8" CACHE STRING "Global flags used by the CXX compiler during all builds." FORCE)
set(CMAKE_C_FLAGS "/WX" CACHE STRING "Global flags used by the C compiler during all builds." FORCE)
# -DNDEBUG is automatically added to all release build types, so manually remove this define from the related variables
@ -475,16 +477,30 @@ endif()
#
if(ENABLE_GAME OR ENABLE_TESTS)
# TODO: SDL2::SDL2 etc component target available with cmake 3.19+
find_package(SDL2 2.0.8 REQUIRED)
find_package(SDL2_image 2.0.2 REQUIRED)
find_package(SDL2_mixer 2.0.0 REQUIRED)
find_package(VorbisFile REQUIRED)
find_package(PkgConfig REQUIRED)
if(NOT MSVC)
# for everything else, use pkgconfig
# find_package can't be used for SDL2 since at least as of Ubuntu 20.04 they forgot to include the sdl2-config-version.cmake, so cmake can't tell if it's >= 2.0.8 and thus rejects using it
# meanwhile SDL2_image and SDL2_mixer don't seem to have any cmake configuration available at all
# the best I could find is that the more modern cmake module support is only available if you build SDL2 yourself instead of using a distro-packaged version
# still wouldn't help for SDL2_image and SDL2_mixer though
@ -70,6 +70,8 @@ See [here](https://github.com/wesnoth/wesnoth/blob/master/projectfiles/Xcode/REA
### Windows
Wesnoth uses CMake for project configuration and vcpkg for installing dependencies. See [here](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio) for information on using Visual Studio with cmake. The first time it's run, vcpkg will build all the required dependencies which may take over an hour, however it will only need to be done once.
NOTE 1: You will need a Windows implementation of pkg-config present in your PATH, such as [pkg-config-lite](https://sourceforge.net/projects/pkgconfiglite/).
## SCons Build
Unlike CMake or the classic "autotools" build-system (configure && make),
**The Battle for Wesnoth** is an Open Source, turn-based tactical strategy game with a
high fantasy theme, featuring both singleplayer and online/hotseat multiplayer
combat. Fight a desperate battle to reclaim the throne of Wesnoth, or take
hand in any number of other adventures.
**The Battle for Wesnoth** is an Open Source, turn-based tactical strategy game with a high fantasy theme, featuring both singleplayer and online/hotseat multiplayer combat. Fight a desperate battle to reclaim the throne of Wesnoth, or take hand in any number of other adventures.
Community
---------
License
-------
The official Battle for Wesnoth Forums:
<https://forums.wesnoth.org/>
Please see the wiki for information regarding The Battle for Wesnoth's licensing:
Additionally, Wesnoth is available for [iOS](https://apps.apple.com/us/app/battle-for-wesnoth/id575852062) and [Android](https://play.google.com/store/apps/details?id=it.alessandropira.wesnoth114).
To build the game from source, see [INSTALL](/INSTALL.md) for instructions.
Contributing
------------
Wesnoth is most in need of skilled C++ developers (C++14 and later), however there are things that nearly anyone can help with from simpler tasks in C++, the Lua and WML used for content scripting, Python used by various external tools, and even things like play testing and giving feedback on updated campaigns. Additionally, Wesnoth lacks art for a variety of unit animations - anyone who would be interested in lending a hand updating existing unit sprites or creating animations should take a look at the Art Forum as well as contact our current art director.
See also: [CONTRIBUTING](/CONTRIBUTING.md)
For any questions, the best place to start is to simply join Wesnoth's forums, Discord, or IRC and start asking!
Donations
---------
Donations can be sent via [Liberapay](https://liberapay.com/Wesnoth) as well as when downloading through itch.io. All money donated is used to pay for project expenses such as server rent and art commissions, and is very much appreciated.
License
-------
All source code is licensed under the GNU GPL v2+. Most art and music is also licensed under the GNU GPL v2+, however new contributions are now licensed under the Creative Commons BY-SA v4.0. For more detailed information on Wesnoth's licensing, see the wiki:
<https://wiki.wesnoth.org/Wesnoth:Copyrights>
More Information
----------------
For extensive documentation about all aspects of the game, see the
official Battle for Wesnoth web site.
For extensive documentation about all aspects of the game, see the official Battle for Wesnoth web site:
<https://www.wesnoth.org/>
<https://wiki.wesnoth.org/>
A (translated) description of how to play the game can be found in
doc/manual/manual.*.html, or online at:
A (translated) description of how to play the game can be found in doc/manual/manual.*.html, or online at:
<https://wiki.wesnoth.org/WesnothManual>
The official Battle for Wesnoth Forums (with over 400,000 posts from more than
20,000 registered members) can be found at:
For information on creating your own maps, scenarios, and other content, see:
* Run wesnothd server as `_wesnoth:_wesnoth` instead of `nobody:users`, improving safety and fixing a warning message in systemd 246+
### Translations
* Updated translations: Czech, German, Italian
### Miscellaneous and Bug Fixes
* Fix a regression from 1.13.11 that inverted horizontal scrolling with SDL versions 2.0.18+ on X11 and versions 2.0.20+ on Wayland (issues #3362 and #7404, PR #8158)
## Version 1.16.11
### Translations
* Updated translations: Arabic, British English, Bulgarian, Chinese (Simplified), Czech, French, Japanese, Polish, Slovak, Welsh
### Miscellaneous and Bug Fixes
* Fix a crash in the `:inspect` window when pagination is used (issue #7851).
* Fix "Something is wrong with the addon version check database supporting the multiplayer lobby".
Note that It also required the host of the game to use wesnoth 1.16.11
## Version 1.16.10
### Campaigns
* Under the Burning Suns
* S03: Ensure all of Garak’s attacks are changed to fire type (issue #7774).
* Make the name of the dark assassin translatable again (PR #7675).
* Added po hints (translation hints).
* World Conquest
* Fix lua error at victory after promoting a replacement commander (issue #7823).
* wmllint now validates `rank=` values in `[campaign]` (issue #7224)
* Add disconnect check to alert users when they lose connection to the multiplayer server (issue #1336)
* Fixed a crash when checking if abilities are active during game initialisation after loading a saved game. (issues #5643, #7238)
* Fix a crash when an out-of-bounds side number is used in Lua’s `sync.evaluate_multiple` (PR #7222)
* Fixed special notes being duplicated when storing units (issue #7153).
## Version 1.16.6
### Translations
* Updated translations: Arabic, British English, Bulgarian, Chinese (Simplified), Chinese (Traditional), Czech, French, Italian, Japanese, Portuguese (Brazil), Russian, Swedish, Turkish
### Miscellaneous and Bug Fixes
* Fixed drake flare leadership animation over water (issue #3996)
* Fixed animations not clearing properly when zoomed (issue #6589)
* Fixed the `{IS_HERO}` macro to avoid losing the hero ellipse when a unit levels up
* Fixed highlighted movement range when hovering over units after their owner ends turn. It now shows their max movement next turn, instead of the remaining moves from their previous turn. (issue #6716)
* Fixed out of sync errors occurring when unused add-ons contain the [resistance_defaults] or [terrain_defaults] tags (issue #6650)
## Version 1.16.5
### Miscellaneous and Bug Fixes
* Fixed frequent crashes occurring in multiplayer matches (issue #6863).
## Version 1.16.4
### Campaigns
* Eastern Invasion
* S07a:
* Better handling for side 2 (issue #4145)
* Fixed Grug upkeep, added dialogue about ogres joining (issue #4145)
* Northern Rebirth
* S1: Fixed Al'Tar confusing an orc for a slave (issue #6735)
* Under the Burning Suns
* S5: Enforce encounter with the Cloaked Figure (issue #6364)
### Translations
* Updated translations: Arabic, British English, Chinese (Traditional), Czech, Polish, Finnish, French
### Units
* Fixed Warden’s and Arbiter’s animations popping on water tiles (issue #6508)
### User interface
* Resolved broken layout in some low-resolution configurations (issue #5620, #6544)
### Miscellaneous and Bug Fixes
* Fixed path finding visibility bug that sometimes caused OOS errors on maps with tunnels and at least three sides that do not share vision (PR #6744)
* Fixed being unable to interact with units when Scroll Lock is active (issue #6759)
* Removing the Protect Unit Micro AI no longer causes a Lua error
* Fixed chance of being unscathed in damage calculation for some fights in which both units can die (issue #6590)
* Fixed visibility bug in ai_helper.get_attackable_enemies() for some complex filters
* Fixed bug in Bottleneck Micro AI involving units without moves on terrain with multiple open passages (issue #6599)
* Fixed error in Castle Switch CA of the Experimental AI after a leader was killed (issue #6440)
* Fixed error in retreat-injured CA when regenerate ability code does not include a value= key
* Retreat-injured CA no longer takes villages from allies
* Experimental AI no longer uses generic_recruit_engine: fixes a data leakage bug between Experimental AIs of different sides
* Experimental AI recruit rushers: include unit types from extra_recruit (issue #4924)
* Fix segfault when weapon is removed during attack (issues #4927 and #5914)
* Add no-unit error message for unit debug command (issue #6116)
* Significantly improve efficiency of move-to-any-enemy CA
## Version 1.16.3
### Add-ons client
* Fixed: using the up or down arrow keys in small-screen mode returned to the title screen (issue #6485).
* Add-on passwords that are not stored in the `_server.pbl` can now be stored in the same credentials file as multiplayer passwords (PR #6543).
### Campaigns
* Delfador’s Memoirs
* S11: Finding Chantal will now share her side’s vision with the player, as originally intended.
* S14: Smoother appearance of enemies and added dialogue (#6176).
* Descent into Darkness
* S08: Prevent Spectral Servant from picking up the book (issue #6576).
* Northern Rebirth
* S05a_01: Solve units getting stuck in the wall before the spider chamber (issue #6607).
* Sceptre of Fire
* Fixed Thursagan's Arcanister advancement being "lost" after dismounting a minecart.
* Improvements and spelling corrections to the English prose text (PR #6177).
* S9: Allow Grypon Riders to complete the scenario (issue #6332)
* Son of the Black Eye
* Improvements and spelling corrections to the English prose text (PR #6166).
* The Rise of Wesnoth
* S22: Fixed the possibility of a misplaced dialogue when a bridge was broken (issue #6376).
* Under the Burning Suns
* S08: Kromph and the Dust devil now trigger a critical event (issue #6211).
* World Conquest
* Updated the modding instructions, helping add-on authors add extra factions etc.
### Editor
* Add documentation for the magenta D and special terrain overlays (PR #6460).
* Added some missing terrain groupings (issue #6643)
### Multiplayer
* Fixed updating add-ons when joining a game that requires a new version (issue #6383).
* Add a `/clear` command for the lobby-chat window.
### Packaging
* flatpak: update freedesktop runtime version to 21.08 (issue #6497).
### Terrain
* Better transition for Swamp to Icy Cobbles (PR #6491).
* New graphics variations for icy and rocky terrains.
* The help browser adds special notes for castles and healing terrains (PR #6461).
### Translations
* Updated translations: British English, Bulgarian, Chinese (Simplified), Czech, French, Italian, Japanese, Portuguese (Brazil), Russian
* Fixed the stats for Spanish being overwritten by the stats for Spanish (Latin American).
### Units
* Saurian sprites cleanup (PR #6450).
* Various small sprite updates for sea serpents and swamp lizards (PR #6452).
### User interface
* Mark the Plan Unit Advance mod as MP-only so it doesn't show up as available for campaigns.
### Miscellaneous and Bug Fixes
* wmlscope can now report about calls to deprecated macros when using the `--unresolved` switch.
* wmlxgettext’s old behavior of processing files in the order they’re given on the command line can be selected with the `--no-sort-by-file` option (PR #6586).
* Fixed a crash with "laststrike" (firststrike given to the opponent) weapon specials (issue #6575).
* Fixed a crash with locally-edited add-ons that had neither `_server.pbl` nor `_info.cfg` (issue #6389).
* Added more unit tests for weapon specials.
* Resolve crash on systems using musl implementation of libc (issue #6603)
* The `--stringfreeze` (`-Z`) command line flag has been removed from wmllint.
* The checks for the old special notes system have been removed from wmllint; the `notecheck off`, `notecheck on` and `match <ability> with <note>` magic comments no longer have any effect.
* Resolved title screen flashing during the loading screen (issue #2395)
* Fixed erratic keyboard and mouse scroll speed (issue #3607)
* wmllint automatically removes the obsolete lines `{SOUND:SLOW}` and `{SOUND:POISON}`
## Version 1.16.2
### Campaigns
* Delfador’s Memoirs
* S07: Clarified objectives (issue #5608) and remove End Turn being required to trigger victory (issue #6173)
* Descent into Darkness
* S08: Prevent possibility of Darken Volk advancing to Lich (issue #6351)
* Heir to the Throne
* S05b: Temples given an aged appearance to match ‘ancient temples’ description (issue #5576)
* Sceptre of Fire
* Added notes about Thursagan’s rune mechanics
* S04: Mining objectives are much clearer now (issue #6154)
* Secret of the Ancients
* S06: Ardonna should no longer mistake hostile bats as ‘my pet’
* S20: Directions “left” and “right” in character speech now use the character’s orientation, not the player’s
* Consistently capitalise the name of the Academy of Magic (issue #6310)
* The Rise of Wesnoth
* S08: The appearance of Naga is now smoother (issue #6140)
* S19: The troll’s gold is automatically collected upon victory if not already obtained (issue #6141)
* S19: Avoid units spawning over chasms
* Under the Burning Suns
* Correct Traveler’s Ring description (issue #6043) and add an icon overlay (issue #6126)
* Remove the “formation” ability from the attack predictions dialog, as it was in a confusing location; its effect is still shown in the calculations and chance-to-hit percentage (PR #6326)
* S02: Pinnacle Rock is now shown during dialogue (issue #6125)
* S04: Improve dialogue about dark underground tunnels (PR #6345)
* S06b:
* Account for non-elvish units encountering Dwarf Sergeant (issue #6196)
* Grog will not die as quick now (issue #6196ᠵ)
* Hermit dialogue cannot be accidentally skipped now (issue #6196)
* Fixed bug where tentacles would not spawn (issue #6196)
* Fast units cannot get stuck on the wall now (issue #6196)
* Camera now moves to where the charges are blown up (issue #6197)
* Fixed weird scout AI behaviour (issue #6196)
* S09: Rebels joining Kaleh’s side are now loyal (issue #6229 and #6365)
* The last unit killed to trigger certain events should no longer linger during those events (issue #6341)
* The Dark Assassin’s race is not revealed until uncloaked (issue #6213)
* The Dust Devil’s XP bar is now blue (issue #6212)
* World Conquest:
* Fixed for Winged Scepter not giving the correct defence values
* Corrected the attack icon of ice bow from a lightning bolt to an iceball
### Multiplayer
* Lobby joins are no longer displayed in chat even when that preference has been disabled (issue #6234)
* Added a specific prompt for moderators before joining password-protected games (issue #4101)
* Fixed add-ons not getting enabled for clients, leading to errors such as Unknown Terrain (issue #6285)
* Fixed an information leak where planned multi-turn moves could be visible to enemy players (issue #6292)
* Made planned moves visible to allies; this refers to trying to move more hexes than the unit can move this turn, it isn’t the whiteboard (issue #6292)
### Lua API
* Fixed an error in `gui.get_user_choice()` and added support for the current DescriptionWML syntax (PR #6247)
### Translations
* Added translations: Spanish (Latin American)
* Updated translations: British English, Chinese (Simplified), Czech, Finnish, Italian, Japanese, Portuguese (Brazil), Scottish Gaelic, Turkish.
* Lots of corrections of typos in `en_US` (untranslated text), which will require marking translations as `non-fuzzy` again
* Comments in .po files are now kept in order when the .pot is regenerated (issue #5989)
### Units
* Added attack image for the Bone Knight’s trample
* Added attack image for the Nightblade’s kick
### User interface
* Improved translatability of MP ban durations (issue #6036, PR #6097)
* Fixed missing sidebar tooltips in low resolutions such as 800x600 (issue #6264)
### Miscellaneous and Bug Fixes
* Password storage was fixed to work with multiple accounts (PR #6290)
* wmllint now automatically removes `{MAGENTA_IS_THE_TEAM_COLOR}`
* Added workaround for connecting to the multiplayer server taking too long when Chinese or Japanese language is selected (issue #6291)
* Added `KeyboardInterrupt` handling to many Python WML tools
* Added `--simple-version` command line option
* wmllint, wmlscope and wmlindent now support the command line `--version` flag, which reports the current version of Wesnoth (issue #6346).
* wmllint is now capable of handling unit levels and types when checking recruitment patterns.
* Fixed units on a recall list sometimes being put on the map by `[modify_unit]` or `[store_unit]...[unstore_unit]` (issues #6295 and #6315)
* Fixed abilities that are shown as weapon specials in the attack prediction window being shown on the placeholder for units with no ranged attack, or dark adepts' melee response
* Fixed a glitch after a move is interrupted, paths to the hex where the move started were shown (issue #6292)
## Version 1.16.1
### Add-ons server
* Fixed `core=` attribute in `_server.pbl` being completely ignored (issue #5664).
### Campaigns
* Tutorial
* Use a portrait on the Campaigns menu.
* Sceptre of Fire
* S02p5: Added defeat condition if Alanin dies.
### Multiplayer
* Increased the limits of timer values (up to 10 minutes turn bonus, 50 minutes reservoir).
* Re-added HTML character escaping.
### Lua API
* Fixed an error in `gui.get_user_choice()` (part of PR #6247).
* Fixed an error in handling `x,y` locations (issue #6231).
### Packaging
* Fixed missing dependency on boost-math in the vcpkg config.
* Made `get_dlls.py` install libraries for `wesnothd` too.
* gettext plural forms now have caret prefixes stripped as well (PR #6094).
### User interface
* Steam cloud file is no longer listed in the Load Game dialog.
* Redefine green text in dialogs and tool-tips so they are no longer ‘too dark’ with recent Pango versions (issue #4348)
* Gave the main menu's Language button a label again, now displaying the current language.
* Tweaked margins around the main menu's bottom row.
* Difficulty no longer displayed in the Load Game dialog when it is not relevant to a save file (issue #5321)
### Miscellaneous and Bug Fixes
* Correct unit display adjustments on certain tiles when at zoom level other than 100% (issue #5974)
## Version 1.15.17
### Campaigns
* World Conquest is re-enabled.
### Translations
* Updated translations: British English, Polish
### Miscellaneous and Bug Fixes
* Messenger MAI: fixed bug of own units sometimes blocking the path to a waypoint for the messenger
* A bug that would corrupt WML sent to the multiplayer and add-ons server was fixed.
## Version 1.15.16
### Campaigns
* Liberty
* S06: Enforce failure condition for allied team (issue #6019)
* The South Guard
* S8b: Reduced difficulty
* Tutorial
* S01: Don't let the first Quintain chase the player to a village (PR #5968)
* S01: Synchronise the choice of character dialog, so that replays don't get OOS (issue #5926)
* S01: Fix some glitches on HDPI displays (PR #6005)
* Secrets of the Ancients
* Synchronise the walking corpse recruitment dialog, so that replays don't get OOS (issue #5334)
* Under the Burning Suns
* S09: Reveal the boss of the scenario at the end of part 1 (issue #5540)
* World Conquest
* Add campaign icons, campaign image and credits (PR #5958)
* Update to new mushroom terrain from the deprecated mushroom terrain (issue #5135, PR #5960)
### Multiplayer
* If an add-on needs to be installed on all players' devices but doesn't specify a min version, assume it needs the latest (issue #5004)
### Terrain
* Fix transition between snowy mountains and castles (issue #6016)
### Translations
* Updated translations: British English, Chinese (Traditional), Czech, Finnish, French, Indonesian, Italian, Polish, Portuguese (Brazil), Russian, Turkish
### Units
* Added and improved Naga animations (issue #5980, PR #6012)
* Added Troll defense animations (PR #5964)
### User interface
* The names of the abilities used as specials appear in the attack prediction window with specials weapons
* In the Load Game dialog, list directories from previous versions in decending order
* Refined design of the Faction Select screen
* Made the campaign selection on bigger on HDPI screens (PR #6013)
### Miscellaneous and Bug Fixes
* Added a timeout when connecting to the wesnothd server
* Improved logging of deprecation messages, fixing duplication and missing timestamps (issue #5942)
* Added `[era]` attributes to the schema
* Added to wmllint an automatic update of four terrain-graphics macros
* Removed wmllint's check for spaces in e-mail addresses
* Standardised the date line of copyright statements, and updated them to 2021
## Version 1.15.15
### Translations
* Updated translations: British English, Bulgarian, Chinese (Traditional), Czech, Italian, Portuguese (Brazil), Russian, Spanish, Turkish
### User interface
* Added a prompt to allow migrating settings and redownloading add-ons used in a previous version of Wesnoth when starting a new versions for the first time.
### Miscellaneous and Bug Fixes
* Fixed: keyboard input during the loading screen intermittently caused a crash (issue #4447)
* AI: fixed custom synced commands not changing the game state
## Version 1.15.14
### Add-ons client
* Fixed: using the versions drop-down in small-screen mode returned to the title screen (issue #5810)
This directory is where PR authors can add a file per PR containing the text that should be added to the main changelog.md during the release process for the next version. The format should match that of the main changelog as well as use an existing category defined there. For example, a file could contain:
### Terrain
* Change codes "Irs, Ias, Icr, Ior, and Icn" to "Isr, Isa, Isc, Iwo, and Iwc", respectively
The purpose of this is to make it easier to add changelog entries with a PR while avoiding merge conflicts in the main changelog file if someone ends up merging their PR before yours.
The contents of this directory (aside from this README file) will then be deleted after each release.
description=_ "The amount of time in seconds before a disconnect is detected. If currently logged into the multiplayer server, you must log out and then log back in for this to take effect."
message=_ "<span color='#A00000'>Important:</span> The animal Micro AIs in this scenario are written for a number of animal unit types that do not exist in Wesnoth mainline, such as sheep, sheep dogs, or deer. In this test scenario, these units have been replaced by mainline units."
[/message]
# wmlindent: start ignoring
[message]
speaker=narrator
image=wesnoth-icon.png
@ -354,7 +353,6 @@
"+{ANIMAL_AI_DESCRIPTIONS1}
[/message]
# wmlindent: stop ignoring
[message]
speaker=narrator
image=wesnoth-icon.png
@ -366,13 +364,11 @@
caption=_ "Question for the Player"
image=wesnoth-icon.png
# wmllint: unbalanced-on
# wmlindent: start ignoring
message=_ "It is possible to include a human-controlled Side 1, so that the action stops once every turn for looking around (or to mess with things in debug mode).
Note that there is no end to this scenario. For demonstration purposes, any unit that is killed is replaced by another unit of the same type at the beginning of the next turn. In order to end the scenario, there's a right-click option - but that only works in human-controlled mode. In AI-only mode, you have to press 'Esc' or reload a previous savefile.
Also note: The Animal AIs are coded as Micro AIs. A Micro AI can be added and adapted to the need of a scenario easily using only WML and the [micro_ai] tag. Check out the <span color='#00A000'>Micro AI wiki page</span> at https://wiki.wesnoth.org/Micro_AIs for more information." # wmllint: no spellcheck
# wmlindent: stop ignoring
# wmllint: unbalanced-off
[option]
label=_ "<span font='16'>I'll just watch the animals.</span>"
@ -426,13 +422,11 @@ Also note: The Animal AIs are coded as Micro AIs. A Micro AI can be added and ad
type=Wolf
[/filter_second]
# wmlindent: start ignoring
[message]
speaker=$second_unit.id
message=_ "Yowl!
Translation: Those boars are mean! We better stay away from them and their young."
message=_ "Kai, please lead us against them yourself, it will hearten the folk. And — if you will permit — you reach the age now where a kai must learn battle skills."
message=_ "Kai, please lead us against them yourself, it will hearten the folk. And — if you will permit — you now reach the age where a kai must learn battle skills."
story=_ "Mal-Ravanal, it seemed, was a great human wizard who had transformed himself into a lich. He had attacked the edges of the kingdom of Wesnoth, and was building a fearsome army of undead humans there. He had also sent necromancers to attack the orcs, and even the elves, in a quest for undead soldiers of different races. It seemed that he also lusted for merfolk slaves. Krellis’ scouts reported that more dark armies were heading north."
story=_ "Mal-Ravanal, it seemed, was a great human wizard who had transformed himself into a lich. He had attacked the edges of the Kingdom of Wesnoth, and was building a fearsome army of undead humans there. He had also sent necromancers to attack the orcs, and even the elves, in a quest for undead soldiers of different races. It seemed that he also lusted for merfolk slaves. Krellis’ scouts reported that more dark armies were heading north."
[/part]
[part]
@ -363,7 +363,7 @@ _f, _f, _f, _f, _f, _f, _f
[else]
[message]
speaker=Cylanna
message=_ "However, I am afraid that not everyone will follow you on so perilous an adventure. First you must prove you are not afraid of danger. If you leave now, many will think the mission is but an excuse to flee."
message=_ "However, I am afraid that not everyone will follow you on so perilous an adventure. First, you must prove you are not afraid of danger. If you leave now, many will think the mission is but an excuse to flee."
[/message]
[/else]
[/if]
@ -502,6 +502,7 @@ _f, _f, _f, _f, _f, _f, _f
[/message]
[message]
speaker=second_unit
#po: This should just be "translated" to whatever noise a bat makes in your language.
message=_ "Neep, neep!"
[/message]
[message]
@ -775,7 +776,7 @@ _f, _f, _f, _f, _f, _f, _f
[/if]
[message]
speaker=Cylanna
message=_ "I believe it is undead and has no will of its own, but the Kai may have the willpower to direct it."
message=_ "I believe it is undead and has no will of its own, but the Kai may have the willpower to direct it."
[/message]
[message]
speaker=Kai Krellis
@ -928,7 +929,7 @@ _f, _f, _f, _f, _f, _f, _f
[else]
[message]
speaker=Cylanna
message=_ "Killing these enemies was good, but there were many more on the way. It will take greater might than we have to defeat them."
message=_ "Killing these enemies was good, but there are many more on the way. It will take greater might than we have to defeat them."
message=_ "You can choose when the slaves come out of their villages and attack their captors. When you are ready, right click anywhere and select the slave revolt."
message=_ "You can choose when the slaves come out of their villages and attack their captors. When you are ready, right-click anywhere and select 'Inspire the slaves to revolt'."
[/message]
#define PUT_SLAVE TYPE X Y
@ -499,6 +499,7 @@
#endif
[message]
speaker=narrator
#po: "to hand" is an expression that means "nearby".
message=_ "Cheers erupted from several villages, and former slaves rushed out with whatever meager weapons they could find, or fists and rocks if no weapons were to hand. Screams and curses came from the saurian castles."
image=wesnoth-icon.png
[/message]
@ -660,7 +661,7 @@
[message]
speaker=Gwabbo
message=_ "Don’t let him go too crazy. Those saurian spears will go right through his scales."
message=_ "Don’t let him go too crazy. Those saurian spears can go right through his scales."
story=_ "It had been more of an adventure than the Kai Krellis had planned, but they were finally at their destination. The small island where Tyegëa and her students lived was before them."
story=_ "It had been more of an adventure than Kai Krellis had planned, but they were finally at their destination. The small island where Tyegëa and her students lived was before them."
[/part]
[/story]
@ -67,6 +67,10 @@
description=_ "Choose a unit to take the holy water"
condition=win
[/objective]
[gold_carryover]
carryover_percentage=100
[/gold_carryover]
[/objectives]
[unit]
@ -176,11 +180,11 @@
[/message]
[message]
speaker=Tyegea
message=_ "That remains to be seen. I find it disturbing that a Kai — and my descendant — would run here begging for help. Before I agree to save you, you have to prove that my blood flows in your veins. Prove that your are, despite appearances, courageous, and worthy of my help."
message=_ "That remains to be seen. I find it disturbing that a kai — and my descendant — would run here begging for help. Before I agree to save you, you have to prove that my blood flows in your veins. Prove that your are, despite appearances, courageous, and worthy of my help."
[/message]
[message]
speaker=Kai Krellis
message=_ "Well, I defeated the Drakes on your island."
message=_ "Well, I defeated the drakes on your island."
message=_ "Well, he calls himself Mal-Govon now, but yes. He called this land the KINGDOM of Agnovon. He was its first king. And its last, and every one in between, too! He kept getting older and older, but he never died. Well, NOW he’s dead of course. He still putters around in that castle over there, but he hasn’t really cared about keeping his kingdom under control for a good long while. I bet I can wake him up, though. Watch THIS!"
message=_ "Well, he calls himself Mal-Govon now, but yes. He called this land the KINGDOM of Agnovon. He was its first king. And its last. And each one in between too! He kept getting older and older, but he never died. Well, NOW he’s dead of course. He still putters around in that castle over there, but he hasn’t really cared about keeping his kingdom under control for a good long while. I bet I can wake him up, though. Watch THIS!"
[/message]
[message]
speaker=narrator
@ -307,7 +307,7 @@
[/message]
[message]
speaker=Mal-Govon
message=_ "What I remember, you old fool, is you leaving behind the smoldering bodies of the orcs you had hired to steal my sword. Now, you bring mer to do your dirty work. When they lay expiring like gasping fish on the shore, will you not flee again? Do not speak to <i>me</i> of fear."
message=_ "What I remember, you old fool, is you leaving behind the smoldering bodies of the orcs you had hired to steal my sword. Now, you bring merfolk to do your dirty work. When they lie expiring like gasping fish on the shore, will you not flee again? Do not speak to <i>me</i> of fear."
[/message]
[message]
speaker=Kai Krellis
@ -369,7 +369,7 @@
[message]
speaker=Kai Krellis
message=_ "I am Kai Krellis of Jotha. I am attempting to defeat Mal-Govon and take his sword. Will you to join us in battle against a common enemy?"
message=_ "I am Kai Krellis of Jotha. I am attempting to defeat Mal-Govon and take his sword. Will you join us in battle against a common enemy?"
[/message]
[message]
@ -1068,7 +1068,7 @@
[then]
[message]
speaker=Kai Krellis
message=_ "We thank all you humans for your help, and release you from any farther obligations. Where we are going, you cannot easily follow."
message=_ "We thank all you humans for your help, and release you from any further obligations. Where we are going, you cannot easily follow."
message=_ "Indeed, though we have not been hardpressed. The creatures have been busy fouling the waters and making the bay more to their liking. We worry that they will soon be back to finish with us, and I fear we will not survive."
message=_ "Indeed, though we have not been hard-pressed. The creatures have been busy fouling the waters and making the bay more to their liking. We worry that they will soon be back to finish with us, and I fear we will not survive."
story=_ "This is the true story of Delfador the Great from his humble beginnings; the tale of how he became the most famous and powerful of all the mages of Wesnoth."
story=_ "This is the true story of how Delfador the Great arose from his humble beginnings, the tale of how he became the most famous and powerful of all the mages of Wesnoth."
[/part]
[part]
story=_ "It begins on the Isle of Alduin, at the Academy which trains mages from throughout the Great Continent."
story=_ "It begins on the Isle of Alduin, at the Academy, which trains mages from throughout the Great Continent."
[/part]
[part]
story=_ "After ten years of training, two tests stand between that apprentice and attainment of the degree of Mage:"
story=_ "After ten years of training, two tests stand between one particular apprentice and attainment of the degree of Mage:"
story=_ "Delfador’s wandering time with Methor took them to many strange places, both within and beyond the lands of men. They studied and practiced, applying magecraft to aid those they traveled among and to deepen their understanding of the hidden currents and powers of the world."
[/part]
[part]
story=_ "But the elder mage’s health was taxed by the rigors of the journey. A year after the two left Alduin, Methor settled in a tranquil valley at the edge of the Dulatus Hills, not far southeast of the capitol at Weldyn. He opened a small school of his own, and with Delfador assisting him he began training a handful of youths who might in time be worthy to enter the great Academy on Alduin."
story=_ "But the elder mage’s health was taxed by the rigors of the journey. A year after the two left Alduin, Methor settled in a tranquil valley at the edge of the Dulatus Hills, not far southeast of the capital at Weldyn. He opened a small school of his own; and with Delfador assisting him, he began training a handful of youths who might in time be worthy to enter the great Academy on Alduin."
[/part]
[/story]
{DM_TRACK {SEARCH_STAGE2}}
@ -74,7 +74,7 @@
name=start
[message]
speaker=Methor
message=_"Delfador, your time as my apprentice is now almost over. You are a fully-trained mage, and may choose your own path in life. I hope, however, that you will take my advice, and enroll yourself in the service of King Garard. I have many contacts at the court and..."
message=_"Delfador, your time as my apprentice is now almost over. You are a fully-trained mage and may choose your own path in life. I hope, however, that you will take my advice and enroll yourself in the service of King Garard. I have many contacts at the court and—"
{NAMED_UNIT 1 Horseman 30 21 Gar _"Gar" ()} {FACING ne}
[message]
speaker=Derrin
message=_"Beware, stranger! I come to warn you — a party of orcs have moved into the Great Valley to the north, and have been raiding the lands around. If you press on westward, you will have to fight them."
message=_"Beware, stranger! I come to warn you — a party of orcs have moved into the Great Valley to the north and have been raiding the lands around. If you press on westward, you will have to fight them."
message=_"Bad news, my liege. The orcs mass in great numbers on the north shore of the river, near to the Ford of Abez. We have been cut off from the dwarves of Knalga — the rumor is that the orcs plan to overrun them, then turn their attention to Wesnoth. The good people of our northern provinces flee, and the land there falls into anarchy. We were attacked more than once by thugs and bandits, and by evil creatures that roamed the night in the shapes of men."
message=_"Bad news, my liege. The orcs mass in great numbers on the north shore of the river, near the Ford of Abez. We have been cut off from the dwarves of Knalga — the rumor is that the orcs plan to overrun them, then turn their attention to Wesnoth. The good people of our northern provinces flee, and the land there falls into anarchy. We were attacked more than once by thugs and bandits, and by evil creatures that roamed the night in the shapes of men."
[/message]
[message]
speaker=Leollyn
@ -90,7 +90,7 @@
[/message]
[message]
speaker=Garard II
message=_"Then there is no time to be lost! I will ride to the Ford of Abez with an army. As bold as the orcs may be to cross our borders in secret and prey on the defenseless, they are disorganized and cowardly in the face of a foe worth their mettle. They need reminding that Wesnoth is too hot for them. Gurcyn, you have been to the west — will the Elves lend their archers to help us?"
message=_"Then there is no time to be lost! I will ride to the Ford of Abez with an army. As bold as the orcs may be to cross our borders in secret and prey on the defenseless, they are disorganized and cowardly in the face of a foe worth their mettle. They need reminding that Wesnoth is too hot for them. Gurcyn, you have been to the west — will the elves lend their archers to help us?"
[/message]
[message]
speaker=Gurcyn
@ -98,7 +98,7 @@
[/message]
[message]
speaker=Delfador
message=_"Your majesty... may I join your army? I mean, I came to Weldyn to seek your employ. And if it’s archers you need, might not a mage be of help?"
message=_"Your Majesty... may I join your army? I mean, I came to Weldyn to seek your employ. And if it’s archers you need, might not a mage be of help?"
[/message]
[message]
speaker=Garard II
@ -125,11 +125,11 @@
[/message]
[message]
speaker=Delfador
message=_"I’m honored that you would entrust me with such a task... but I too stay in Weldyn, by the king’s order!"
message=_"I’m honored that you would entrust me with such a task... but I too stay in Weldyn, by the King’s order!"
[/message]
[message]
speaker=Leollyn
message=_"Hmmm... King Garard placed you under my command, and I may command you to travel north, if you wish to; he will not interfere with a mission of magery as he might with one of war. But you must be sure you are ready for such a grave task. Dealings with the spirit world are dangerous even for the most powerful mages. Allow only your mind to enter the land of the dead — should your body follow, there is no return! Do you still wish to go?"
message=_"Hmmm... King Garard placed you under my command, and I may command you to travel north, if you wish to; he will not interfere with a mission of magery as he might with one of war. But you must be sure you are ready for such a grave task. Dealings with the spirit world are dangerous even for the most powerful mages. Allow only your mind to enter the Land of the Dead — should your body follow, there is no return! Do you still wish to go?"
message=_"You know, you really ought to be more careful before handing over money to suspicious strangers like me. But, since I'm feeling nice at the moment, I think I will actually keep my word and offer you some protection."
message=_"You know, you really ought to be more careful before handing over money to suspicious strangers like me. But, since I’m feeling nice at the moment, I think I will actually keep my word and offer you some protection."
[/message]
[message]
speaker=Harold
message=_"Hey, what's your problem, Garrath? I thought we had a deal!"
message=_"Hey, what’s your problem, Garrath? I thought we had a deal!"
[/message]
[message]
speaker=Garrath
@ -181,11 +181,11 @@
[/redraw]
[message]
speaker=Delfador
message=_"...I'm not entirely sure what just happened here, but I guess I should be grateful?"
message=_"...I’m not entirely sure what just happened here, but I guess I should be grateful?"
[/message]
[message]
speaker=Lionel
message=_"While it appears we lucked out this time, I fear for the travelers for whom this man does NOT keep his word..."
message=_"While it appears fortune favored us this time, I fear for the travelers for whom this man does <i>not</i> keep his word..."
[/message]
#else
[message]
@ -251,7 +251,7 @@
[then]
[message]
speaker=Garrath
message=_"Hey, that was one of OUR villages! Deal's off; we're no longer protecting you!"
message=_"Hey, that was one of <i>our</i> villages! Deal’s off; we’re no longer protecting you!"
[/message]
# Need to conditionalize here to ensure Garrath's reply makes sense:
[if]
@ -261,7 +261,7 @@
[then]
[message]
speaker=Harold
message=_"So... does that mean that OUR deal is back on now, Garrath?"
message=_"So... does that mean that <i>our</i> deal is back on now, Garrath?"
[/message]
[message]
speaker=Garrath
@ -271,7 +271,7 @@
[/if]
[message]
speaker=Delfador
message=_"Wait, I'm sorry! I didn't realize you were so attached to that village! Please give me a chance to make it up to you!"
message=_"Wait, I’m sorry! I didn’t realize you were so attached to that village! Please give me a chance to make it up to you!"
[/message]
[message]
speaker=Garrath
@ -290,7 +290,7 @@
[message]
speaker=Delfador
# If debugging, feel free to edit the variable $gold into this message to see how much you have left:
message=_"I'm afraid I don't have much gold left..."
message=_"I’m afraid I don’t have much gold left..."
[/message]
[message]
speaker=Garrath
@ -307,7 +307,7 @@
speaker=Delfador
message=_"Well..."
[option]
label=_"Here's 20 more gold."
label=_"Here’s 20 more gold."
[command]
[gold]
side=1
@ -320,18 +320,18 @@
{VARIABLE_OP times_garrath_paid add 1}
[message]
speaker=Garrath
message=_"Pleasure doing business with you! Just don't let it happen again!"
message=_"Pleasure doing business with you! Just don’t let it happen again!"
[/message]
# If Harold is dead, dialogue will still make sense with this omitted:
[message]
speaker=Harold
message=_"Sheesh, Garrath, won't you make up your mind already?!"
message=_"Sheesh, Garrath, won’t you make up your mind already?!"
[/message]
# (nothing else to do; Garrath stays an ally)
[/command]
[/option]
[option]
label=_"Nope, I'm not giving you any more gold."
label=_"Nope, I’m not giving you any more gold."
[command]
[message]
speaker=Garrath
@ -364,12 +364,12 @@
[/message]
[message]
speaker=Delfador
message=_"Sorry! It's a hard habit to break! Perhaps I can pay you again to make up for it?"
message=_"Sorry! It’s a hard habit to break! Perhaps I can pay you again to make up for it?"
# (possible future direction: actually let him do so, but at a higher price than before. For now, though, we won't.)
[/message]
[message]
speaker=Garrath
message=_"Nope, I'm through with your games! Men, attack!"
message=_"Nope, I’m through with your games! Men, attack!"
[/message]
[modify_side]
side=2
@ -411,7 +411,7 @@
[then]
[message]
speaker=Garrath
message=_"Hm, it looks like you don't have any gold left. We're not interested in you anymore; bye!"
message=_"Hm, it looks like you don’t have any gold left. We’re not interested in you anymore; bye!"
[/message]
[kill]
side=2
@ -436,7 +436,7 @@
[/filter_second]
[message]
speaker=Harold
message=_"I'll be taking back that money that your men “borrowed” from me now, Garrath!"
message=_"I’ll be taking back that money that your men “borrowed” from me now, Garrath!"
# if someone capable of destroying the generator moves there
[event]
name=moveto
[filter]
side=1
x,y={X},{Y}
type_adv_tree=Mage,Journeyman Mage,Paladin
[/filter]
[message]
speaker=unit
message=_"I call upon all that is holy to break the power of this evil stone!"
[/message]
[sound]
name=lightning.ogg
[/sound]
[color_adjust]
red=100
green=100
blue=100
[/color_adjust]
[delay]
time=10
[/delay]
[color_adjust]
red=0
green=0
blue=0
[/color_adjust]
[remove_event]
id=generator_{X}_{Y}
[/remove_event]
[set_variable]
name=generators_destroyed
add=1
[/set_variable]
[if]
[variable]
name=generators_destroyed
equals={ON_DIFFICULTY 2 2 3}
[/variable]
[then]
[if]
[not]
[have_unit]
side=2
[/have_unit]
[/not]
[then]
[message]
speaker=Delfador
message=_"I think that’s all of them! Let’s move on — the less time we spend in this swamp the better."
[/message]
{CLEAR_VARIABLE generators_destroyed}
[endlevel]
result=victory
bonus=yes
[/endlevel]
[/then]
[else]
[objectives]
side=1
[objective]
description=_ "Survive until daybreak"
condition=win
show_turn_counter=yes
[/objective]
[objective]
{ALTERNATIVE_OBJECTIVE_CAPTION}
description=_ "Defeat remaining enemy units"
condition=win
[/objective]
[objective]
description=_ "Death of Delfador"
condition=lose
[/objective]
[objective]
description=_ "Death of Lionel"
condition=lose
[/objective]
[gold_carryover]
bonus=yes
carryover_percentage=80
[/gold_carryover]
[/objectives]
# if the player manages to destroy all generators he then has to kill remaining enemy units. an unlikely outcome unless we are on EASY. the following child event is spawned from this condition.
[event]
name=die
first_time_only=no
[filter]
side=2
[/filter]
[if]
[not]
[have_unit]
side=2
[/have_unit]
[/not]
[then]
[message]
speaker=Delfador
message=_"I think that’s all of them! Let’s move on — the less time we spend in this swamp the better."
[/message]
{CLEAR_VARIABLE generators_destroyed}
[endlevel]
result=victory
bonus=yes
[/endlevel]
[/then]
[/if]
[/event]
[/else]
[/if]
[/then]
[/if]
[/event]
# if someone who can't destroy the generator moves there
[event]
name=moveto
[filter]
x,y={X},{Y}
side=1
[not]
type_adv_tree=Mage,Journeyman Mage,Paladin
[/not]
[/filter]
[message]
speaker=unit
message=_"Evil emanates from this stone, but I have not the power to destroy it."
[/message]
[/event]
#enddef
#ifdef EASY
{MEMOIRS_GENERATOR_SKELETON 18 3}
{MEMOIRS_GENERATOR_SKELETON 10 16}
#endif
#ifdef NORMAL
#else
{MEMOIRS_GENERATOR_SKELETON 7 5}
{MEMOIRS_GENERATOR_SKELETON 11 19}
#endif
#ifdef HARD
{MEMOIRS_GENERATOR_SKELETON 18 3}
{MEMOIRS_GENERATOR_SKELETON 7 5}
{MEMOIRS_GENERATOR_SKELETON 11 19}
#endif HARD
#endif
[event]
name=prestart
{MODIFY_UNIT (id=Delfador) facing nw}
{MODIFY_UNIT (id=Lionel) facing se}
{VARIABLE generators_destroyed 0}
[objectives]
side=1
[objective]
@ -86,7 +252,7 @@
[/objective]
[objective]
{ALTERNATIVE_OBJECTIVE_CAPTION}
description=_ "Destroy the stones"
description=_ "Destroy the stones and defeat all enemies"
condition=win
[/objective]
[objective]
@ -180,35 +346,12 @@
speaker=Lionel
message=_"I hope I never see another night like that! Let’s leave this evil place as quickly as possible — I want to get us out of Illuven before dusk."
[/message]
{CLEAR_VARIABLE generators_destroyed}
[endlevel]
result=victory
bonus=no
[/endlevel]
[/event]
# if the player manages to destroy all generators...
# an unlikely outcome unless we are on EASY
[event]
name=new turn
first_time_only=no
[if]
[not]
[have_unit]
side=2
[/have_unit]
[/not]
[then]
[message]
speaker=Delfador
message=_"I think that’s all of them! Let’s move on — the less time we spend in this swamp the better."
message=_"I am defeated... My children: hear my last words! Destroy the humans, and never let them set foot on our island again!"
message=_"I am defeated... My children, hear my last words! Destroy the humans, and never let them set foot on our island again!"
[/message]
[message]
speaker=Delfador
@ -186,7 +186,7 @@
[/filter]
[message]
speaker=Delfador
message=_"Ur-Thorodor, listen to me! We are not here to take your island. If you will let just me remain here, then I promise you, on behalf of King Garard, that no Wesnothian will set foot on your island without your permission again. As a token of good faith, I command my army to return to the mainland."
message=_"Ur-Thorodor, listen to me! We are not here to take your island. If you will let me remain here, then I promise you, on behalf of King Garard, that no Wesnothian will set foot on your island without your permission again. As a token of good faith, I command my army to return to the mainland."
[/message]
[message]
speaker=Lionel
@ -194,7 +194,7 @@
[/message]
[message]
speaker=Delfador
message=_"It’s the only way! Lionel, lead our soldiers back to the mainland. I will rejoin you when I have carried out my mission, and determined what is amiss in the world of the dead."
message=_"It’s the only way! Lionel, lead our soldiers back to the mainland. I will rejoin you when I have carried out my mission and determined what is amiss in the world of the dead."
story=_ "It was one of those moments that altered the destiny of the world. The orc warrior held many possibilities in his hand. He could simply have taken Delfador’s head. Had that occurred, the orcs might have overrun the whole of Wesnoth and ruled it for ages. But what he chose, thinking it rare sport to abuse one of the hated human mages, was to strike Delfador with his gauntleted fist."
[/part]
[part]
story=_ "The blow interrupted Delfador’s meditation. He began to topple over to the ground, but before his head reached it he vanished as though he had never been there at all."
story=_ "The blow interrupted Delfador’s meditation. He began to topple over to the ground; but before his head reached it, he vanished as though he had never been there at all."
[/part]
[/story]
@ -156,7 +156,7 @@
[/message]
[message]
speaker=Delfador
message=_"This is surely the land of the dead... and it seems I am still alive. But then, as Leollyn warned, I can never return! I suppose I may as well explore."
message=_"This is surely the Land of the Dead... and it seems I am still alive. But then, as Leollyn warned, I can never return! I suppose I may as well explore."
message=_"Do not fear me, Delfador. It is my doom to appear as you see me. I was a serf of a cruel lord. He demanded great taxes to fight many wars... then plague came... my family were starving, and we were forced to eat the flesh of those who had died."
message=_"Do not fear me, Delfador. It is my doom to appear as you see me. I was a serf of a cruel lord. He demanded great taxes to fight many wars... then plague came... my family was starving, and we were forced to eat the flesh of those who had died."
[/message]
[allow_recruit]
type=Ghoul
@ -530,7 +530,7 @@
[/message]
[message]
speaker=Delfador
message=_"I am only a man, a living man seeking a way home from the house of the dead."
message=_"I am only a man, a living man seeking a way home from the Land of the Dead."
# Shroud is required for share_vision to have the intended effect in the event where the player finds Chantal.
shroud=yes
share_vision=none
recruit=Elvish Ranger,Elvish Rider
{GOLD 120 110 100}
team_name=allies
@ -208,11 +211,11 @@
[/message]
[message]
speaker=Chantal
message=_"Yes. I am Chantal, and I know many things. I know you come from the great human kingdom of the south, and are a master of magic. You have faced great adversity, and visited a place from where few hope to return, and from where none before have returned unchanged. Fate is heavy upon you, and you deserve our help."
message=_"Yes. I am Chantal, and I know many things. I know you come from the great human kingdom of the south and are a master of magic. You have faced great adversity and visited a place from where few hope to return, from where none before have returned unchanged. Fate is heavy upon you, and you deserve our help."
[/message]
[message]
speaker=Delfador
message=_"Oh... well... very nice of you, but I don’t feel very fated. In fact, I’ve been positively blundering! I was just trying to defend my master Methor’s school against the orcs, and then to find out the source of the undead activity... and I have failed at both."
message=_"Oh... well... very nice of you, but I don’t feel very fated. In fact, I’ve been positively blundering! I was just trying to defend my master Methor’s school against the orcs, and then I was tasked with finding the source of the undead activity... and now I have failed at both."
[/message]
[message]
speaker=Chantal
@ -257,7 +260,8 @@
[/set_recruit]
[modify_side]
side=3
share_maps=yes
# Originally share_maps=yes. Since player's side has fog=no, this is effectively share_vision=all.
# 417 YW; Parthyn is strongly garrisoned within the next
# few years. It is now 470 YW and Garard I died a few months
# previously. Garard II, the new King, is 30 years old.
message=_ "This is the nearest human garrison, Delfador. Here is the only place to cross the river. Soon after the last King of Wesnoth began his reign, he put a strong garrison not far south of here in the town of Parthyn, and orcs have not been able to cross into Wesnoth over this part of the river since."
message=_ "This is the nearest human garrison, Delfador — the only place where the river can be crossed. Soon after the last King of Wesnoth began his reign, he put a strong garrison not far south of here in the town of Parthyn, and orcs have not been able to cross into Wesnoth over this part of the river since."
[/message]
[message]
speaker=Delfador
@ -296,7 +296,7 @@
[then]
[message]
speaker=unit
message=_ "There's something there in the mist!"
message=_ "There’s something there in the mist!"
[/message]
[/then]
[/if]
@ -327,7 +327,7 @@
[/message]
[message]
speaker=Delfador
message=_ "Prepare to fight them! We must keep the Ford clear!"
message=_ "Prepare to fight them! We must keep the ford clear!"
[/message]
[fire_event]
name=enemies
@ -391,7 +391,7 @@
[/message]
[message]
role=Commander
message=_ "Yes, close by the southeast wall of our fort across the Ford. But they are jealous of their privileges and hold aloof from us."
message=_ "Yes, close by the southeast wall of our fort across the ford. But they are jealous of their privileges and hold aloof from us."
[/message]
[message]
speaker=Delfador
@ -544,7 +544,7 @@
[/message]
[message]
role=Teacher
message=_ "I recognize it. Very well; we shall join battle."
message=_ "I recognize it. Very well; we shall join the battle."
[/message]
{SUBSUME_SIDE_AND_VILLAGES 5}
@ -1106,11 +1106,11 @@
[/message]
[message]
speaker=Delfador
message=_ "My King does not command him... but if Elves and Humans do not stand together in this, I fear we will fall separately."
message=_ "My king does not command him... but if elves and humans do not stand together in this, I fear we will fall separately."
[/message]
[message]
speaker=Chantal
message=_ "I do not doubt it. Go to your King, Delfador, and have faith in yourself; for I sense that you hold the fate of Wesnoth in your hands, and will need all the strength you have. I think we will meet again."
message=_ "I do not doubt it. Go to your king, Delfador, and have faith in yourself; for I sense that you hold the fate of Wesnoth in your hands, and will need all the strength you have. I think we will meet again."
story=_"While Delfador was still at the Academy, major events were taking place throughout Wesnoth. After centuries of squabbling, a warlord emerged to unite the Orcs. This was ill tidings for men and Elves alike."
story=_"While Delfador was still at the Academy, major events were taking place throughout Wesnoth. After centuries of squabbling, a warlord emerged to unite the orcs. This was ill tidings for humans and elves alike."
[/part]
[part]
#po: "errantry" is an archaic English word associated with medieval
#po: knights. It means he wandered around looking for monsters to
#po: slay and wrongs to right.
story=_"There was an elf named Kalenz who had already in Delfador’s time been a legend among his people for centuries; his tale, <i>The Legend of Wesmere</i>, is known throughout the Elven lands. Prolonged in life by a necromantic potion, he put aside the High Lordship of the Elves after the death of his beloved wife, and wandered the Great Continent in errantry."
story=_"There was an elf named Kalenz who had already, in Delfador’s time, been a legend among his people for centuries; his tale, <i>The Legend of Wesmere</i>, is known throughout the elven lands. Prolonged in life by a necromantic potion, he put aside the High Lordship of the Elves after the death of his beloved wife, and wandered the Great Continent in errantry."
[/part]
[part]
story=_"But Kalenz half-knew and half-feared he would be needed again, and the day he had long foreseen finally arrived. Report came to him of large orcish forces attacking the outskirts of elvish forests, including Lintanir itself. Kalenz quickly gathered a small troop of picked guards. War had returned to the land of the Elves."
story=_"But Kalenz half-knew and half-feared he would be needed again, and the day he had long foreseen finally arrived. Reports came to him of large orcish forces attacking the outskirts of elvish forests, including Lintanir itself. Kalenz quickly gathered a small troop of handpicked guards. War had returned to the land of the elves."
[/part]
[/story]
{DM_TRACK {KALENZ_STAGE1}}
@ -206,7 +206,7 @@
name=start
[message]
speaker=Tan-drul
message=_ "Kill these filthy elves! All warlords will then accept our leader, Zorlan, as king and he will reward you all!"
message=_ "Kill these filthy elves! Show all warlords the might of Zorlan! When they accept him as sovereign we will all be rewarded!"
[/message]
[message]
speaker=Kalenz
@ -260,7 +260,7 @@
[/message]
[message]
speaker=Chantal
message=_ "A paramount chief of all the Orcs has arisen, and he is setting a trap for the humans at the Ford of Abez. I think we must aid the humans, lest we be defeated separately once they are crushed."
message=_ "A paramount chief of all the orcs has arisen, and he is setting a trap for the humans at the Ford of Abez. I think we must aid the humans, lest we be defeated separately once they are crushed."
[/message]
[message]
speaker=Chantal
@ -280,7 +280,11 @@
[/message]
[message]
speaker=Chantal
message=_ "No. But Cleodil gave some of the Book’s least dangerous secrets to her daughters, and so I had them from my mother. And I think I have found the one we have been awaiting since Cleodil accepted the guardianship of the Book. You know of what I speak."
message=_ "No. The preparation of holy water was a secret that Lady Cleodil passed on to her daughters and granddaughters. She thought it wise to share the least dangerous secrets of the Book."
[/message]
[message]
speaker=Chantal
message=_ "Returning to present matters, I believe I have found the one we have been awaiting ever since Lady Cleodil accepted guardianship of the Book. You know of what I speak."
[/message]
[message]
speaker=Kalenz
@ -288,7 +292,7 @@
[/message]
[message]
speaker=Chantal
message=_ "Delfador, a mage trusted of their King. He has survived a passage through the Land of the Dead not merely alive but uncorrupted. He helped us defeat the orcs when they threatened Lintanir, and I fought undead with him at Parthyn Ford. I have come north partly because I am thinking to fetch the Book of Crelanu so I can take it to him."
message=_ "Delfador, a mage trusted of their king. He has survived a passage through the Land of the Dead not merely alive but uncorrupted. He helped us defeat the orcs when they threatened Lintanir, and I fought undead with him at Parthyn Ford. I have come north partly because I am thinking to fetch the Book of Crelanu so I can take it to him."
message=_ "Agreed, but we must make haste, for the King is hardpressed."
message=_ "Agreed, but we must make haste, for the King is hard-pressed."
[/message]
[/event]
@ -316,7 +316,7 @@
[/filter]
[message]
speaker=Zorlan
message=_ "Argh! It can't be, beaten by these swine!"
message=_ "Argh! It can’t be, beaten by these swine!"
[/message]
[/event]
@ -328,7 +328,7 @@
[/message]
[message]
speaker=Garard II
message=_ "Delfador! And you, elvish friends! The kingdom of Wesnoth is in your debt today!"
message=_ "Delfador! And you, elvish friends! The Kingdom of Wesnoth is in your debt today!"
[/message]
[message]
speaker=Delfador
@ -344,27 +344,27 @@
[/message]
[message]
speaker=Delfador
message=_ "Your Majesty, we have more urgent matters. Leollyn sent me on a mission to find out why the dead are restless. A foul necromancer has opened a portal to the land of the dead. It must be closed at all costs, and I am afraid my skills may be insufficient for that task."
message=_ "Your Majesty, we have more urgent matters. Leollyn sent me on a mission to find out why the dead are restless. A foul necromancer has opened a portal to the Land of the Dead. It must be closed at all costs, and I am afraid my skills may be insufficient for that task."
[/message]
[message]
speaker=Kalenz
message=_ "Delfador, our weapons are weak against the undead, but perhaps we have other help to give you. Centuries ago the great mage Crelanu entrusted to us a book of lore, powerful knowledge, perilous secrets that it took Crelanu all his life to gather."
message=_ "Delfador, our weapons are weak against the undead, but perhaps we have other help to give you. Centuries ago, the great mage Crelanu entrusted to us a book of lore and perilous secrets that took him his entire life to gather."
[/message]
[message]
speaker=Kalenz
message=_ "Crelanu charged us to guard his book until someone worthy of it appeared. We believe you are that one, Delfador. The book may help you find a way to close that portal."
message=_ "Crelanu charged us with guarding this book until someone worthy of it should arrive. We believe you are the one, Delfador. The book may help you find a way to close the portal."
[/message]
[message]
speaker=Delfador
message=_ "Friends, your words do me perhaps greater honor than I deserve. I am not sure I am worthy of this charge."
message=_ "Friends, your words do me greater honor than I perhaps deserve. I am not sure I am worthy of this charge."
[/message]
[message]
speaker=Kalenz
message=_ "Chantal and I are sure of your quality. But be warned: there is a curse on this book. Crelanu fairly warned us that his arts would bring much woe down upon us. And so it proved, though at the time we had no other choice. The victories you win with it may cost you as dearly."
message=_ "You may have some doubts, but Chantal and I are sure of your quality. But be warned: there is a curse on this book. Crelanu fairly warned us that his arts would bring much woe down upon us. And so it proved, though at the time we had no other choice. The victories you win with it may cost you as dearly."
[/message]
[message]
speaker=Delfador
message=_ "Curse or no, we must close that portal soon, or else we are all doomed."
message=_ "Curse or no, we must close the portal soon, or else we are all doomed."
[/message]
[message]
speaker=Kalenz
@ -380,7 +380,7 @@
[/message]
[message]
speaker=Delfador
message=_ "Thank you, friends. May we meet again in happier times. Now I must make haste, for I need to study the book and prepare for the battle with the undead."
message=_ "Thank you, friends. May we meet again in happier times. Now I must make haste, for I need to study the book and prepare for battle with the undead."
story=_"Kalenz and Chantal and their troops departed to ride against the remnants of the orcish Great Horde. Delfador returned to Weldyn with the King and his gift from the elves, the Book of Crelanu. However, despite the victory, Delfador was deeply worried by the undead menace. On the way back they met with Lionel who was arriving with reinforcements, and were deeply saddened to learn that Leollyn had died under very suspicious circumstances."
story=_"Kalenz, Chantal, and their troops departed to ride against the remnants of the orcish Great Horde. Delfador returned to Weldyn with the King and his gift from the elves, the Book of Crelanu. However, despite the victory, Delfador was deeply worried by the undead menace. On the way back, they met with Lionel who was arriving with reinforcements, and were deeply saddened to learn that Leollyn had died under very suspicious circumstances."
[/part]
[part]
background=story/portraits/garard-large.png
@ -31,15 +31,15 @@
[/part]
[part]
background=story/portraits/garard-large.png
story={CAPTION ( _ "Garard II")} + _ "Peace, Lionel. The elves fought well and have earned Our respect. But this council is here to address an alarming matter. Young master Delfador here reports of an undead threat. He was able to fight them off at Parthyn Ford, but more are coming."
story={CAPTION ( _ "Garard II")} + _ "Peace, Lionel. The elves fought well and have earned our respect. But this council is here to address an alarming matter. Young master Delfador here reports of an undead threat. He was able to fight them off at Parthyn Ford, but more are coming."
[/part]
[part]
background=portraits/lionel.png
story={CAPTION ( _ "Lionel")} + _ "With your permission, sire, I will take some picked men north and crush these abominations."
story={CAPTION ( _ "Lionel")} + _ "With your permission, sire, I will take some handpicked men north and crush these abominations."
story={CAPTION ( _ "Delfador")} + _ "Your majesty, these are no stray undead; this lunatic, Iliah-Malal, has opened a portal to the Land of the Dead. Unless we close this portal soon, the relatively small numbers of enemy troops he now commands will swell into an endless stream of undead. And our army, having equipped and trained primarily to fight raiding orcs, is not well suited to fight even the forces he fields now. Mages, in combination with heavy infantry are most effective against them."
story={CAPTION ( _ "Delfador")} + _ "Your Majesty, these are no stray undead; this lunatic, Iliah-Malal, has opened a portal to the Land of the Dead. Unless we close this portal soon, the relatively small numbers of enemy troops he now commands will swell into an endless stream of undead. And our army, having equipped and trained primarily to fight raiding orcs, is not well suited to fight even the forces he fields now. Mages, in combination with heavy infantry, are most effective against them."
story={CAPTION ( _ "Delfador")} + _ "There are three things we must do. First, we must organize our defenses as best we can. Second, we need to ask the elves to create a diversion, to distract and delay Iliah-Malal. The elves will not be able to fight the undead head on on the field, but they can harass them by striking from forests where the undead dare not follow. And last, I have been studying and I think I now know how to close Iliah-Malal’s portal to the Land of the Dead. I will need a small escort, but this must be done immediately."
story={CAPTION ( _ "Delfador")} + _ "There are three things we must do. First, we must organize our defenses as best we can. Second, we need to ask the elves to create a diversion that will distract and delay Iliah-Malal. The elves will not be able to fight the undead head-on on the field, but they can harass them by striking from forests where the undead dare not follow. And last, I have been studying the Book of Crelanu and I think I now know how to close Iliah-Malal’s portal to the Land of the Dead. I will need a small escort, but this must be done immediately."
story={CAPTION ( _ "Delfador")} + _ "These are only the first steps. If we are to defeat the undead, we need to use and train the army differently than we have. First, you must recall every mage in Wesnoth, from Alduin and elsewhere. And you must prepare more heavy infantry."
story={CAPTION ( _ "Delfador")} + _ "These are only the first steps. If we are to defeat the undead, we need to reform the composition of our army. First, you must recall every mage in Wesnoth, from Alduin and elsewhere. And you must prepare more heavy infantry."
[/part]
[part]
background=portraits/lionel.png
@ -124,7 +124,7 @@
[/part]
[part]
background=story/portraits/garard-large.png
story={CAPTION ( _ "Garard II")} + _ "Delfador could. You will command the heavy infantry. Make sure to shield the mages in battle, for they are precious. Now, go, close the portal and come back soon!"
story={CAPTION ( _ "Garard II")} + _ "Delfador could. You will command the heavy infantry. Make sure to shield our mages in battle, for they are precious. Now go, close the portal and come back soon!"
story=_ "Delfador took a small escort to the north in order to attempt to close the portal. But with Iliah-Malal’s army at large north of the Great River, this was a perilous road. Delfador was constrained to avoid well-trodden paths. This meant a detour..."
story=_ "Delfador took a small escort to the north on a mission to close the portal. But with Iliah-Malal’s army at large north of the Great River, this was a perilous road. It was imperative that Delfador avoid well-trodden paths. This meant a detour..."
show_title=yes
[/part]
[/story]
@ -144,7 +144,7 @@
[/message]
[message]
speaker=Delfador
message=_"Dwarves, attacked by undead. We must help them."
message=_"Dwarves, under attack by undead. We must help them."
[/message]
[message]
speaker=Gruv-Malal
@ -195,7 +195,7 @@
[/message]
[message]
speaker=Delfador
message=_"I am Delfador. Friends, a great evil has been unleashed. A portal has been opened to the land of the dead near the northernmost extent of these hills, nearly under the eaves of Lintanir Forest. I must close it, or else we are all doomed."
message=_"I am Delfador. Friends, a great evil has been unleashed. A portal has been opened to the Land of the Dead near the northernmost extent of these hills, nearly under the eaves of Lintanir Forest. I must close it, or else we are all doomed."
story=_ "The dwarves led Delfador through a veritable maze of tunnels. Delfador was amazed at the speed with which the dwarves could move through their tunnels. Far sooner than he would have believed possible they reached their destination, undetected by Iliah-Malal."
story=_ "The dwarves led Delfador through a veritable maze of tunnels; Delfador was amazed at the speed with which the dwarves could move through them. Far sooner than he would have believed possible, they reached their destination, undetected by Iliah-Malal."
show_title=yes
[/part]
[/story]
@ -209,11 +209,11 @@
name=start
[message]
speaker=Prepolur
message=_"Living men and dwarves are nearing. Rise, Portal Guard and slay the intruders!"
message=_"Living men and dwarves are nearing. Rise, my fellow dead, and slay the intruders!"
[/message]
[message]
speaker=Delfador
message=_"The portal must be closed at any cost. You must allow me to get close to it, so I can seal it."
message=_"The portal must be closed at all costs. You must allow me to get close to it, so I can seal it."
[/message]
[message]
speaker=Ulrek
@ -255,7 +255,7 @@
[/message]
[message]
speaker=Delfador
message=_ "They have reinforcements. Hurry, we must close the portal before we are overrun!"
message=_ "(<i>To the dwarves</i>). Their master has arrived with reinforcements. Hurry, we must close the portal before we are overrun!"
[/message]
[message]
speaker=Iliah-Malal
@ -328,11 +328,11 @@
[/filter]
[message]
speaker="Iliah-Malal"
message=_ "Fool! You could not kill me in the land of the dead, nor can you in the land of the living! I transcend both death and life, and I will destroy you!"
message=_ "Fool! You could not kill me in the Land of the Dead, nor can you in the land of the living! I transcend both death and life, and I will destroy you!"
[/message]
[message]
speaker=Delfador
message=_ "We cannot defeat him now. We must carry out our mission first, so we will be able to defeat him later."
message=_ "We cannot defeat him now. We must allow some time to pass after the portal has been closed. By then, his power will have weakened, rendering him vulnerable."
[/message]
# He gets a full heal, not an advance, otherwise we'd have to make sure we ported him to the next scenario properly
{FULL_HEAL id=Iliah-Malal}
@ -373,7 +373,7 @@
[/message]
[message]
speaker=Iliah-Malal
message=_"Delfador, you have proven your skill. I have an offer for you. Join me and you will live as my right hand. Together our magic skills will be unmatched and irresistible."
message=_"Delfador, you have proven your skill. I have an offer for you. Join me, and you will live as my right hand. Together, our magic skills will be unmatched and irresistible."
[/message]
[message]
speaker=Delfador
@ -393,7 +393,7 @@
[/message]
[message]
speaker=Delfador
message=_"(<i>To the dwarves</i>). Now that the portal is closed, his power will start to weaken, but that doesn't help us now. Quickly, back in the tunnel! I will stay last to seal the entrance."
message=_"(<i>To the dwarves</i>). Now that the portal is closed, his power will start to weaken. It will be some time until he is rendered vulnerable; at the moment, we must flee. Quickly, back to the tunnel! I will enter it last to seal the entrance."
story=_ "With the portal closed, Iliah-Malal was weakened. He retreated into the Swamp of Dread to recover his strength and attempt another conjuration. Delfador’s troop, hurrying west by secret Dwarvish ways and stealthily crossing the Listra by night, found the necromancer there, on the brink of raising another army amidst the fetid reek."
story=_ "With the portal closed, Iliah-Malal was weakened. He retreated into the Swamp of Dread to recover his strength and attempt another conjuration. Delfador’s troop, hurrying west by secret dwarvish ways and stealthily crossing the Listra by night, found the necromancer there, on the brink of raising another army amidst the fetid reek."
[/part]
[part]
story=_ "Using dwarvish and elvish messengers, Delfador was able to communicate the news to the King and ask for help. Mustering all the troops he could find, Lionel marched north to join Delfador for the battle that would decide the fate of Wesnoth."
@ -330,7 +330,7 @@
[/message]
[message]
speaker=Delfador
message=_ "Your mindless minions will be no match for the spirit and fire of the living."
message=_ "Your mindless minions are no match for the spirit and fire of the living."
[/message]
{MODIFY_UNIT (id=Lionel) facing nw}
[message]
@ -491,11 +491,11 @@
[/if]
[message]
speaker=Lionel
message=_"And the portal, it is sealed for good?"
message=_"And the portal, is it sealed for good?"
[/message]
[message]
speaker=Delfador
message=_"Yes, it is. But it was too great a work of magic to be entirely undone; there is a flaw still remaining, a trace of Iliah-Malal’s way between worlds. Raising undead will be a little easier in the future than it has been before. Those who come after us will have to be vigilant against the corruption of the dark arts, and show themselves worthy of the land they live in."
message=_"Yes, it is. But it was too great a work of magic to be entirely undone; there is a flaw still remaining, a trace of Iliah-Malal’s way between worlds. Raising undead will be a little easier in the future than it has been before. Those who come after us will have to be vigilant against the corruption of the dark arts and show themselves worthy of the land they live in."
[/message]
# This is set-up for the next scenario, where Kalenz leads side 1 again
story=_ "One day reports came of Wesnothian forces seizing elvish land on the border. Kalenz gathered a small force and hurried to the disputed country."
story=_ "One day, reports came of Wesnothian forces seizing elvish land on the border. Kalenz gathered a small force and hurried to the disputed country."
[/part]
[/story]
{DM_TRACK {BOOK_STAGE1}}
@ -162,11 +162,11 @@
[/lift_fog]
[message]
speaker=Kalenz
message=_ "Generals of Wesnoth: you have attacked defenseless elvish land. You must leave immediately. I am Kalenz, High Lord of the Elves. Delfador the Great will confirm the treaty between us."
message=_ "Generals of Wesnoth, you have attacked defenseless elvish land. You must leave immediately. I am Kalenz, High Lord of the Elves. Delfador the Great will confirm the treaty between us."
[/message]
[message]
speaker=Eldred
message=_ "This is elvish land no more. I, Eldred, prince of Wesnoth and heir to the throne, claim it for Wesnoth and Queen Asheviere. Delfador does not rule in Wesnoth!"
message=_ "This is elvish land no more. I, Eldred, Prince of Wesnoth and heir to the throne, claim it for Wesnoth and Queen Asheviere. Delfador does not rule in Wesnoth!"
[/message]
[message]
speaker=Kalenz
@ -213,11 +213,11 @@
[/message]
[message]
speaker=Chantal
message=_ "Kalenz, I am very worried. There is a cloud of evil swirling around the Royal Palace, and it has more centers than the prince alone. I see dark days ahead..."
message=_ "Kalenz, I am very worried. There is a cloud of evil swirling around the Royal Palace, and it has more centers than the Prince alone. I see dark days ahead..."
[/message]
[message]
speaker=Kalenz
message=_ "I wonder if the Book of Crelanu is not behind this. The Book is not evil in itself, but the power it gives tends to magnify any evil in the reader’s soul. Delfador, has anyone but you opened its covers since you got it from us?"
message=_ "I wonder if the Book of Crelanu is behind this. The Book is not evil in itself, but the power it gives tends to magnify any evil in the reader’s soul. Delfador, has anyone but you opened its covers since you got it from us?"
#po: "demesne" = the part of a feudal lord's lands reserved for
#po: personal use.
#po: The "Sceptre" spelling is intentional.
story=_ "Upon his return to Weldyn, Delfador discovered that the Book was missing. The queen had left with a strong escort to visit her family’s demesne and her ailing parents. Lionel, the King’s most trusted general, had been sent at Asheviere’s request on an errand to Knalga to retrieve the Sceptre of Fire. That mission would cost Lionel his life; and neither Lionel nor Delfador knew that Lionel’s mission had been compromised from the start."
story=_ "Upon his return to Weldyn, Delfador discovered that the Book was missing. The Queen had left with a strong escort to visit her family’s demesne and her ailing parents. Lionel, the King’s most trusted general, had been sent at Asheviere’s request on an errand to Knalga to retrieve the Sceptre of Fire. That mission would cost Lionel his life; and neither Lionel nor Delfador knew that Lionel’s mission had been compromised from the start."
[/part]
[part]
story=_ "Although the King did reprimand Eldred for his actions, Delfador could sense that the military commanders were solidly behind Eldred and his mother. Asheviere had flattered them and beguiled them with promises of glory and plunder in a coming war."
@ -35,7 +35,7 @@
story=_ "Delfador was granted an audience with the King and expressed his concerns about the Book, but the King put off a decision until Asheviere returned to Weldyn, and ordered Delfador to take no further action. And for once, Delfador knew he could not obey the King’s order."
[/part]
[part]
story=_ "Since he could not ask even his personal guard to go against the King’s wishes, he turned to Kalenz and the elves. Traveling by night to remain unseen they reached Asheviere’s family demesne."
story=_ "Since he could not ask even his personal guard to go against the King’s wishes, he turned to Kalenz and the elves. Traveling by night to remain unseen, they reached Asheviere’s family demesne."
[/part]
[/story]
{DM_TRACK {BOOK_STAGE3}}
@ -161,11 +161,11 @@
[message]
speaker=Delfador
message=_ "I am grieved to have to resort to this. Yet the book must be recovered at all costs and no one should be left alive."
message=_ "I am grieved to have to resort to this. Yet the Book must be recovered at all costs; and no one should be left alive."
[/message]
[message]
speaker=Kalenz
message=_ "The book’s curse is already weighing heavy upon you, friend. But we cannot falter. We have acquired orcish weapons, as you have requested. Nobody will be able to link this to you or the elves."
message=_ "The Book’s curse is already weighing heavy upon you, friend. But we cannot falter. We have acquired orcish weapons, as you have requested. Nobody will be able to link this to you or the elves."
[/message]
[message]
speaker=Kalenz
@ -173,7 +173,7 @@
[/message]
[message]
speaker=Rhuwin
message=_ "Elves! And that traitor, Delfador is with them! Riders, quickly, go alert the queen. And guards, prepare to strike them down!"
message=_ "Elves! And that traitor, Delfador is with them! Riders, quickly, go alert the Queen. And guards, prepare to strike them down!"
[/message]
{HIGHLIGHT_IMAGE 1 19 scenery/signpost.png ()}
@ -272,7 +272,7 @@
name=new-objectives
[message]
speaker=Delfador
message=_ "The guards are slain. Now we must look for the book."
message=_ "The guards are slain. Now we must look for the Book."
[/message]
[objectives]
side=1
@ -331,7 +331,7 @@
[then]
[message]
speaker=Rhuwin
message=_ "Everyone, quickly, go alert the queen!"
message=_ "Everyone, quickly, go alert the Queen!"
[/message]
# loop through all remaining units and have them go to the nearest exit
story=_ "Delfador returned to Weldyn, but not before secreting the Book of Crelanu in a place known only to him. To his surprise, Asheviere made no further mention of the events in the manor. But not long after, orcish raids increased to a degree that threatened the Kingdom. The King mustered his armies to deal with the orcish menace, leading to the great battle at the Ford of Abez that was lost through betrayal."
story=_ "Delfador returned to Weldyn, but not before secreting the Book of Crelanu to a place known only to him. To his surprise, Asheviere made no mention of the events in the manor. But not long after, orcish raids increased to a degree that threatened the Kingdom. The King mustered his armies to deal with the orcish menace, leading to the great battle at the Ford of Abez that was lost through betrayal."
[/part]
[part]
story=_"Delfador’s last great quest, after that battle, was ending the usurpation of Asheviere and restoring the rightful <i>Heir to the Throne</i>."
[/part]
[part]
story=_ "Afterwards, Delfador lived the rest of his life as an advisor to the new rulers. He devoted much of his attention to restoring the Great Academy in Alduin to its former glory. But his efforts there were to bear little fruit in his lifetime; for through many years of war and strife, very few mages were left, and none of them came near in power and skill to Delfador, greatest mage ever to grace the courts of Wesnoth."
story=_ "Afterwards, Delfador lived the rest of his life as an advisor to the new rulers. He devoted much of his attention to restoring the great Academy in Alduin to its former glory. But his efforts there were to bear little fruit in his lifetime; for through many years of war and strife, very few mages were left, and none of them came near in power and skill to Delfador, greatest mage ever to grace the courts of Wesnoth."
# there's no way you do this without debug, right?
[if]
[variable]
name=s_unit.type
equals=Necrophage
[/variable]
[or]
[variable]
name=s_unit.type
equals=Ghast
[/variable]
[/or]
[and]
[variable]
name=s_unit.max_hitpoints
greater_than=9999
[/variable]
[/and]
[then]
[fire_event]
name=rat eating4
[/fire_event]
[/then]
[/if]
@ -1130,13 +1201,40 @@
[/message]
[/event]
[event]
name=rat eating
name=rat eating1
[message]
speaker=Malin Keshar
message=_ "I must be absolutely mad to be spending hours here just feeding rats to this rotten pile of flesh..."
[/message]
[/event]
[event]
name=rat eating2
[message]
speaker=Darken Volk
message=_ "Has this boy been smoking again?"
[/message]
[/event]
[event]
name=rat eating3
[message]
speaker=Malin Keshar
message=_ "Day 1337:
All sense of time and being are entombed within darkness. How long has passed since I came here? My senses are a blur. My past life, my prior goals, my very self is all but a distant memory. All I know now is the constant squealing of rats and the ever growing mountain of flesh that feasts before me."
[/message]
[/event]
[event]
name=rat eating4
#po: Malin Keshar breaks the fourth wall here and addresses the player, whom the 'you' refers to.
[message]
speaker=Malin Keshar
message=_ "You. You there behind the screen. You are the one controlling me. Why are you doing this? What did I do to deserve this torment? Please, I beg of you. End me now. Release me from my misery!"
story=_ "As Malin and Darken Volk continue their raids on the orcs, they eventually force the usually fractious Whitefang chieftains to unite in opposition. The orcs pursue the two necromancers east toward the mouth of the river Men call the Longlier and Elves call the Arkan-thoria, where they manage to surround the humans and force a fight."
story=_ "As Malin and Darken Volk continue their raids on the orcs, they eventually force the usually fractious Whitefang chieftains to unite in opposition. The orcs pursue the two necromancers east toward the mouth of the river humans call the Longlier and elves call the Arkan-thoria, where they manage to surround the humans and force a fight."
# This helps prevent Darken from getting himself killed easily by preventing
@ -763,7 +763,7 @@
message=_ "Nothing to say this time? No quip ’bout how we don’t understand ya? No comment about yer moral superiority? I can only hope you’ll be so quiet when I kill you."
[/message]
{VARIABLE dela_arrived 1}
{VARIABLE dela_arrived yes}
[/event]
[event]
@ -820,7 +820,7 @@
[and]
[variable]
name=dela_arrived
numerical_equals=1
boolean_equals=yes
[/variable]
[/and]
[then]
@ -949,6 +949,14 @@
[not]
type_adv_tree=Ghost,Vampire Bat
[/not]
[not]
type_adv_tree=Walking Corpse
variation=bat
[/not]
[not]
# this unit does not advance normally so each type has to be listed individually
story=_ "So reads the book that Malin has reclaimed. <i>“The spells of necromancy can free the spirit from the limitations of the flesh, but only once the soul has been unbound from the body. The necromancer must make the necessary incantations with his dying breaths, then conquer his own spirit much the same way he binds the spirits of others. Because he retains his own will, however, the lich can call upon the awesome powers of the spirit world.”</i>"
story=_ "So reads the book that Malin has reclaimed. <i>“The spells of necromancy can free the spirit from the limitations of the flesh, but only once the soul has been unbound from the body. The necromancer must make the necessary incantations with his dying breaths, then conquer his own spirit in much the same way he binds the spirits of others. Because he retains his own will, however, the lich can call upon the awesome powers of the spirit world.”</i>"
story=_ "The lich sometimes wonders if his endeavors are naught but a fruitless crusade, but then again, so what? Life, unlife, death... nothing has ever given his existence meaning. And yet, he still persists on? For what?"
story=_ "The lich sometimes wonders if his endeavors are naught but a fruitless crusade, but then again, so what? Life, unlife, death... nothing has ever given his existence meaning. And yet, he still persists? For what?"
message=_ "We have come to the Great River. Should we cross here, or try to find a ford?"
[/message]
[message]
speaker=Dacyn
message=_ "We must cross here. The undead are chasing us, and their hordes are much too great for us to defeat. We've haven't faced even a small part of their force yet. We need to cross the river before the bulk of their army arrives!"
message=_ "We must cross here. The undead are chasing us, and their hordes are much too great for us to defeat. We’ve haven’t faced even a small part of their force yet. We need to cross the river before the bulk of their army arrives!"
[/message]
[message]
speaker=Owaec
@ -189,6 +190,10 @@
x,y=36,29
[/unstore_unit]
{CLEAR_VARIABLE saved_Garnad}
[modify_side]
side=2
hidden=no
[/modify_side]
[terrain]
x,y=36,29
@ -211,7 +216,7 @@
[/message]
[message]
speaker=Dacyn
message=_ "They're closing in on us! We must get moving quickly."
message=_ "They’re closing in on us! We must get moving quickly."
[/message]
[/event]
@ -244,7 +249,7 @@
[message]
speaker=Mal-Hakralan
message=_ "I see, this is where the scared dogs ran to. Don't think you can get away <b>this</b> easily."
message=_ "I see, this is where the scared dogs ran to. Don’t think you can get away <b>this</b> easily."
[/message]
[message]
speaker=Dacyn
@ -368,7 +373,8 @@
[then]
[message]
speaker=Grug
message=_ "Grug say join you will he."
#po: "Grug say join you will he" means "I will join you" in a weird speech pattern. "Gork and Drog too" means that two other ogres will be joining Gweddry.
message=_ "Grug say join you will he. Gork and Drog too."
message=_ "We head south. My research revealed that the dragon Khrakrahs is in possession of a Null Stone; with it I will be able to block Mal-Ravanal’s teleportation. Once we have retrieved the stone, we must travel to Weldyn. Our experience fighting the undead will prove invaluable in the defense of our homeland. Also, I have advice to give the king: I know Mal-Ravanal’s weakness."
message=_ "We head south. My research revealed that the dragon Khrakrahs is in possession of a Null Stone; with it I will be able to block Mal-Ravanal’s teleportation. Once we have retrieved the stone, we must travel to Weldyn. Our experience fighting the undead will prove invaluable in the defense of our homeland. Also, I have advice to give the King: I know Mal-Ravanal’s weakness."
story=_ "The greatest seer in the land, Galdren, foresaw that some day, some day soon, a great evil would spread over the land. The king, naturally, was worried. The seer told him that the only way to stop the evil was to appoint a mage, versed well in combat with the spirits of darkness, to be the king’s advisor."
story=_ "The greatest seer in the land, Galdren, foresaw that some day, some day soon, a great evil would spread over the land. The King, naturally, was worried. The seer told him that the only way to stop the evil was to appoint a mage, versed well in combat with the spirits of darkness, to be the king’s advisor."
[/part]
[part]
story=_ "In all the land, there were two magi that clearly stood out from the rest. A mage from the east named Ravan, and myself. The King, wishing to choose the best advisor, sent us both before Galdren. Then he conversed with the seer privately. None know what was said, but when he came out he announced that the seer was dead, and he had chosen me as his new advisor."
message=_ "You have risked your life to defend our city. In return, I place one of my city’s finest defenders in your service. Simyr, step forward. I place your lance in the service of young prince Konrad here. May you help him restore order to the country."
message=_ "You have risked your life to defend our city. In return, I place one of my city’s finest defenders in your service. Simyr, step forward. I place your lance in the service of young Prince Konrad here. May you help him restore order to the country."
# po: a hint that the player has 3 scenarios before the first main test of their XP management
description=_ "You’ll need experienced troops at Elensefar."
[/note]
[/objectives]
[/event]
@ -193,17 +198,22 @@
speaker=Konrad
message=_ "So this is Alduin. It looks a little... desolate."
[/message]
[message]
speaker=Delfador
message=_ "I fear so, Konrad. It seems that the orcs have come even here. Here to the place where I was born, where I was trained."
[/message]
[message]
speaker="Usadar Q'kai"
message=_ "Who is that? Oh, a party of elves has landed. We shall drive them back into the sea!"
[/message]
[message]
speaker=Delfador
message=_ "I did not think the orcs would have come here. This island used to be so beautiful. We must recapture it! To arms!"
message=_ "If the orcs have come here, their forces at Elensefar must be even more numerous than I feared."
[/message]
[message]
speaker=Delfador
# po: a hint for players who are expecting campaigns to have a steadily-rising difficulty curve.
message=_ "Konrad, training is important. If we only have inexperienced troops when we reach Elensefar, then our journey is likely to end in sight of the city’s gates."
[/message]
[message]
speaker=Delfador
message=_ "This island is the place where I was born, and where I learned magic; it used to be so beautiful. We must recapture it! To arms!"
[/message]
[/event]
@ -307,7 +317,7 @@
[message]
speaker=Seimus
message=_ "She has taken control of the Bay of Pearls, long held by the Mer, and has turned them into slaves. There they dive for pearls by which she grows richer every day. There are even rumors that she may break the ancient treaty and attack Elensefar!"
message=_ "She has taken control of the Bay of Pearls, long held by the mer, and has turned them into slaves. There they dive for pearls by which she grows richer every day. There are even rumors that she may break the ancient treaty and attack Elensefar!"
message=_ "You must escape the clutches of that vile Queen, my lord. If you take a course bearing north-east, on past the mountain of gryphons, you will be able to ford the Great River at Abez. Make haste though, for you will not be able to ford the river in winter!"
message=_ "You must escape the clutches of that vile queen, my lord. If you take a course bearing north-east, on past the mountain of gryphons, you will be able to ford the Great River at Abez. Make haste though, for you will not be able to ford the river in winter!"
message=_ "The forces of the king were encamped here, and the forces of the north were on the north side of the river. For three days and three nights the armies faced each other, neither willing to ford the river. On the fourth day, the northern armies crossed and attacked us."
message=_ "The forces of the King were encamped here, and the forces of the north were on the north side of the river. For three days and three nights the armies faced each other, neither willing to ford the river. On the fourth day, the northern armies crossed and attacked us."
[/message]
[message]
speaker=Konrad
@ -211,19 +211,19 @@
[/message]
[message]
speaker=Kalenz
message=_ "And then the king’s son, in the heat of battle, turned upon the king!"
message=_ "And then the King’s son, in the heat of battle, turned upon the King!"
[/message]
[message]
speaker=Konrad
message=_ "But you avenged the murder. You killed the prince. Right, Delfador?"
message=_ "But you avenged the murder. You killed the Prince. Right, Delfador?"
[/message]
[message]
speaker=Delfador
message=_ "When I saw the king betrayed and his banner fallen, I fled the battle. I know not now whether it was wisdom or cowardice, but I did flee, seeing no further hope on that day."
message=_ "When I saw the King betrayed and his banner fallen, I fled the battle. I know not now whether it was wisdom or cowardice, but I did flee, seeing no further hope on that day."
[/message]
[message]
speaker=Konrad
message=_ "Oh, but the elves always told me that you killed the prince, Delfador, even though you never talked about it."
message=_ "Oh, but the elves always told me that you killed the Prince, Delfador, even though you never talked about it."
[/message]
[message]
speaker=Delfador
Some files were not shown because too many files have changed in this diff
Show more