1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
This commit is contained in:
AlexVinS 2016-10-02 01:32:28 +03:00
parent 8aa57f0cbc
commit c5440a1c6c
6 changed files with 23 additions and 87 deletions

View File

@ -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:

View File

@ -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 *>();

View File

@ -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;
};

View File

@ -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

View File

@ -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);

View File

@ -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;