1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-24 03:47:18 +02:00

Use range limit selector when modifying bonus lists and checking for spell bonuses

* fixes http://bugs.vcmi.eu/view.php?id=2532
This commit is contained in:
AlexVinS 2016-09-30 17:11:17 +03:00
parent 0f7a68684d
commit 2f7e10a06f
3 changed files with 18 additions and 26 deletions

View File

@ -331,6 +331,11 @@ bool IBonusBearer::hasBonus(const CSelector &selector, const std::string &cachin
return getBonuses(selector, cachingStr)->size() > 0;
}
bool IBonusBearer::hasBonus(const CSelector &selector, const CSelector &limit, const std::string &cachingStr /*= ""*/) const
{
return getBonuses(selector, limit, cachingStr)->size() > 0;
}
bool IBonusBearer::hasBonusOfType(Bonus::BonusType type, int subtype /*= -1*/) const
{
std::stringstream cachingStr;
@ -369,7 +374,7 @@ bool IBonusBearer::hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const
{
std::stringstream cachingStr;
cachingStr << "source_" << source << "id_" << sourceID;
return hasBonus(Selector::source(source,sourceID), cachingStr.str());
return hasBonus(Selector::source(source,sourceID), Selector::all, cachingStr.str());
}
int IBonusBearer::MoraleVal() const
@ -521,28 +526,9 @@ const std::shared_ptr<Bonus> IBonusBearer::getEffect(ui16 id, int turn /*= 0*/)
return nullptr;
}
ui8 IBonusBearer::howManyEffectsSet(ui16 id) const
{
//TODO should check only local bonuses?
ui8 ret = 0;
auto bonuses = getAllBonuses();
for(auto& it : *bonuses)
{
if(it->source == Bonus::SPELL_EFFECT && it->sid == id) //effect found
{
++ret;
}
}
return ret;
}
const TBonusListPtr IBonusBearer::getAllBonuses() const
{
auto matchAll = [] (const Bonus *) { return true; };
auto matchNone = [] (const Bonus *) { return true; };
return getAllBonuses(matchAll, matchNone);
return getAllBonuses(Selector::all, Selector::all);
}
const std::shared_ptr<Bonus> IBonusBearer::getBonus(const CSelector &selector) const
@ -778,7 +764,7 @@ void CBonusSystemNode::detachFrom(CBonusSystemNode *parent)
void CBonusSystemNode::popBonuses(const CSelector &s)
{
BonusList bl;
exportedBonuses.getBonuses(bl, s);
exportedBonuses.getBonuses(bl, s, Selector::all);
for(auto b : bl)
removeBonus(b);
@ -789,7 +775,7 @@ void CBonusSystemNode::popBonuses(const CSelector &s)
void CBonusSystemNode::updateBonuses(const CSelector &s)
{
BonusList bl;
exportedBonuses.getBonuses(bl, s);
exportedBonuses.getBonuses(bl, s, Selector::all);
for(auto b : bl)
{
b->turnsRemain--;
@ -1237,6 +1223,9 @@ namespace Selector
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source);
}
DLL_LINKAGE CSelector all([](const Bonus * b){return true;});
DLL_LINKAGE CSelector none([](const Bonus * b){return false;});
bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type)
{
Bonus dummy;

View File

@ -582,6 +582,7 @@ public:
int getBonusesCount(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 CSelector &limit, const std::string &cachingStr = "") const;
const TBonusListPtr getBonuses(const CSelector &selector, const CSelector &limit, const std::string &cachingStr = "") const;
const TBonusListPtr getBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
@ -607,7 +608,6 @@ public:
virtual si32 magicResistance() const;
ui32 Speed(int turn = 0, bool useBind = false) const; //get speed of creature with all modificators
const std::shared_ptr<Bonus> getEffect(ui16 id, int turn = 0) const; //effect id (SP)
ui8 howManyEffectsSet(ui16 id) const; //returns amount of effects with given id set for this stack
si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const;
@ -991,6 +991,9 @@ namespace Selector
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID);
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source);
extern DLL_LINKAGE CSelector all;
extern DLL_LINKAGE CSelector none;
bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type);
bool DLL_LINKAGE matchesTypeSubtype(const CSelector &sel, Bonus::BonusType type, TBonusSubtype subtype);
bool DLL_LINKAGE positiveSpellEffects(const Bonus *b);

View File

@ -203,7 +203,7 @@ bool CureMechanics::dispellSelector(const Bonus * b)
ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
{
//Selector method name is ok as cashing string. --AVS
if(!obj->canBeHealed() && !obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector).And(CSelector(CureMechanics::dispellSelector)), "CureMechanics::dispellSelector"))
if(!obj->canBeHealed() && !obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector).And(CSelector(CureMechanics::dispellSelector)), Selector::all, "CureMechanics::dispellSelector"))
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
return DefaultSpellMechanics::isImmuneByStack(caster, obj);
@ -231,7 +231,7 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
}
if(obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector), "DefaultSpellMechanics::dispellSelector"))
if(obj->hasBonus(CSelector(DefaultSpellMechanics::dispellSelector), Selector::all, "DefaultSpellMechanics::dispellSelector"))
return ESpellCastProblem::OK;
else
return ESpellCastProblem::WRONG_SPELL_TARGET;