1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

get rid of IBonusBearer::getSpellBonuses & Selector::anyRange

This commit is contained in:
AlexVinS 2016-10-01 09:07:18 +03:00
parent c243ae6f3e
commit 96c17505ae
6 changed files with 26 additions and 63 deletions

View File

@ -3206,12 +3206,12 @@ void CBattleInterface::showAliveStacks(SDL_Surface * to, std::vector<const CStac
return true; return true;
}; };
auto getEffectsPositivness = [&](const CStack * stack) -> int auto getEffectsPositivness = [&](const std::vector<si32> & activeSpells) -> int
{ {
int pos = 0; int pos = 0;
for(auto & spellId : stack->activeSpells()) for(const auto & spellId : activeSpells)
{ {
pos += CGI->spellh->objects[ spellId ]->positiveness; pos += CGI->spellh->objects.at(spellId)->positiveness;
} }
return pos; return pos;
}; };
@ -3243,8 +3243,9 @@ void CBattleInterface::showAliveStacks(SDL_Surface * to, std::vector<const CStac
//blitting amount background box //blitting amount background box
SDL_Surface *amountBG = amountNormal; SDL_Surface *amountBG = amountNormal;
if(!stack->getSpellBonuses()->empty()) std::vector<si32> activeSpells = stack->activeSpells();
amountBG = getAmountBoxBackground(getEffectsPositivness(stack)); if(!activeSpells.empty())
amountBG = getAmountBoxBackground(getEffectsPositivness(activeSpells));
SDL_Rect temp_rect = genRect(amountBG->h, amountBG->w, creAnims[stack->ID]->pos.x + xAdd, creAnims[stack->ID]->pos.y + yAdd); SDL_Rect temp_rect = genRect(amountBG->h, amountBG->w, creAnims[stack->ID]->pos.x + xAdd, creAnims[stack->ID]->pos.y + yAdd);
SDL_BlitSurface(amountBG, nullptr, to, &temp_rect); SDL_BlitSurface(amountBG, nullptr, to, &temp_rect);

View File

@ -324,14 +324,14 @@ void CStackWindow::CWindowSection::createActiveSpells()
for(si32 effect : spells) for(si32 effect : spells)
{ {
const CSpell * sp = CGI->spellh->objects[effect]; const CSpell * sp = CGI->spellh->objects[effect];
std::string spellText; std::string spellText;
//not all effects have graphics (for eg. Acid Breath) //not all effects have graphics (for eg. Acid Breath)
//for modded spells iconEffect is added to SpellInt.def //for modded spells iconEffect is added to SpellInt.def
const bool hasGraphics = (effect < SpellID::THUNDERBOLT) || (effect >= SpellID::AFTER_LAST); const bool hasGraphics = (effect < SpellID::THUNDERBOLT) || (effect >= SpellID::AFTER_LAST);
if (hasGraphics) if (hasGraphics)
{ {
spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds." spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds."
boost::replace_first (spellText, "%s", sp->name); boost::replace_first (spellText, "%s", sp->name);
@ -582,7 +582,7 @@ void CStackWindow::CWindowSection::createButtonPanel()
} }
if(LOCPLINT->cb->getResourceAmount().canAfford(totalCost)) if(LOCPLINT->cb->getResourceAmount().canAfford(totalCost))
{ {
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[207], onUpgrade, nullptr, true, resComps); LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[207], onUpgrade, nullptr, true, resComps);
} }
else else
@ -751,7 +751,7 @@ void CStackWindow::initSections()
void CStackWindow::initBonusesList() void CStackWindow::initBonusesList()
{ {
BonusList output, input; BonusList output, input;
input = *(info->stackNode->getBonuses(CSelector(Bonus::Permanent).And(Selector::anyRange()))); input = *(info->stackNode->getBonuses(CSelector(Bonus::Permanent), Selector::all));
while (!input.empty()) while (!input.empty())
{ {
@ -840,7 +840,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, bool popup):
info->creature = stack->type; info->creature = stack->type;
info->creatureCount = stack->count; info->creatureCount = stack->count;
info->popupWindow = popup; info->popupWindow = popup;
info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj); info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj);
init(); init();
} }
@ -870,7 +870,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup):
info->commander = commander; info->commander = commander;
info->creatureCount = 1; info->creatureCount = 1;
info->popupWindow = popup; info->popupWindow = popup;
info->owner = dynamic_cast<const CGHeroInstance *> (commander->armyObj); info->owner = dynamic_cast<const CGHeroInstance *> (commander->armyObj);
init(); init();
} }
@ -885,7 +885,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui3
info->levelupInfo = StackWindowInfo::CommanderLevelInfo(); info->levelupInfo = StackWindowInfo::CommanderLevelInfo();
info->levelupInfo->skills = skills; info->levelupInfo->skills = skills;
info->levelupInfo->callback = callback; info->levelupInfo->callback = callback;
info->owner = dynamic_cast<const CGHeroInstance *> (commander->armyObj); info->owner = dynamic_cast<const CGHeroInstance *> (commander->armyObj);
init(); init();
} }

