mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
This commit is contained in:
parent
8aa57f0cbc
commit
c5440a1c6c
@ -2050,8 +2050,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
case ANY_LOCATION:
|
||||
if (myNumber > -1) //TODO: this should be checked for all actions
|
||||
{
|
||||
creatureCasting = stackCanCastSpell && !spellDestSelectMode; //as isCastingPossibleHere is not called
|
||||
legalAction = true;
|
||||
if(isCastingPossibleHere (sactive, shere, myNumber))
|
||||
legalAction = true;
|
||||
}
|
||||
break;
|
||||
case AIMED_SPELL_CREATURE:
|
||||
|
@ -624,7 +624,7 @@ std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex,
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<const CStack *> DefaultSpellMechanics::getAffectedStacks(const CBattleInfoCallback * cb, SpellTargetingContext & ctx) const
|
||||
std::vector<const CStack *> DefaultSpellMechanics::getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||
{
|
||||
std::vector<const CStack *> attackedCres = calculateAffectedStacks(cb, ctx);
|
||||
handleImmunities(cb, ctx, attackedCres);
|
||||
@ -707,8 +707,13 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBat
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||
{
|
||||
//no problems by default, this method is for spell-specific problems
|
||||
//common problems handled by CSpell
|
||||
if(ctx.mode == ECastingMode::CREATURE_ACTIVE_CASTING || ctx.mode == ECastingMode::HERO_CASTING)
|
||||
{
|
||||
std::vector<const CStack *> affected = getAffectedStacks(cb, ctx);
|
||||
if(affected.empty())
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
}
|
||||
|
||||
return ESpellCastProblem::OK;
|
||||
}
|
||||
|
||||
@ -836,6 +841,13 @@ bool DefaultSpellMechanics::requiresCreatureTarget() const
|
||||
return true;
|
||||
}
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem SpecialSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||
{
|
||||
//no problems by default
|
||||
//common problems handled by CSpell
|
||||
return ESpellCastProblem::OK;
|
||||
}
|
||||
|
||||
std::vector<const CStack *> SpecialSpellMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||
{
|
||||
return std::vector<const CStack *>();
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
DefaultSpellMechanics(CSpell * s): ISpellMechanics(s){};
|
||||
|
||||
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override;
|
||||
std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, SpellTargetingContext & ctx) const override final;
|
||||
std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override final;
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||
@ -91,6 +91,8 @@ class DLL_LINKAGE SpecialSpellMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
SpecialSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||
protected:
|
||||
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||
};
|
||||
|
@ -214,7 +214,7 @@ std::vector<BattleHex> CSpell::rangeInHexes(BattleHex centralHex, ui8 schoolLvl,
|
||||
std::vector<const CStack *> CSpell::getAffectedStacks(const CBattleInfoCallback * cb, ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const
|
||||
{
|
||||
SpellTargetingContext ctx(this, mode, caster, spellLvl, destination);
|
||||
return mechanics->getAffectedStacks(cb, ctx);;
|
||||
return mechanics->getAffectedStacks(cb, ctx);
|
||||
}
|
||||
|
||||
CSpell::ETargetType CSpell::getTargetType() const
|
||||
@ -362,81 +362,7 @@ ESpellCastProblem::ESpellCastProblem CSpell::canBeCastAt(const CBattleInfoCallba
|
||||
{
|
||||
SpellTargetingContext ctx(this, mode, caster, caster->getSpellSchoolLevel(this), destination);
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem specific = mechanics->canBeCast(cb, ctx);
|
||||
|
||||
if(specific != ESpellCastProblem::OK)
|
||||
return specific;
|
||||
|
||||
//todo: this should be moved to mechanics
|
||||
//rising spells handled by mechanics
|
||||
if(ctx.ti.onlyAlive && 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(ctx.ti.smart && isNegative() && aliveStack->owner == caster->getOwner())
|
||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||
if(ctx.ti.smart && 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
|
||||
{
|
||||
// Get all stacks at destination hex. only alive if not rising spell
|
||||
TStacks stacks = cb->battleGetStacksIf([=](const CStack * s)
|
||||
{
|
||||
return s->coversPos(destination) && s->isValidTarget(isRisingSpell());
|
||||
});
|
||||
|
||||
if(!stacks.empty())
|
||||
{
|
||||
bool allImmune = true;
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem problem = ESpellCastProblem::INVALID;
|
||||
|
||||
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;
|
||||
return mechanics->canBeCast(cb, ctx);
|
||||
}
|
||||
|
||||
int CSpell::adjustRawDamage(const ISpellCaster * caster, const CStack * affectedCreature, int rawDamage) const
|
||||
|
@ -298,10 +298,6 @@ 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);
|
||||
|
||||
|
@ -107,7 +107,7 @@ public:
|
||||
virtual ~ISpellMechanics(){};
|
||||
|
||||
virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
|
||||
virtual std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, SpellTargetingContext & ctx) const = 0;
|
||||
virtual std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const = 0;
|
||||
|
||||
virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user