mirror of
https://github.com/vcmi/vcmi.git
synced 2025-12-07 23:33:15 +02:00
hacks to optimize a few bonus requests
This commit is contained in:
@@ -152,6 +152,120 @@ const BonusList * CBonusProxy::operator->() const
|
||||
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()
|
||||
{
|
||||
}
|
||||
@@ -467,6 +581,22 @@ void BonusList::insert(BonusList::TInternalContainer::iterator position, BonusLi
|
||||
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
|
||||
{
|
||||
return valOfBonuses(Selector::type(type).And(selector));
|
||||
@@ -532,13 +662,12 @@ bool IBonusBearer::hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const
|
||||
|
||||
int IBonusBearer::MoraleVal() const
|
||||
{
|
||||
if(hasBonusOfType(Bonus::NON_LIVING) || hasBonusOfType(Bonus::UNDEAD) ||
|
||||
hasBonusOfType(Bonus::NO_MORALE) || hasBonusOfType(Bonus::SIEGE_WEAPON))
|
||||
if(anaffectedByMorale.getHasBonus())
|
||||
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);
|
||||
|
||||
return vstd::abetween(ret, -3, +3);
|
||||
|
||||
Reference in New Issue
Block a user