1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-23 22:37:55 +02:00
Files
vcmi/lib/bonuses/Updaters.h

154 lines
4.4 KiB
C++
Raw Normal View History

2023-04-30 14:31:20 +03:00
/*
2023-04-30 16:52:48 +03:00
* Updaters.h, part of VCMI engine
2023-04-30 14:31:20 +03:00
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
2023-05-01 20:29:53 +03:00
#include "Bonus.h"
#include "../serializer/Serializeable.h"
2023-04-30 14:31:20 +03:00
VCMI_LIB_NAMESPACE_BEGIN
class AggregateLimiter;
class CCreatureTypeLimiter;
class HasAnotherBonusLimiter;
class CreatureTerrainLimiter;
class CreatureLevelLimiter;
class FactionLimiter;
class CreatureAlignmentLimiter;
class OppositeSideLimiter;
class RankRangeLimiter;
class UnitOnHexLimiter;
2023-04-30 14:31:20 +03:00
// observers for updating bonuses based on certain events (e.g. hero gaining level)
class DLL_LINKAGE IUpdater : public Serializeable
2023-04-30 14:31:20 +03:00
{
public:
virtual ~IUpdater() = default;
virtual std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context);
2023-04-30 14:31:20 +03:00
virtual std::string toString() const;
virtual JsonNode toJsonNode() const;
virtual void visitLimiter(AggregateLimiter & limiter);
virtual void visitLimiter(CCreatureTypeLimiter& limiter);
virtual void visitLimiter(HasAnotherBonusLimiter & limiter);
virtual void visitLimiter(CreatureTerrainLimiter & limiter);
virtual void visitLimiter(CreatureLevelLimiter & limiter);
virtual void visitLimiter(FactionLimiter & limiter);
virtual void visitLimiter(CreatureAlignmentLimiter & limiter) ;
virtual void visitLimiter(OppositeSideLimiter & limiter);
virtual void visitLimiter(RankRangeLimiter & limiter);
virtual void visitLimiter(UnitOnHexLimiter & limiter);
template <typename Handler> void serialize(Handler & h)
2023-04-30 14:31:20 +03:00
{
}
};
class DLL_LINKAGE GrowsWithLevelUpdater : public IUpdater
{
public:
int valPer20 = 0;
int stepSize = 1;
GrowsWithLevelUpdater() = default;
GrowsWithLevelUpdater(int valPer20, int stepSize = 1);
template <typename Handler> void serialize(Handler & h)
2023-04-30 14:31:20 +03:00
{
h & static_cast<IUpdater &>(*this);
h & valPer20;
h & stepSize;
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::string toString() const override;
JsonNode toJsonNode() const override;
2023-04-30 14:31:20 +03:00
};
class DLL_LINKAGE TimesHeroLevelUpdater : public IUpdater
{
public:
template <typename Handler> void serialize(Handler & h)
2023-04-30 14:31:20 +03:00
{
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::string toString() const override;
JsonNode toJsonNode() const override;
2023-04-30 14:31:20 +03:00
};
class DLL_LINKAGE TimesStackLevelUpdater : public IUpdater
{
Better support for Adela specialty (+new modding functionality for it) Fixes Adela specialty that was apparently broken back in #1518 and replaced with logic that was clearly not tested - it was neither functional, nor it was following H3 behavior. - `HAS_ANOTHER_BONUS_LIMITER` now accepts `null` in place of bonus type, for cases when limiting is needed by bonus source or bonus subtype. This allows Adela Bless specialty to always work, irregardless of which bonuses are provided by Bless. - Implemented `DIVIDE_STACK_LEVEL` updater that functions same as `TIMES_STACK_LEVEL`, but it divides bonus value, instead of multiplying it (to make Adela specialty weaker for high-tier units, as in H3) - Implemented `TIMES_HERO_LEVEL_DIVIDE_STACK_LEVEL` updater that combines two existing updaters, to implement `val * heroLevel / unitLevel` formula needed for Adela specialty - Removed deprecated `ARMY_MOVEMENT` updater. Its functionality has already been removed in 1.6.X releases, and it was remaining only as a placeholder - Updated modding documentation to account for these changes & to remove some TODO's Fixed regression from #777 that could led to either duplicated bonuses or to multiple application of updaters. It introduced double-recursion - node parents were gathered recursively, and then bonuses were also collected recursively within each parent. This created situation where updater could be applied different number of times. For example, hero bonus that is propagated to unit in combat could be selected directly, or via hero->combat unit chain, or via hero->garrison unit->combat unit chains, leading to different calls to updaters if updater handles garrison unit node type
2025-04-11 15:04:30 +03:00
std::shared_ptr<Bonus> apply(const std::shared_ptr<Bonus> & b, int level) const;
2023-04-30 14:31:20 +03:00
public:
template <typename Handler> void serialize(Handler & h)
2023-04-30 14:31:20 +03:00
{
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::string toString() const override;
JsonNode toJsonNode() const override;
2023-04-30 14:31:20 +03:00
};
Better support for Adela specialty (+new modding functionality for it) Fixes Adela specialty that was apparently broken back in #1518 and replaced with logic that was clearly not tested - it was neither functional, nor it was following H3 behavior. - `HAS_ANOTHER_BONUS_LIMITER` now accepts `null` in place of bonus type, for cases when limiting is needed by bonus source or bonus subtype. This allows Adela Bless specialty to always work, irregardless of which bonuses are provided by Bless. - Implemented `DIVIDE_STACK_LEVEL` updater that functions same as `TIMES_STACK_LEVEL`, but it divides bonus value, instead of multiplying it (to make Adela specialty weaker for high-tier units, as in H3) - Implemented `TIMES_HERO_LEVEL_DIVIDE_STACK_LEVEL` updater that combines two existing updaters, to implement `val * heroLevel / unitLevel` formula needed for Adela specialty - Removed deprecated `ARMY_MOVEMENT` updater. Its functionality has already been removed in 1.6.X releases, and it was remaining only as a placeholder - Updated modding documentation to account for these changes & to remove some TODO's Fixed regression from #777 that could led to either duplicated bonuses or to multiple application of updaters. It introduced double-recursion - node parents were gathered recursively, and then bonuses were also collected recursively within each parent. This created situation where updater could be applied different number of times. For example, hero bonus that is propagated to unit in combat could be selected directly, or via hero->combat unit chain, or via hero->garrison unit->combat unit chains, leading to different calls to updaters if updater handles garrison unit node type
2025-04-11 15:04:30 +03:00
class DLL_LINKAGE DivideStackLevelUpdater : public IUpdater
2023-04-30 14:31:20 +03:00
{
Better support for Adela specialty (+new modding functionality for it) Fixes Adela specialty that was apparently broken back in #1518 and replaced with logic that was clearly not tested - it was neither functional, nor it was following H3 behavior. - `HAS_ANOTHER_BONUS_LIMITER` now accepts `null` in place of bonus type, for cases when limiting is needed by bonus source or bonus subtype. This allows Adela Bless specialty to always work, irregardless of which bonuses are provided by Bless. - Implemented `DIVIDE_STACK_LEVEL` updater that functions same as `TIMES_STACK_LEVEL`, but it divides bonus value, instead of multiplying it (to make Adela specialty weaker for high-tier units, as in H3) - Implemented `TIMES_HERO_LEVEL_DIVIDE_STACK_LEVEL` updater that combines two existing updaters, to implement `val * heroLevel / unitLevel` formula needed for Adela specialty - Removed deprecated `ARMY_MOVEMENT` updater. Its functionality has already been removed in 1.6.X releases, and it was remaining only as a placeholder - Updated modding documentation to account for these changes & to remove some TODO's Fixed regression from #777 that could led to either duplicated bonuses or to multiple application of updaters. It introduced double-recursion - node parents were gathered recursively, and then bonuses were also collected recursively within each parent. This created situation where updater could be applied different number of times. For example, hero bonus that is propagated to unit in combat could be selected directly, or via hero->combat unit chain, or via hero->garrison unit->combat unit chains, leading to different calls to updaters if updater handles garrison unit node type
2025-04-11 15:04:30 +03:00
std::shared_ptr<Bonus> apply(const std::shared_ptr<Bonus> & b, int level) const;
2023-04-30 14:31:20 +03:00
public:
template <typename Handler> void serialize(Handler & h)
2023-04-30 14:31:20 +03:00
{
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::string toString() const override;
JsonNode toJsonNode() const override;
2023-04-30 14:31:20 +03:00
};
Better support for Adela specialty (+new modding functionality for it) Fixes Adela specialty that was apparently broken back in #1518 and replaced with logic that was clearly not tested - it was neither functional, nor it was following H3 behavior. - `HAS_ANOTHER_BONUS_LIMITER` now accepts `null` in place of bonus type, for cases when limiting is needed by bonus source or bonus subtype. This allows Adela Bless specialty to always work, irregardless of which bonuses are provided by Bless. - Implemented `DIVIDE_STACK_LEVEL` updater that functions same as `TIMES_STACK_LEVEL`, but it divides bonus value, instead of multiplying it (to make Adela specialty weaker for high-tier units, as in H3) - Implemented `TIMES_HERO_LEVEL_DIVIDE_STACK_LEVEL` updater that combines two existing updaters, to implement `val * heroLevel / unitLevel` formula needed for Adela specialty - Removed deprecated `ARMY_MOVEMENT` updater. Its functionality has already been removed in 1.6.X releases, and it was remaining only as a placeholder - Updated modding documentation to account for these changes & to remove some TODO's Fixed regression from #777 that could led to either duplicated bonuses or to multiple application of updaters. It introduced double-recursion - node parents were gathered recursively, and then bonuses were also collected recursively within each parent. This created situation where updater could be applied different number of times. For example, hero bonus that is propagated to unit in combat could be selected directly, or via hero->combat unit chain, or via hero->garrison unit->combat unit chains, leading to different calls to updaters if updater handles garrison unit node type
2025-04-11 15:04:30 +03:00
class DLL_LINKAGE TimesHeroLevelDivideStackLevelUpdater : public TimesHeroLevelUpdater
{
std::shared_ptr<DivideStackLevelUpdater> divideStackLevel;
public:
template <typename Handler> void serialize(Handler & h)
{
h & static_cast<TimesHeroLevelUpdater &>(*this);
h & divideStackLevel;
}
TimesHeroLevelDivideStackLevelUpdater()
: divideStackLevel(std::make_shared<DivideStackLevelUpdater>())
{}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) override;
std::string toString() const override;
JsonNode toJsonNode() const override;
};
2023-04-30 14:31:20 +03:00
class DLL_LINKAGE OwnerUpdater : public IUpdater
{
protected:
PlayerColor owner;
2023-04-30 14:31:20 +03:00
public:
template <typename Handler> void serialize(Handler& h)
2023-04-30 14:31:20 +03:00
{
h & static_cast<IUpdater &>(*this);
}
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus>& b, const CBonusSystemNode& context) override;
std::string toString() const override;
JsonNode toJsonNode() const override;
void visitLimiter(OppositeSideLimiter& limiter) override;
2023-04-30 14:31:20 +03:00
};
VCMI_LIB_NAMESPACE_END