1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Move battleIsImmune to CSpell

This commit is contained in:
AlexVinS 2014-11-29 04:25:51 +03:00
parent e8aeb0bf8e
commit b0df8172f9
4 changed files with 61 additions and 66 deletions

View File

@ -1565,60 +1565,6 @@ std::vector<BattleHex> CBattleInfoCallback::getAttackableBattleHexes() const
return attackableBattleHexes;
}
ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest) const
{
RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
// Get all stacks at destination hex -> subject of our spell. only alive if not rising spell
TStacks stacks = battleGetStacksIf([=](const CStack * s){
return s->coversPos(dest) && (spell->isRisingSpell() || s->alive());
});
if(!stacks.empty())
{
bool allImmune = true;
ESpellCastProblem::ESpellCastProblem problem;
for(auto s : stacks)
{
ESpellCastProblem::ESpellCastProblem res = spell->isImmuneByStack(caster,s);
if(res == ESpellCastProblem::OK)
{
allImmune = false;
}
else
{
problem = res;
}
}
if(allImmune)
return problem;
}
else //no target stack on this tile
{
if(spell->getTargetType() == CSpell::CREATURE)
{
if(caster && mode == ECastingMode::HERO_CASTING) //TODO why???
{
const CSpell::TargetInfo ti = spell->getTargetInfo(caster->getSpellSchoolLevel(spell));
if(!ti.massive)
return ESpellCastProblem::WRONG_SPELL_TARGET;
}
else
{
return ESpellCastProblem::WRONG_SPELL_TARGET;
}
}
}
return ESpellCastProblem::OK;
}
ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell( PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode ) const
{
RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
@ -1898,11 +1844,11 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
}
const CGHeroInstance * caster = nullptr;
if (mode == ECastingMode::HERO_CASTING)
return battleIsImmune(battleGetFightingHero(playerToSide(player)), spell, mode, dest);
else
return battleIsImmune(nullptr, spell, mode, dest);
caster = battleGetFightingHero(playerToSide(player));
return spell->isImmuneAt(this, caster, mode, dest);
}
const CStack * CBattleInfoCallback::getStackIf(std::function<bool(const CStack*)> pred) const

View File

@ -311,17 +311,10 @@ public:
AccessibilityInfo getAccesibility(const std::vector<BattleHex> &accessibleHexes) const; //given hexes will be marked as accessible
std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const;
protected:
//checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into acount general problems such as not having spellbook or mana points etc.
ESpellCastProblem::ESpellCastProblem battleIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, BattleHex dest) const;
ReachabilityInfo getFlyingReachability(const ReachabilityInfo::Parameters &params) const;
ReachabilityInfo makeBFS(const AccessibilityInfo &accessibility, const ReachabilityInfo::Parameters &params) const;
ReachabilityInfo makeBFS(const CStack *stack) const; //uses default parameters -> stack position and owner's perspective
std::set<BattleHex> getStoppers(BattlePerspective::BattlePerspective whichSidePerspective) const; //get hexes with stopping obstacles (quicksands)
};
class DLL_LINKAGE CPlayerBattleCallback : public CBattleInfoCallback

View File

@ -425,6 +425,58 @@ void CSpell::getEffects(std::vector<Bonus>& lst, const int level) const
}
}
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallback * cb, const CGHeroInstance * caster, ECastingMode::ECastingMode mode, BattleHex destination) const
{
// Get all stacks at destination hex. only alive if not rising spell
TStacks stacks = cb->battleGetStacksIf([=](const CStack * s){
return s->coversPos(destination) && (isRisingSpell() || s->alive());
});
if(!stacks.empty())
{
bool allImmune = true;
ESpellCastProblem::ESpellCastProblem problem;
for(auto s : stacks)
{
ESpellCastProblem::ESpellCastProblem res = isImmuneByStack(caster,s);
if(res == ESpellCastProblem::OK)
{
allImmune = false;
}
else
{
problem = res;
}
}
if(allImmune)
return problem;
}
else //no target stack on this tile
{
if(getTargetType() == CSpell::CREATURE)
{
if(caster && mode == ECastingMode::HERO_CASTING) //TODO why???
{
const CSpell::TargetInfo ti(this, caster->getSpellSchoolLevel(this), mode);
if(!ti.massive)
return ESpellCastProblem::WRONG_SPELL_TARGET;
}
else
{
return ESpellCastProblem::WRONG_SPELL_TARGET;
}
}
}
return ESpellCastProblem::OK;
}
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj) const
{
//todo: use new bonus API

View File

@ -214,6 +214,7 @@ public:
~CSpell();
bool isCastableBy(const IBonusBearer * caster, bool hasSpellBook, const std::set<SpellID> & spellBook) const;
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr ) const; //convert range to specific hexes; last optional out parameter is set to true, if spell would cover unavailable hexes (that are not included in ret)
ETargetType getTargetType() const; //deprecated
@ -239,10 +240,13 @@ public:
bool hasEffects() const;
void getEffects(std::vector<Bonus> &lst, const int level) const;
///checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into account general problems such as not having spellbook or mana points etc.
ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const CGHeroInstance * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
//internal, for use only by Mechanics classes
ESpellCastProblem::ESpellCastProblem isImmuneBy(const IBonusBearer *obj) const;
//checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into acount general problems such as not having spellbook or mana points etc.
//checks for creature immunity / anything that prevent casting *at given target* - doesn't take into account general problems such as not having spellbook or mana points etc.
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const;
//internal, for use only by Mechanics classes. applying secondary skills