If two [damage_type]alternative_type= are used with two different types, the chosen type displayed in the pre-combat window will be the one to which the opponent is most vulnerable. That type will then also be used in the attack if it is stronger than the original/replacement_type.
In the sidebar (report) all alternative_types are displayed.
---------
Co-authored-by: Gunter Labes <soliton@wesnoth.org>
max_value is used to limit the increase in resistance with the "resistance" capability, but there was no equivalent for its reduction.
To be able to add min_value without redoing the "resistance" checking for the umpteenth time, I prefer to modify effect:: so that the checking of these two attributes is done at the same time as the other numerical attributes and keep the door open to a possible generalization of the proceed
If the first trait of a unit has no name, then clicking on the units (other)
trait in the sidebar opened the wrong page in the help.
(cherry picked from commit f9af941f1ec7165ad135cba465717203a4007287)
When [damage_type] is used but the opponent uses the resistance ability
against the added type, the ability filter only detected the original type and
the new type was not affected.
* Fix#8460 [effect] apply_to=variation
Previously the code could apply the variation effects
last, so that codes like
```
[effect]
apply_to=variation
..
[/effect]
[effect]
apply_to=hitpoints
heal_full=yes
[/effect]
```
Would not set the unit hitpoints to the new variations
hitpoints because the variation effect was applied after
the healing effect.
In 1.16 this worked because healing was applied a little
too often but that lead also to bugs like #8342
* f prev
* f prev
* f prev
* f prev
* f prev
* Create modification_effect_type_variation.cfg
* Update wml_test_schedule
Previously it could happen that removing an object applies the status healing,
in particular of the default AMLAs (which are meant to only heal the unit once).
For me (and this is not the opinion of https://github.com/soliton-) when we check the value of the value attribute,
we seek to verify that the value encoded in ability (or possibly the default) corresponds,
the value by default means that the value attribute is encoded with this default value, that's it.
Apparently https://github.com/soliton- understood that it was the returned value that was checked and
I let myself get into this error which I am now correcting.
currently absence of default value is only detected when other numeric attributes are used, this commit is here to repair this rather unfortunate oversight.
At the suggestion of @stevecotton, I propose a special 'replacement_type' and 'alternative_type' attribute capable of modifying the type of attack used when the conditions are met.
Also make Holy water combine arcane damage with native type of weapon
Like holy water imbued ordinary weapon, it's seem logic what arcane damage dominant what if more efficient what original type(water can't altered pierce or blading of spear or sword)
Fix https://github.com/wesnoth/wesnoth/issues/7923 .when we want to detect an ability with value=0-20 and an ability with add=15 is present, this is detected because the system assigns a value of 0 when 'value' is not present, and so the system matches abilities that do not use 'value' or even no numerical value at all. it is therefore necessary to decide that the absence of an attribute is a non-correspondence to the criteria.
There are questions about how this filter should treat empty values, and the
use cases that we can think of can be implemented in other ways, for example,
if we want to look for big damage boosts, then we could filter for
`add=5-infinity` `[or]` `multiply=2-infinity`.
The simple answer seems to be to remove it from the API before we freeze for 1.18.
There's more discussion in issue 7944.
Adds support for using these in the weapons and ability filters:
* "-1", which was previously treated as an parse error (no number before the separator).
* "-3--1"
* "-infinity" as the lower number in the range, provided a different upper number is given.
This treats "-infinity" (with no other number), "-infinity--infinity",
"infinity" (with no other number) and "infinity-infinity" as errors. It seems
unlikely that someone would intend to use a filter that can't match any
reasonable number.
The range "-infinity-infinity" will be parsed successfully. I don't see a use
case for that, but nor do I see a reason to add extra C++ to reject it.
However, it's not added to the schema, as I think it's good for the schema to
give a warning when someone creates a filter which will accept every value
(including accepting the default, so "-infinity-infinity" accepts the unset
value too).
Includes new unit tests for the C++ and the Lua stringx.parse_range functions.
The next commit adds more WML tests, but is kept separate to credit the author.
This started as a change to move common filter functions from unit.cpp to
somewhere that they could be reused for other config-based filters. In the
process a missing feature was found and added, the move is still included in a
single Git commit because the move was required in order to make these
functions accessible to the Boost unit tests.
Two CodeBlocks project files additionally get src/utils/any.hpp added,
which was in one of them but missing from the other two. I noticed because
these are alphabetically at the start of the src/utils file list.
Thanks to @CelticMinstrel for the review comments and Xcode project updates.
Support (fe)male_name key in unit.
Support FEMALE_NAME in macros for named units with random gender.
Add female variants to generic unit names in DiD, TSG and UtBS.
Previously the config class had an operator bool and
it was a common pattern to use if(const config& = cfg.child(..)).
While this pattern was nice to use. It has severe drawbacks, in
particular it was unclear whether a function that took a config&
parameter allowed "invalid" configs, while most functions
did not, there were some that did. Furtheremore it lead to a few
buggy codes that were unconvered by this change (Not fixed though!),
in particular codes that tested local config objects that were
not references to being invalid, which could never be the case.
This commits replaces those with just `true` in order to not
change behaviour.
Some obvious cases were also removed including for example
things like `assert(config());` There is ony case in the ai code
that i'm not 100% sure of where one implementation of a virtual
function checked for an invalid config and another one that didn't.
With this, all code that check for a config child to be
present now uses config::optional_child which returns an object
that behaves similar to optional<(const) config&>, so it throws
on invalid dereferencing. But it also has operator[string] for
convinience, in particular to make is similary
easy to use the the previous `if (config& = .. child())`.
Also it has a tool DEBUG_CONFIG which tests whether all
optional_config values are checked before they are derefereneced.
Another method manditory_child was
added that throws when the key is not found, which replaces all
occurances of child() that did not check whether the result was
valid. This was neccecary (this= adding a new method instead of
renaming .child) to keep track of converted changes, and be sure
no occurances of child() were accidentally changed to the
throwing version.
We might want to rename one of mandatory_child or optional_child
to just child later. Not sure which one yet. I think it's better
to keep it in the current state (no config::child() ) for a while
though, so that people that currently used child() in their open
prs or other work get an error and not wrongly rely on the previous
behviour of config::child.
The interface of vconfig was not changed in this commit.
This will also accept them during multiplayer matches, but it will still
warn if the unit's stats have changed. When using the new option, the
checksum includes data that has been ignored since 93fe5607a658c74b987.
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.
C++20 will add std::erase_if as a convenience wrapper around std::remove_if,
handling the subsequent call to std::vector::erase. This simplifies readability,
avoiding the need to either store the result of std::remove_if in a temporary
or to put the second argument of vector::erase after the body of a lambda.
This adds utils::erase_if, which does the same thing. The C++20 function returns
the number of elements removed, but as none of the callers need that I've not
implemented it in utils::erase_if.
This commit omits the refactor of attack_type::overwrite_special_checking,
because that function is being worked on in parallel by Newfrenchy. It'll be
simpler for either of us to update it later instead of creating merge conflicts.
This replaces the code for handling backstab with code that converts it to something new that still works.
Thus, the deprecation message is now INDEFINITE instead of PREEMPTIVE.
The function is specified by [event]code= and will be passed the entire contents of the [event] tag (including the code itself).
If code= is omitted, a default is supplied which runs ActionWML; however, internally it is still a function rather than a list of ActionWML commands.
This has been megasquashed because it was a month-long mess of fixes
and reworks.
In summary:
* objects no-longer draw by hooking a DRAW event. In stead they
inherit from gui2::top_level_drawable, and implement its interface.
* the game display now renders to an offscreen buffer. This is used
to implement hardware scrolling, and to redraw after halos, floating
labels etc. move.
* halos, floating labels, tooltips, and a few more things are now
drawn on top of the game display, rather than as part of it. This
allows them to be updated independently without reading pixels
from the screen.
* surface restorers have been removed. Reading pixels from the screen
should now be unnecessary excepting two cases: (a) screenshots,
(b) background blur. Blur is cached, and screenshots are occasional.
* GUI2 widgets no longer keep track of dirty state. They are redrawn
as necessary. Most places which previously set dirty state now queue
a redraw in their part of the screen in stead.
* A consequence is that active translucency is enabled across all UI
elements, and the game display can (and does) continue to animate
while menus and dialogs are showing.
* performance is drastically increased for basically everything, most
notably map scrolling, floating text, and halos.
* CPU usage is drastically decreased. With animations disabled it is
essentially zero while nothing is moving.
* GPU usage is also minimal. The display is only flipped if something
is drawn.
* 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.
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.
Refactor special notes for abilities, attack types, movetypes and weapon specials
An easier way of setting special notes in the most common use-cases. Text given
in the following attributes will be collected and added to the special notes
for units and unit types (some of these were added in the previous commit):
* [ability tag name]special_note=
* [language]special_note_damage_type_TYPE=
* [movetype][special_note]note=
* [attack][specials][special tag name]special_note=
It's no longer necessary to put these notes in each unit_type's .cfg file, and
the macros for doing so are now deprecated.
C++ changes
-----
Simplify both unit_type::special_notes and unit::unit_special_notes. Add
utils::stable_unique, similar to std::unique but accepts non-ordered input and
preserves the order in the output.
Remove unit_type::has_special_notes() - callers can instead call
special_notes() and then check if the returned vector is empty, which removes
the need for duplicating code in unit_type.
Trade-off: the new [language]special_note_damage_type_TYPE is likely deprecated in 1.19.
-----
Adding [language]special_note_damage_type_TYPE= uses the same existing design
as [language]type_TYPE=, however both are hacks that don't fit the general
style of WML. It could be better to define a new [damage_type] tag that
supercedes both and also provides a place for specifying the damage icon;
however that won't be done in time for the API freeze for 1.16.
Doing it in the way that this commit does it is a hack, but it's one where
replacing it with the better solution in 1.18 will affect very few UMCs (only
those that define additional damage types). Even in the UMCs that would be
affected, it would likely only be a few changes in a single central file.
Trade-off: NOTE_DEFENSE_CAP is not auto-added
-----
It might be better to auto-add NOTE_DEFENSE_CAP when movetype.cpp detects that
the type has capped values. However as NOTE_SPIRIT already requires
[movetype][special_note], it's simple to use the same mechanism. If we decide
to change it to being auto-added, the current commit greatly reduces the number
of places that would need to change again, as it's now in the [movetype]
instead of the many [unit_type]s using that movetype.