mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Factored out battleCanCastThisSpellHere
This commit is contained in:
parent
0d5eaa1183
commit
b09f150e7b
@ -1773,38 +1773,12 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
|
||||
logGlobal->errorStream() << "CBattleInfoCallback::battleCanCastThisSpellHere: no spellcaster.";
|
||||
return ESpellCastProblem::INVALID;
|
||||
}
|
||||
const PlayerColor player = caster->getOwner();
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem problem = battleCanCastThisSpell(caster, spell, mode);
|
||||
if(problem != ESpellCastProblem::OK)
|
||||
return problem;
|
||||
|
||||
problem = spell->canBeCastAt(this, caster, mode, dest);
|
||||
if(problem != ESpellCastProblem::OK)
|
||||
return problem;
|
||||
|
||||
//get dead stack if we cast resurrection or animate dead
|
||||
const CStack *deadStack = getStackIf([dest](const CStack *s) { return !s->alive() && s->coversPos(dest); });
|
||||
const CStack *aliveStack = getStackIf([dest](const CStack *s) { return s->alive() && s->coversPos(dest);});
|
||||
|
||||
|
||||
if(spell->isRisingSpell())
|
||||
{
|
||||
if(!deadStack && !aliveStack)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
if(deadStack && deadStack->owner != player) //you can resurrect only your own stacks //FIXME: it includes alive stacks as well
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
}
|
||||
else if(spell->getTargetType() == CSpell::CREATURE)
|
||||
{
|
||||
if(!aliveStack)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
if(spell->isNegative() && aliveStack->owner == player)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
if(spell->isPositive() && aliveStack->owner != player)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
}
|
||||
return spell->isImmuneAt(this, caster, mode, dest);
|
||||
return spell->canBeCastAt(this, caster, mode, dest);
|
||||
}
|
||||
|
||||
const CStack * CBattleInfoCallback::getStackIf(std::function<bool(const CStack*)> pred) const
|
||||
|
@ -573,12 +573,6 @@ bool RemoveObstacleMechanics::canRemove(const CObstacleInstance * obstacle, cons
|
||||
}
|
||||
|
||||
///RisingSpellMechanics
|
||||
ESpellCastProblem::ESpellCastProblem RisingSpellMechanics::canBeCast(const SpellTargetingContext & ctx) const
|
||||
{
|
||||
//todo: RisingSpellMechanics::canBeCast
|
||||
return ESpellCastProblem::OK;
|
||||
}
|
||||
|
||||
HealingSpellMechanics::EHealLevel RisingSpellMechanics::getHealLevel(int effectLevel) const
|
||||
{
|
||||
//this may be even distinct class
|
||||
@ -673,6 +667,21 @@ int SacrificeMechanics::calculateHealedHP(const SpellCastEnvironment* env, const
|
||||
}
|
||||
|
||||
///SpecialRisingSpellMechanics
|
||||
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::canBeCast(const SpellTargetingContext & ctx) const
|
||||
{
|
||||
const CStack * stack = ctx.cb->getStackIf([ctx](const CStack * s)
|
||||
{
|
||||
const bool ownerMatches = !ctx.ti.smart || s->getOwner() == ctx.caster->getOwner();
|
||||
|
||||
return ownerMatches && s->isValidTarget(true) && s->coversPos(ctx.destination);
|
||||
});
|
||||
|
||||
if(nullptr == stack)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
|
||||
return ESpellCastProblem::OK;
|
||||
}
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||
{
|
||||
// following does apply to resurrect and animate dead(?) only
|
||||
|
@ -125,7 +125,7 @@ class DLL_LINKAGE RisingSpellMechanics : public HealingSpellMechanics
|
||||
{
|
||||
public:
|
||||
RisingSpellMechanics(CSpell * s): HealingSpellMechanics(s){};
|
||||
ESpellCastProblem::ESpellCastProblem canBeCast(const SpellTargetingContext & ctx) const override;
|
||||
|
||||
EHealLevel getHealLevel(int effectLevel) const override;
|
||||
};
|
||||
|
||||
@ -140,11 +140,12 @@ protected:
|
||||
int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||
};
|
||||
|
||||
///all rising spells but SACRIFICE
|
||||
///ANIMATE_DEAD and RESURRECTION
|
||||
class DLL_LINKAGE SpecialRisingSpellMechanics : public RisingSpellMechanics
|
||||
{
|
||||
public:
|
||||
SpecialRisingSpellMechanics(CSpell * s): RisingSpellMechanics(s){};
|
||||
ESpellCastProblem::ESpellCastProblem canBeCast(const SpellTargetingContext & ctx) const override;
|
||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||
};
|
||||
|
||||
|
@ -222,11 +222,6 @@ bool CSpell::isNeutral() const
|
||||
return positiveness == NEUTRAL;
|
||||
}
|
||||
|
||||
bool CSpell::isHealingSpell() const
|
||||
{
|
||||
return isRisingSpell() || (id == SpellID::CURE);
|
||||
}
|
||||
|
||||
bool CSpell::isRisingSpell() const
|
||||
{
|
||||
return isRising;
|
||||
@ -307,12 +302,31 @@ void CSpell::getEffects(std::vector<Bonus> & lst, const int level) const
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem CSpell::canBeCastAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const
|
||||
{
|
||||
|
||||
//todo: CSpell::canBeCastAt check common problems
|
||||
|
||||
ISpellMechanics::SpellTargetingContext ctx(this, cb, mode, caster, caster->getSpellSchoolLevel(this), destination);
|
||||
|
||||
return mechanics->canBeCast(ctx);
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem specific = mechanics->canBeCast(ctx);
|
||||
|
||||
if(specific != ESpellCastProblem::OK)
|
||||
return specific;
|
||||
|
||||
//todo: this should be moved to mechanics
|
||||
if(ctx.ti.onlyAlive && ctx.ti.smart && getTargetType() == CSpell::CREATURE)
|
||||
{
|
||||
const CStack * aliveStack = cb->getStackIf([destination](const CStack * s)
|
||||
{
|
||||
return s->isValidTarget(false) && s->coversPos(destination);
|
||||
});
|
||||
|
||||
if(!aliveStack)
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
if(isNegative() && aliveStack->owner == caster->getOwner())
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
if(isPositive() && aliveStack->owner != caster->getOwner())
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
}
|
||||
|
||||
return isImmuneAt(cb, caster, mode, destination);
|
||||
}
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const
|
||||
|
@ -204,7 +204,6 @@ public:
|
||||
bool isNeutral() const;
|
||||
|
||||
bool isDamageSpell() const;
|
||||
bool isHealingSpell() const;
|
||||
bool isRisingSpell() const;
|
||||
bool isOffensiveSpell() const;
|
||||
|
||||
@ -272,9 +271,6 @@ public:
|
||||
///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 canBeCastAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
|
||||
|
||||
///checks for creature immunity *at given hex*.
|
||||
ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
|
||||
|
||||
///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 ISpellCaster * caster, const CStack * obj) const;
|
||||
public:
|
||||
@ -303,6 +299,10 @@ public://internal, for use only by Mechanics classes
|
||||
ESpellCastProblem::ESpellCastProblem internalIsImmune(const ISpellCaster * caster, const CStack *obj) const;
|
||||
|
||||
private:
|
||||
|
||||
///checks for creature immunity *at given hex*.
|
||||
ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
|
||||
|
||||
void setIsOffensive(const bool val);
|
||||
void setIsRising(const bool val);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user