diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 45caf5f54..bd7d3ea1d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -71,7 +71,6 @@ set(lib_MAIN_SRCS bonuses/BonusParams.cpp bonuses/BonusSelector.cpp bonuses/BonusCustomTypes.cpp - bonuses/CBonusProxy.cpp bonuses/CBonusSystemNode.cpp bonuses/IBonusBearer.cpp bonuses/Limiters.cpp @@ -442,7 +441,6 @@ set(lib_MAIN_HEADERS bonuses/BonusParams.h bonuses/BonusSelector.h bonuses/BonusCustomTypes.h - bonuses/CBonusProxy.h bonuses/CBonusSystemNode.h bonuses/IBonusBearer.h bonuses/Limiters.h diff --git a/lib/battle/CUnitState.cpp b/lib/battle/CUnitState.cpp index f8d1430fa..f1b0f0f7d 100644 --- a/lib/battle/CUnitState.cpp +++ b/lib/battle/CUnitState.cpp @@ -84,13 +84,13 @@ void CAmmo::serializeJson(JsonSerializeFormat & handler) ///CShots CShots::CShots(const battle::Unit * Owner) : CAmmo(Owner, Selector::type()(BonusType::SHOTS)), - shooter(Owner, BonusType::SHOOTER) + shooter(Owner, Selector::type()(BonusType::SHOOTER)) { } bool CShots::isLimited() const { - return !shooter.getHasBonus() || !env->unitHasAmmoCart(owner); + return !shooter.hasBonus() || !env->unitHasAmmoCart(owner); } void CShots::setEnv(const IUnitEnvironment * env_) @@ -100,7 +100,7 @@ void CShots::setEnv(const IUnitEnvironment * env_) int32_t CShots::total() const { - if(shooter.getHasBonus()) + if(shooter.hasBonus()) return CAmmo::total(); else return 0; @@ -116,19 +116,19 @@ CCasts::CCasts(const battle::Unit * Owner): CRetaliations::CRetaliations(const battle::Unit * Owner) : CAmmo(Owner, Selector::type()(BonusType::ADDITIONAL_RETALIATION)), totalCache(0), - noRetaliation(Owner, Selector::type()(BonusType::SIEGE_WEAPON).Or(Selector::type()(BonusType::HYPNOTIZED)).Or(Selector::type()(BonusType::NO_RETALIATION)), "CRetaliations::noRetaliation"), - unlimited(Owner, BonusType::UNLIMITED_RETALIATIONS) + noRetaliation(Owner, Selector::type()(BonusType::SIEGE_WEAPON).Or(Selector::type()(BonusType::HYPNOTIZED)).Or(Selector::type()(BonusType::NO_RETALIATION))), + unlimited(Owner, Selector::type()(BonusType::UNLIMITED_RETALIATIONS)) { } bool CRetaliations::isLimited() const { - return !unlimited.getHasBonus() || noRetaliation.getHasBonus(); + return !unlimited.hasBonus() || noRetaliation.hasBonus(); } int32_t CRetaliations::total() const { - if(noRetaliation.getHasBonus()) + if(noRetaliation.hasBonus()) return 0; //after dispel bonus should remain during current round @@ -336,7 +336,6 @@ CUnitState::CUnitState(): stackSpeedPerTurn(this, Selector::type()(BonusType::STACKS_SPEED), BonusCacheMode::VALUE), immobilizedPerTurn(this, Selector::type()(BonusType::SIEGE_WEAPON).Or(Selector::type()(BonusType::BIND_EFFECT)), BonusCacheMode::PRESENCE), bonusCache(this, generateBonusSelectors()), - cloneLifetimeMarker(this, Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(SpellID(SpellID::CLONE)))), "CUnitState::cloneLifetimeMarker"), cloneID(-1) { @@ -360,11 +359,7 @@ CUnitState & CUnitState::operator=(const CUnitState & other) waiting = other.waiting; waitedThisTurn = other.waitedThisTurn; casts = other.casts; - counterAttacks = other.counterAttacks; health = other.health; - shots = other.shots; -// bonusCache = other.bonusCache; - cloneLifetimeMarker = other.cloneLifetimeMarker; cloneID = other.cloneID; position = other.position; return *this; @@ -913,7 +908,7 @@ void CUnitState::afterNewRound() if(alive() && isClone()) { - if(!cloneLifetimeMarker.getHasBonus()) + if(!bonusCache.hasBonus(UnitBonusValuesProxy::CLONE_MARKER)) makeGhost(); } } @@ -964,6 +959,7 @@ const UnitBonusValuesProxy::SelectorsArray * CUnitState::generateBonusSelectors( Selector::type()(BonusType::HYPNOTIZED),//HYPNOTIZED, Selector::type()(BonusType::FREE_SHOOTING).Or(Selector::type()(BonusType::SIEGE_WEAPON)),//HAS_FREE_SHOOTING, Selector::type()(BonusType::STACK_HEALTH),//STACK_HEALTH, + Selector::type()(BonusType::NONE).And(Selector::source(BonusSource::SPELL_EFFECT, BonusSourceID(SpellID(SpellID::CLONE)))) }; return &selectors; diff --git a/lib/battle/CUnitState.h b/lib/battle/CUnitState.h index fe83f89ce..c2a323e7f 100644 --- a/lib/battle/CUnitState.h +++ b/lib/battle/CUnitState.h @@ -11,7 +11,6 @@ #pragma once #include "Unit.h" -#include "../bonuses/CBonusProxy.h" #include "../bonuses/BonusCache.h" VCMI_LIB_NAMESPACE_BEGIN @@ -62,7 +61,7 @@ public: private: const IUnitEnvironment * env; - CCheckProxy shooter; + BonusValueCache shooter; }; class DLL_LINKAGE CCasts : public CAmmo @@ -84,8 +83,8 @@ public: private: mutable int32_t totalCache; - CCheckProxy noRetaliation; - CCheckProxy unlimited; + BonusValueCache noRetaliation; + BonusValueCache unlimited; }; class DLL_LINKAGE CHealth @@ -268,7 +267,6 @@ private: BonusCachePerTurn immobilizedPerTurn; BonusCachePerTurn stackSpeedPerTurn; UnitBonusValuesProxy bonusCache; - CCheckProxy cloneLifetimeMarker; void reset(); }; diff --git a/lib/bonuses/BonusCache.cpp b/lib/bonuses/BonusCache.cpp index 6c07c59ec..5e037ee3c 100644 --- a/lib/bonuses/BonusCache.cpp +++ b/lib/bonuses/BonusCache.cpp @@ -50,6 +50,11 @@ int BonusValueCache::getValue() const return getBonusValueImpl(value, selector, BonusCacheMode::VALUE); } +bool BonusValueCache::hasBonus() const +{ + return getBonusValueImpl(value, selector, BonusCacheMode::PRESENCE); +} + MagicSchoolMasteryCache::MagicSchoolMasteryCache(const IBonusBearer * target) :target(target) {} diff --git a/lib/bonuses/BonusCache.h b/lib/bonuses/BonusCache.h index 54f520119..b3209e880 100644 --- a/lib/bonuses/BonusCache.h +++ b/lib/bonuses/BonusCache.h @@ -45,6 +45,7 @@ class BonusValueCache : public BonusCacheBase public: BonusValueCache(const IBonusBearer * target, const CSelector selector); int getValue() const; + bool hasBonus() const; }; /// Cache that can track a list of queries to bonus system @@ -101,6 +102,8 @@ public: HAS_FREE_SHOOTING, STACK_HEALTH, + CLONE_MARKER, + TOTAL_KEYS, }; static constexpr size_t KEYS_COUNT = static_cast(ECacheKeys::TOTAL_KEYS); diff --git a/lib/bonuses/CBonusProxy.cpp b/lib/bonuses/CBonusProxy.cpp deleted file mode 100644 index 263f42ad8..000000000 --- a/lib/bonuses/CBonusProxy.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * CBonusProxy.cpp, part of VCMI engine - * - * 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 - * - */ - -#include "StdInc.h" -#include "CBonusProxy.h" -#include "IBonusBearer.h" - -VCMI_LIB_NAMESPACE_BEGIN - -///CCheckProxy -CCheckProxy::CCheckProxy(const IBonusBearer * Target, BonusType bonusType): - target(Target), - selector(Selector::type()(bonusType)), - cachingStr("type_" + std::to_string(static_cast(bonusType))), - cachedLast(0), - hasBonus(false) -{ - -} - -CCheckProxy::CCheckProxy(const IBonusBearer * Target, CSelector Selector, const std::string & cachingStr): - target(Target), - selector(std::move(Selector)), - cachedLast(0), - cachingStr(cachingStr), - hasBonus(false) -{ -} - -//This constructor should be placed here to avoid side effects -CCheckProxy::CCheckProxy(const CCheckProxy & other) = default; - -bool CCheckProxy::getHasBonus() const -{ - const auto treeVersion = target->getTreeVersion(); - - if(treeVersion != cachedLast) - { - hasBonus = target->hasBonus(selector, cachingStr); - cachedLast = treeVersion; - } - - return hasBonus; -} - -VCMI_LIB_NAMESPACE_END diff --git a/lib/bonuses/CBonusProxy.h b/lib/bonuses/CBonusProxy.h deleted file mode 100644 index 68fc1ebe7..000000000 --- a/lib/bonuses/CBonusProxy.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * CBonusProxy.h, part of VCMI engine - * - * 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 - -#include "BonusSelector.h" - -VCMI_LIB_NAMESPACE_BEGIN - -class DLL_LINKAGE CCheckProxy -{ -public: - CCheckProxy(const IBonusBearer * Target, CSelector Selector, const std::string & cachingStr); - CCheckProxy(const IBonusBearer * Target, BonusType bonusType); - CCheckProxy(const CCheckProxy & other); - CCheckProxy& operator= (const CCheckProxy & other) = default; - - bool getHasBonus() const; - -private: - const IBonusBearer * target; - std::string cachingStr; - CSelector selector; - - mutable int64_t cachedLast; - mutable bool hasBonus; -}; - -VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/CArmedInstance.cpp b/lib/mapObjects/CArmedInstance.cpp index f2783662d..eddaf2d95 100644 --- a/lib/mapObjects/CArmedInstance.cpp +++ b/lib/mapObjects/CArmedInstance.cpp @@ -46,7 +46,7 @@ CArmedInstance::CArmedInstance(IGameCallback *cb) CArmedInstance::CArmedInstance(IGameCallback *cb, bool isHypothetic): CGObjectInstance(cb), CBonusSystemNode(isHypothetic), - nonEvilAlignmentMix(this, BonusType::NONEVIL_ALIGNMENT_MIX), // Take Angelic Alliance troop-mixing freedom of non-evil units into account. + nonEvilAlignmentMix(this, Selector::type()(BonusType::NONEVIL_ALIGNMENT_MIX)), // Take Angelic Alliance troop-mixing freedom of non-evil units into account. battle(nullptr) { } @@ -86,7 +86,7 @@ void CArmedInstance::updateMoraleBonusFromArmy() size_t factionsInArmy = factions.size(); //town garrison seems to take both sets into account - if (nonEvilAlignmentMix.getHasBonus()) + if (nonEvilAlignmentMix.hasBonus()) { size_t mixableFactions = 0; diff --git a/lib/mapObjects/CArmedInstance.h b/lib/mapObjects/CArmedInstance.h index 8c50cba16..cbd943ea0 100644 --- a/lib/mapObjects/CArmedInstance.h +++ b/lib/mapObjects/CArmedInstance.h @@ -11,8 +11,8 @@ #include "CGObjectInstance.h" #include "../CCreatureSet.h" -#include "../bonuses/CBonusProxy.h" #include "../bonuses/CBonusSystemNode.h" +#include "../bonuses/BonusCache.h" VCMI_LIB_NAMESPACE_BEGIN @@ -23,8 +23,7 @@ class JsonSerializeFormat; class DLL_LINKAGE CArmedInstance: public CGObjectInstance, public CBonusSystemNode, public CCreatureSet, public IConstBonusProvider { private: - CCheckProxy nonEvilAlignmentMix; - static CSelector nonEvilAlignmentMixSelector; + BonusValueCache nonEvilAlignmentMix; public: BattleInfo *battle; //set to the current battle, if engaged