mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
hacks to optimize a few bonus requests
This commit is contained in:
parent
cc75b859d4
commit
d782ee39df
@ -152,6 +152,120 @@ const BonusList * CBonusProxy::operator->() const
|
|||||||
return get().get();
|
return get().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTotalsProxy::CTotalsProxy(const IBonusBearer * Target, CSelector Selector, int InitialValue)
|
||||||
|
: target(Target),
|
||||||
|
selector(Selector),
|
||||||
|
initialValue(InitialValue),
|
||||||
|
meleeCachedLast(0),
|
||||||
|
meleeValue(0),
|
||||||
|
rangedCachedLast(0),
|
||||||
|
rangedValue(0),
|
||||||
|
value(0),
|
||||||
|
cachedLast(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CTotalsProxy::CTotalsProxy(const CTotalsProxy & other)
|
||||||
|
: target(other.target),
|
||||||
|
selector(other.selector),
|
||||||
|
initialValue(other.initialValue),
|
||||||
|
meleeCachedLast(other.meleeCachedLast),
|
||||||
|
meleeValue(other.meleeValue),
|
||||||
|
rangedCachedLast(other.rangedCachedLast),
|
||||||
|
rangedValue(other.rangedValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CTotalsProxy & CTotalsProxy::operator=(const CTotalsProxy & other)
|
||||||
|
{
|
||||||
|
initialValue = other.initialValue;
|
||||||
|
meleeCachedLast = other.meleeCachedLast;
|
||||||
|
meleeValue = other.meleeValue;
|
||||||
|
rangedCachedLast = other.rangedCachedLast;
|
||||||
|
rangedValue = other.rangedValue;
|
||||||
|
value = other.value;
|
||||||
|
cachedLast = other.cachedLast;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTotalsProxy::getValue() const
|
||||||
|
{
|
||||||
|
const auto treeVersion = target->getTreeVersion();
|
||||||
|
|
||||||
|
if(treeVersion != cachedLast)
|
||||||
|
{
|
||||||
|
auto bonuses = target->getBonuses(selector);
|
||||||
|
|
||||||
|
value = initialValue + bonuses->totalValue();
|
||||||
|
cachedLast = treeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTotalsProxy::getMeleeValue() const
|
||||||
|
{
|
||||||
|
static const auto limit = Selector::effectRange(Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_MELEE_FIGHT));
|
||||||
|
|
||||||
|
const auto treeVersion = target->getTreeVersion();
|
||||||
|
|
||||||
|
if(treeVersion != meleeCachedLast)
|
||||||
|
{
|
||||||
|
auto bonuses = target->getBonuses(selector, limit);
|
||||||
|
meleeValue = initialValue + bonuses->totalValue();
|
||||||
|
meleeCachedLast = treeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return meleeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTotalsProxy::getRangedValue() const
|
||||||
|
{
|
||||||
|
static const auto limit = Selector::effectRange(Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT));
|
||||||
|
|
||||||
|
const auto treeVersion = target->getTreeVersion();
|
||||||
|
|
||||||
|
if(treeVersion != rangedCachedLast)
|
||||||
|
{
|
||||||
|
auto bonuses = target->getBonuses(selector, limit);
|
||||||
|
rangedValue = initialValue + bonuses->totalValue();
|
||||||
|
rangedCachedLast = treeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rangedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
///CCheckProxy
|
||||||
|
CCheckProxy::CCheckProxy(const IBonusBearer * Target, CSelector Selector)
|
||||||
|
: target(Target),
|
||||||
|
selector(Selector),
|
||||||
|
cachedLast(0),
|
||||||
|
hasBonus(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CCheckProxy::CCheckProxy(const CCheckProxy & other)
|
||||||
|
: target(other.target),
|
||||||
|
selector(other.selector),
|
||||||
|
cachedLast(other.cachedLast),
|
||||||
|
hasBonus(other.hasBonus)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCheckProxy::getHasBonus() const
|
||||||
|
{
|
||||||
|
const auto treeVersion = target->getTreeVersion();
|
||||||
|
|
||||||
|
if(treeVersion != cachedLast)
|
||||||
|
{
|
||||||
|
hasBonus = target->hasBonus(selector);
|
||||||
|
cachedLast = treeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasBonus;
|
||||||
|
}
|
||||||
|
|
||||||
CAddInfo::CAddInfo()
|
CAddInfo::CAddInfo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -467,6 +581,22 @@ void BonusList::insert(BonusList::TInternalContainer::iterator position, BonusLi
|
|||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSelector IBonusBearer::anaffectedByMoraleSelector
|
||||||
|
= Selector::type(Bonus::NON_LIVING)
|
||||||
|
.Or(Selector::type(Bonus::UNDEAD))
|
||||||
|
.Or(Selector::type(Bonus::NO_MORALE))
|
||||||
|
.Or(Selector::type(Bonus::SIEGE_WEAPON));
|
||||||
|
|
||||||
|
CSelector IBonusBearer::moraleSelector = Selector::type(Bonus::MORALE);
|
||||||
|
CSelector IBonusBearer::selfMoraleSelector = Selector::type(Bonus::SELF_MORALE);
|
||||||
|
|
||||||
|
IBonusBearer::IBonusBearer()
|
||||||
|
:anaffectedByMorale(this, anaffectedByMoraleSelector),
|
||||||
|
moraleValue(this, moraleSelector, 0),
|
||||||
|
selfMorale(this, selfMoraleSelector)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
|
int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
|
||||||
{
|
{
|
||||||
return valOfBonuses(Selector::type(type).And(selector));
|
return valOfBonuses(Selector::type(type).And(selector));
|
||||||
@ -532,13 +662,12 @@ bool IBonusBearer::hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const
|
|||||||
|
|
||||||
int IBonusBearer::MoraleVal() const
|
int IBonusBearer::MoraleVal() const
|
||||||
{
|
{
|
||||||
if(hasBonusOfType(Bonus::NON_LIVING) || hasBonusOfType(Bonus::UNDEAD) ||
|
if(anaffectedByMorale.getHasBonus())
|
||||||
hasBonusOfType(Bonus::NO_MORALE) || hasBonusOfType(Bonus::SIEGE_WEAPON))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int ret = valOfBonuses(Bonus::MORALE);
|
int ret = moraleValue.getValue();
|
||||||
|
|
||||||
if(hasBonusOfType(Bonus::SELF_MORALE)) //eg. minotaur
|
if(selfMorale.getHasBonus()) //eg. minotaur
|
||||||
vstd::amax(ret, +1);
|
vstd::amax(ret, +1);
|
||||||
|
|
||||||
return vstd::abetween(ret, -3, +3);
|
return vstd::abetween(ret, -3, +3);
|
||||||
|
@ -87,6 +87,51 @@ private:
|
|||||||
mutable TBonusListPtr data;
|
mutable TBonusListPtr data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DLL_LINKAGE CTotalsProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTotalsProxy(const IBonusBearer * Target, CSelector Selector, int InitialValue);
|
||||||
|
CTotalsProxy(const CTotalsProxy & other);
|
||||||
|
CTotalsProxy(CTotalsProxy && other) = delete;
|
||||||
|
|
||||||
|
CTotalsProxy & operator=(const CTotalsProxy & other);
|
||||||
|
CTotalsProxy & operator=(CTotalsProxy && other) = delete;
|
||||||
|
|
||||||
|
int getMeleeValue() const;
|
||||||
|
int getRangedValue() const;
|
||||||
|
int getValue() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const IBonusBearer * target;
|
||||||
|
CSelector selector;
|
||||||
|
int initialValue;
|
||||||
|
|
||||||
|
mutable int64_t cachedLast;
|
||||||
|
mutable int value;
|
||||||
|
|
||||||
|
mutable int64_t meleeCachedLast;
|
||||||
|
mutable int meleeValue;
|
||||||
|
|
||||||
|
mutable int64_t rangedCachedLast;
|
||||||
|
mutable int rangedValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLL_LINKAGE CCheckProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CCheckProxy(const IBonusBearer * Target, CSelector Selector);
|
||||||
|
CCheckProxy(const CCheckProxy & other);
|
||||||
|
|
||||||
|
bool getHasBonus() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const IBonusBearer * target;
|
||||||
|
CSelector selector;
|
||||||
|
|
||||||
|
mutable int64_t cachedLast;
|
||||||
|
mutable bool hasBonus;
|
||||||
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CAddInfo : public std::vector<si32>
|
class DLL_LINKAGE CAddInfo : public std::vector<si32>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -641,11 +686,20 @@ public:
|
|||||||
|
|
||||||
class DLL_LINKAGE IBonusBearer
|
class DLL_LINKAGE IBonusBearer
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
static CSelector anaffectedByMoraleSelector;
|
||||||
|
CCheckProxy anaffectedByMorale;
|
||||||
|
static CSelector moraleSelector;
|
||||||
|
CTotalsProxy moraleValue;
|
||||||
|
static CSelector selfMoraleSelector;
|
||||||
|
CCheckProxy selfMorale;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//new bonusing node interface
|
//new bonusing node interface
|
||||||
// * selector is predicate that tests if HeroBonus matches our criteria
|
// * selector is predicate that tests if HeroBonus matches our criteria
|
||||||
// * root is node on which call was made (nullptr will be replaced with this)
|
// * root is node on which call was made (nullptr will be replaced with this)
|
||||||
//interface
|
//interface
|
||||||
|
IBonusBearer();
|
||||||
virtual const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const = 0;
|
virtual const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const = 0;
|
||||||
int valOfBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
int valOfBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||||
bool hasBonus(const CSelector &selector, const std::string &cachingStr = "") const;
|
bool hasBonus(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||||
|
@ -19,99 +19,6 @@
|
|||||||
|
|
||||||
namespace battle
|
namespace battle
|
||||||
{
|
{
|
||||||
|
|
||||||
CTotalsProxy::CTotalsProxy(const IBonusBearer * Target, CSelector Selector, int InitialValue)
|
|
||||||
: target(Target),
|
|
||||||
selector(Selector),
|
|
||||||
initialValue(InitialValue),
|
|
||||||
meleeCachedLast(0),
|
|
||||||
meleeValue(0),
|
|
||||||
rangedCachedLast(0),
|
|
||||||
rangedValue(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CTotalsProxy::CTotalsProxy(const CTotalsProxy & other)
|
|
||||||
: target(other.target),
|
|
||||||
selector(other.selector),
|
|
||||||
initialValue(other.initialValue),
|
|
||||||
meleeCachedLast(other.meleeCachedLast),
|
|
||||||
meleeValue(other.meleeValue),
|
|
||||||
rangedCachedLast(other.rangedCachedLast),
|
|
||||||
rangedValue(other.rangedValue)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CTotalsProxy & CTotalsProxy::operator=(const CTotalsProxy & other)
|
|
||||||
{
|
|
||||||
initialValue = other.initialValue;
|
|
||||||
meleeCachedLast = other.meleeCachedLast;
|
|
||||||
meleeValue = other.meleeValue;
|
|
||||||
rangedCachedLast = other.rangedCachedLast;
|
|
||||||
rangedValue = other.rangedValue;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CTotalsProxy::getMeleeValue() const
|
|
||||||
{
|
|
||||||
static const auto limit = Selector::effectRange(Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_MELEE_FIGHT));
|
|
||||||
|
|
||||||
const auto treeVersion = target->getTreeVersion();
|
|
||||||
|
|
||||||
if(treeVersion != meleeCachedLast)
|
|
||||||
{
|
|
||||||
auto bonuses = target->getBonuses(selector, limit);
|
|
||||||
meleeValue = initialValue + bonuses->totalValue();
|
|
||||||
meleeCachedLast = treeVersion;
|
|
||||||
}
|
|
||||||
return meleeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CTotalsProxy::getRangedValue() const
|
|
||||||
{
|
|
||||||
static const auto limit = Selector::effectRange(Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT));
|
|
||||||
|
|
||||||
const auto treeVersion = target->getTreeVersion();
|
|
||||||
|
|
||||||
if(treeVersion != rangedCachedLast)
|
|
||||||
{
|
|
||||||
auto bonuses = target->getBonuses(selector, limit);
|
|
||||||
rangedValue = initialValue + bonuses->totalValue();
|
|
||||||
rangedCachedLast = treeVersion;
|
|
||||||
}
|
|
||||||
return rangedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
///CCheckProxy
|
|
||||||
CCheckProxy::CCheckProxy(const IBonusBearer * Target, CSelector Selector)
|
|
||||||
: target(Target),
|
|
||||||
selector(Selector),
|
|
||||||
cachedLast(0),
|
|
||||||
hasBonus(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CCheckProxy::CCheckProxy(const CCheckProxy & other)
|
|
||||||
: target(other.target),
|
|
||||||
selector(other.selector),
|
|
||||||
cachedLast(other.cachedLast),
|
|
||||||
hasBonus(other.hasBonus)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCheckProxy::getHasBonus() const
|
|
||||||
{
|
|
||||||
const auto treeVersion = target->getTreeVersion();
|
|
||||||
|
|
||||||
if(treeVersion != cachedLast)
|
|
||||||
{
|
|
||||||
hasBonus = target->hasBonus(selector);
|
|
||||||
cachedLast = treeVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasBonus;
|
|
||||||
}
|
|
||||||
|
|
||||||
///CAmmo
|
///CAmmo
|
||||||
CAmmo::CAmmo(const battle::Unit * Owner, CSelector totalSelector)
|
CAmmo::CAmmo(const battle::Unit * Owner, CSelector totalSelector)
|
||||||
: used(0),
|
: used(0),
|
||||||
|
@ -24,47 +24,6 @@ namespace battle
|
|||||||
{
|
{
|
||||||
class CUnitState;
|
class CUnitState;
|
||||||
|
|
||||||
class DLL_LINKAGE CTotalsProxy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CTotalsProxy(const IBonusBearer * Target, CSelector Selector, int InitialValue);
|
|
||||||
CTotalsProxy(const CTotalsProxy & other);
|
|
||||||
CTotalsProxy(CTotalsProxy && other) = delete;
|
|
||||||
|
|
||||||
CTotalsProxy & operator=(const CTotalsProxy & other);
|
|
||||||
CTotalsProxy & operator=(CTotalsProxy && other) = delete;
|
|
||||||
|
|
||||||
int getMeleeValue() const;
|
|
||||||
int getRangedValue() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const IBonusBearer * target;
|
|
||||||
CSelector selector;
|
|
||||||
int initialValue;
|
|
||||||
|
|
||||||
mutable int64_t meleeCachedLast;
|
|
||||||
mutable int meleeValue;
|
|
||||||
|
|
||||||
mutable int64_t rangedCachedLast;
|
|
||||||
mutable int rangedValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DLL_LINKAGE CCheckProxy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CCheckProxy(const IBonusBearer * Target, CSelector Selector);
|
|
||||||
CCheckProxy(const CCheckProxy & other);
|
|
||||||
|
|
||||||
bool getHasBonus() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const IBonusBearer * target;
|
|
||||||
CSelector selector;
|
|
||||||
|
|
||||||
mutable int64_t cachedLast;
|
|
||||||
mutable bool hasBonus;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DLL_LINKAGE CAmmo
|
class DLL_LINKAGE CAmmo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -36,7 +36,11 @@ void CArmedInstance::randomizeArmy(int type)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Take Angelic Alliance troop-mixing freedom of non-evil units into account.
|
||||||
|
CSelector CArmedInstance::nonEvilAlignmentMixSelector = Selector::type(Bonus::NONEVIL_ALIGNMENT_MIX);
|
||||||
|
|
||||||
CArmedInstance::CArmedInstance()
|
CArmedInstance::CArmedInstance()
|
||||||
|
:nonEvilAlignmentMix(this, nonEvilAlignmentMixSelector)
|
||||||
{
|
{
|
||||||
battle = nullptr;
|
battle = nullptr;
|
||||||
}
|
}
|
||||||
@ -57,6 +61,9 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
|||||||
std::set<TFaction> factions;
|
std::set<TFaction> factions;
|
||||||
bool hasUndead = false;
|
bool hasUndead = false;
|
||||||
|
|
||||||
|
const std::string undeadCacheKey = "type_UNDEAD";
|
||||||
|
static const CSelector undeadSelector = Selector::type(Bonus::UNDEAD);
|
||||||
|
|
||||||
for(auto slot : Slots())
|
for(auto slot : Slots())
|
||||||
{
|
{
|
||||||
const CStackInstance * inst = slot.second;
|
const CStackInstance * inst = slot.second;
|
||||||
@ -64,13 +71,12 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
|||||||
|
|
||||||
factions.insert(creature->faction);
|
factions.insert(creature->faction);
|
||||||
// Check for undead flag instead of faction (undead mummies are neutral)
|
// Check for undead flag instead of faction (undead mummies are neutral)
|
||||||
hasUndead |= inst->hasBonusOfType(Bonus::UNDEAD);
|
hasUndead |= inst->hasBonus(undeadSelector, undeadCacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t factionsInArmy = factions.size(); //town garrison seems to take both sets into account
|
size_t factionsInArmy = factions.size(); //town garrison seems to take both sets into account
|
||||||
|
|
||||||
// Take Angelic Alliance troop-mixing freedom of non-evil units into account.
|
if (nonEvilAlignmentMix.getHasBonus())
|
||||||
if (hasBonusOfType(Bonus::NONEVIL_ALIGNMENT_MIX))
|
|
||||||
{
|
{
|
||||||
size_t mixableFactions = 0;
|
size_t mixableFactions = 0;
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ class CGameState;
|
|||||||
|
|
||||||
class DLL_LINKAGE CArmedInstance: public CGObjectInstance, public CBonusSystemNode, public CCreatureSet
|
class DLL_LINKAGE CArmedInstance: public CGObjectInstance, public CBonusSystemNode, public CCreatureSet
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
CCheckProxy nonEvilAlignmentMix;
|
||||||
|
static CSelector nonEvilAlignmentMixSelector;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BattleInfo *battle; //set to the current battle, if engaged
|
BattleInfo *battle; //set to the current battle, if engaged
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user