View File

@ -973,7 +973,15 @@ std::vector<si32> CStack::activeSpells() const
{ {
std::vector<si32> ret; std::vector<si32> ret;
TBonusListPtr spellEffects = getSpellBonuses(); std::stringstream cachingStr;
cachingStr << "!type_" << Bonus::NONE << "source_" << Bonus::SPELL_EFFECT;
CSelector selector = Selector::sourceType(Bonus::SPELL_EFFECT)
.And(CSelector([](const Bonus *b)->bool
{
return b->type != Bonus::NONE;
}));
TBonusListPtr spellEffects = getBonuses(selector, Selector::all, cachingStr.str());
for(const std::shared_ptr<Bonus> it : *spellEffects) for(const std::shared_ptr<Bonus> it : *spellEffects)
{ {
if (!vstd::contains(ret, it->sid)) //do not duplicate spells with multiple effects if (!vstd::contains(ret, it->sid)) //do not duplicate spells with multiple effects

View File

@ -487,18 +487,6 @@ bool IBonusBearer::isLiving() const //TODO: theoreticaly there exists "LIVING" b
.Or(Selector::type(Bonus::SIEGE_WEAPON)), cachingStr.str()); .Or(Selector::type(Bonus::SIEGE_WEAPON)), cachingStr.str());
} }
const TBonusListPtr IBonusBearer::getSpellBonuses() const
{
std::stringstream cachingStr;
cachingStr << "!type_" << Bonus::NONE << "source_" << Bonus::SPELL_EFFECT;
CSelector selector = Selector::sourceType(Bonus::SPELL_EFFECT)
.And(CSelector([](const Bonus *b)->bool
{
return b->type != Bonus::NONE;
}));
return getBonuses(selector, Selector::anyRange(), cachingStr.str());
}
const std::shared_ptr<Bonus> IBonusBearer::getBonus(const CSelector &selector) const const std::shared_ptr<Bonus> IBonusBearer::getBonus(const CSelector &selector) const
{ {
auto bonuses = getAllBonuses(Selector::all, Selector::all); auto bonuses = getAllBonuses(Selector::all, Selector::all);
@ -1159,7 +1147,6 @@ namespace Selector
DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange); DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange);
DLL_LINKAGE CWillLastTurns turns; DLL_LINKAGE CWillLastTurns turns;
DLL_LINKAGE CWillLastDays days; DLL_LINKAGE CWillLastDays days;
DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange(&Bonus::effectRange);
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype) CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)
{ {

View File

@ -607,7 +607,6 @@ public:
si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge) si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const; int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const;
const TBonusListPtr getSpellBonuses() const;
}; };
class DLL_LINKAGE CBonusSystemNode : public IBonusBearer, public boost::noncopyable class DLL_LINKAGE CBonusSystemNode : public IBonusBearer, public boost::noncopyable
@ -757,25 +756,6 @@ public:
} }
}; };
template<typename T>
class CSelectFieldAny //allows to ignore value of certain field, that is to accept any value
{
T Bonus::*ptr;
public:
CSelectFieldAny(T Bonus::*Ptr)
: ptr(Ptr)
{
}
bool operator()(const Bonus *bonus) const
{
return true;
}
CSelectFieldAny& operator()()
{
return *this;
}
};
template<typename T> //can be same, needed for subtype field template<typename T> //can be same, needed for subtype field
class CSelectFieldEqualOrEvery class CSelectFieldEqualOrEvery
{ {
@ -979,7 +959,6 @@ namespace Selector
extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange; extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange;
extern DLL_LINKAGE CWillLastTurns turns; extern DLL_LINKAGE CWillLastTurns turns;
extern DLL_LINKAGE CWillLastDays days; extern DLL_LINKAGE CWillLastDays days;
extern DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange;
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype); CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info); CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info);

View File

@ -88,20 +88,8 @@ void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpell
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
{ {
TBonusListPtr spellBon = obj->getSpellBonuses(); if(!obj->hasBonus(Selector::positiveSpellEffects, Selector::all, "Selector::positiveSpellEffects"))
bool hasPositiveSpell = false;
for(const std::shared_ptr<Bonus> b : *spellBon)
{
if(SpellID(b->sid).toSpell()->isPositive())
{
hasPositiveSpell = true;
break;
}
}
if(!hasPositiveSpell)
{
return ESpellCastProblem::NO_SPELLS_TO_DISPEL; return ESpellCastProblem::NO_SPELLS_TO_DISPEL;
}
//use default algorithm only if there is no mechanics-related problem //use default algorithm only if there is no mechanics-related problem
return DefaultSpellMechanics::isImmuneByStack(caster,obj); return DefaultSpellMechanics::isImmuneByStack(caster,obj);