mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-31 22:05:10 +02:00
[Spells] Get rid of SpellTargetingContext.
This commit is contained in:
parent
7374689301
commit
f1a4831813
@ -93,34 +93,27 @@ ChainLightningMechanics::ChainLightningMechanics(const CSpell * s):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CStack *> ChainLightningMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
std::vector<const CStack *> ChainLightningMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const
|
||||||
{
|
{
|
||||||
std::vector<const CStack *> res;
|
std::vector<const CStack *> res;
|
||||||
|
|
||||||
std::set<BattleHex> possibleHexes;
|
std::set<BattleHex> possibleHexes;
|
||||||
for(auto stack : cb->battleGetAllStacks())
|
for(auto stack : cb->battleGetAllStacks())
|
||||||
{
|
{
|
||||||
if(stack->isValidTarget())
|
if(stack->isValidTarget())
|
||||||
{
|
|
||||||
for(auto hex : stack->getHexes())
|
for(auto hex : stack->getHexes())
|
||||||
{
|
possibleHexes.insert(hex);
|
||||||
possibleHexes.insert (hex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int targetsOnLevel[4] = {4, 4, 5, 5};
|
static const std::array<int, 4> targetsOnLevel = {4, 4, 5, 5};
|
||||||
|
|
||||||
BattleHex lightningHex = ctx.destination;
|
BattleHex lightningHex = destination;
|
||||||
for(int i = 0; i < targetsOnLevel[ctx.schoolLvl]; ++i)
|
for(int i = 0; i < targetsOnLevel.at(spellLvl); ++i)
|
||||||
{
|
{
|
||||||
auto stack = cb->battleGetStackByPos(lightningHex, true);
|
auto stack = cb->battleGetStackByPos(lightningHex, true);
|
||||||
if(!stack)
|
if(!stack)
|
||||||
break;
|
break;
|
||||||
res.push_back(stack);
|
res.push_back(stack);
|
||||||
for(auto hex : stack->getHexes())
|
for(auto hex : stack->getHexes())
|
||||||
{
|
|
||||||
possibleHexes.erase(hex); //can't hit same stack twice
|
possibleHexes.erase(hex); //can't hit same stack twice
|
||||||
}
|
|
||||||
if(possibleHexes.empty()) //not enough targets
|
if(possibleHexes.empty()) //not enough targets
|
||||||
break;
|
break;
|
||||||
lightningHex = BattleHex::getClosestTile(stack->side, lightningHex, possibleHexes);
|
lightningHex = BattleHex::getClosestTile(stack->side, lightningHex, possibleHexes);
|
||||||
@ -137,12 +130,10 @@ CloneMechanics::CloneMechanics(const CSpell * s):
|
|||||||
|
|
||||||
void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
const CStack * clonedStack = nullptr;
|
const CStack * clonedStack = vstd::frontOrNull(ctx.attackedCres);
|
||||||
if(ctx.attackedCres.size())
|
|
||||||
clonedStack = *ctx.attackedCres.begin();
|
|
||||||
if(!clonedStack)
|
if(!clonedStack)
|
||||||
{
|
{
|
||||||
env->complain ("No target stack to clone!");
|
env->complain("No target stack to clone!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,18 +448,19 @@ ObstacleMechanics::ObstacleMechanics(const CSpell * s):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const
|
||||||
{
|
{
|
||||||
const auto side = cb->playerToSide(ctx.caster->getOwner());
|
const auto side = cb->playerToSide(caster->getOwner());
|
||||||
|
const auto level = caster->getSpellSchoolLevel(owner);
|
||||||
if(!side)
|
if(!side)
|
||||||
return ESpellCastProblem::INVALID;
|
return ESpellCastProblem::INVALID;
|
||||||
|
|
||||||
bool hexesOutsideBattlefield = false;
|
bool hexesOutsideBattlefield = false;
|
||||||
|
|
||||||
auto tilesThatMustBeClear = owner->rangeInHexes(ctx.destination, ctx.schoolLvl, side.get(), &hexesOutsideBattlefield);
|
auto tilesThatMustBeClear = owner->rangeInHexes(destination, level, side.get(), &hexesOutsideBattlefield);
|
||||||
|
const CSpell::TargetInfo ti(owner, level, mode);
|
||||||
for(const BattleHex & hex : tilesThatMustBeClear)
|
for(const BattleHex & hex : tilesThatMustBeClear)
|
||||||
if(!isHexAviable(cb, hex, ctx.ti.clearAffected))
|
if(!isHexAviable(cb, hex, ti.clearAffected))
|
||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
|
|
||||||
if(hexesOutsideBattlefield)
|
if(hexesOutsideBattlefield)
|
||||||
@ -757,14 +749,16 @@ ESpellCastProblem::ESpellCastProblem RemoveObstacleMechanics::canBeCast(const CB
|
|||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem RemoveObstacleMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem RemoveObstacleMechanics::canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const
|
||||||
{
|
{
|
||||||
auto obstacles = cb->battleGetAllObstaclesOnPos(ctx.destination, false);
|
const auto level = caster->getSpellSchoolLevel(owner);
|
||||||
|
auto obstacles = cb->battleGetAllObstaclesOnPos(destination, false);
|
||||||
if(!obstacles.empty())
|
if(!obstacles.empty())
|
||||||
|
{
|
||||||
for(auto & i : obstacles)
|
for(auto & i : obstacles)
|
||||||
if(canRemove(i.get(), ctx.schoolLvl))
|
if(canRemove(i.get(), level))
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
|
}
|
||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,12 +908,14 @@ SpecialRisingSpellMechanics::SpecialRisingSpellMechanics(const CSpell * s):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const
|
||||||
{
|
{
|
||||||
auto mainFilter = [cb, ctx, this](const CStack * s) -> bool
|
const auto level = caster->getSpellSchoolLevel(owner);
|
||||||
|
const CSpell::TargetInfo ti(owner, level, mode);
|
||||||
|
auto mainFilter = [cb, ti, caster, destination, this](const CStack * s) -> bool
|
||||||
{
|
{
|
||||||
const bool ownerMatches = !ctx.ti.smart || cb->battleMatchOwner(ctx.caster->getOwner(), s, owner->getPositiveness());
|
const bool ownerMatches = !ti.smart || cb->battleMatchOwner(caster->getOwner(), s, owner->getPositiveness());
|
||||||
return ownerMatches && s->coversPos(ctx.destination) && ESpellCastProblem::OK == owner->isImmuneByStack(ctx.caster, s);
|
return ownerMatches && s->coversPos(destination) && ESpellCastProblem::OK == owner->isImmuneByStack(caster, s);
|
||||||
};
|
};
|
||||||
//find alive possible target
|
//find alive possible target
|
||||||
const CStack * stackToHeal = cb->getStackIf([mainFilter](const CStack * s)
|
const CStack * stackToHeal = cb->getStackIf([mainFilter](const CStack * s)
|
||||||
|
@ -38,7 +38,7 @@ class DLL_LINKAGE ChainLightningMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
ChainLightningMechanics(const CSpell * s);
|
ChainLightningMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CloneMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE CloneMechanics : public DefaultSpellMechanics
|
||||||
@ -93,7 +93,7 @@ class DLL_LINKAGE ObstacleMechanics : public SpecialSpellMechanics
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ObstacleMechanics(const CSpell * s);
|
ObstacleMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const override;
|
||||||
protected:
|
protected:
|
||||||
static bool isHexAviable(const CBattleInfoCallback * cb, const BattleHex & hex, const bool mustBeClear);
|
static bool isHexAviable(const CBattleInfoCallback * cb, const BattleHex & hex, const bool mustBeClear);
|
||||||
void placeObstacle(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, const BattleHex & pos) const;
|
void placeObstacle(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, const BattleHex & pos) const;
|
||||||
@ -159,7 +159,7 @@ class DLL_LINKAGE RemoveObstacleMechanics : public SpecialSpellMechanics
|
|||||||
public:
|
public:
|
||||||
RemoveObstacleMechanics(const CSpell * s);
|
RemoveObstacleMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
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;
|
ESpellCastProblem::ESpellCastProblem canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const override;
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
@ -192,8 +192,8 @@ class DLL_LINKAGE SpecialRisingSpellMechanics : public RisingSpellMechanics
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpecialRisingSpellMechanics(const CSpell * s);
|
SpecialRisingSpellMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
ESpellCastProblem::ESpellCastProblem canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE SummonMechanics : public SpecialSpellMechanics
|
class DLL_LINKAGE SummonMechanics : public SpecialSpellMechanics
|
||||||
|
@ -630,36 +630,45 @@ std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CStack *> DefaultSpellMechanics::getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
std::vector<const CStack *> DefaultSpellMechanics::getAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const
|
||||||
{
|
{
|
||||||
std::vector<const CStack *> attackedCres = calculateAffectedStacks(cb, ctx);
|
std::vector<const CStack *> result = calculateAffectedStacks(cb, mode, caster, spellLvl, destination);
|
||||||
handleImmunities(cb, ctx, attackedCres);
|
CSpell::TargetInfo ti(owner, spellLvl, mode);
|
||||||
return attackedCres;
|
|
||||||
|
auto predicate = [&, this](const CStack * s)->bool
|
||||||
|
{
|
||||||
|
const bool hitDirectly = ti.alwaysHitDirectly && s->coversPos(destination);
|
||||||
|
const bool immune = (ESpellCastProblem::OK != owner->isImmuneByStack(caster, s));
|
||||||
|
return !hitDirectly && immune;
|
||||||
|
};
|
||||||
|
vstd::erase_if(result, predicate);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CStack *> DefaultSpellMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
std::vector<const CStack *> DefaultSpellMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const
|
||||||
{
|
{
|
||||||
std::set<const CStack *> attackedCres;//std::set to exclude multiple occurrences of two hex creatures
|
std::set<const CStack *> attackedCres;//std::set to exclude multiple occurrences of two hex creatures
|
||||||
|
CSpell::TargetInfo ti(owner, spellLvl, mode);
|
||||||
|
|
||||||
const auto side = cb->playerToSide(ctx.caster->getOwner());
|
const auto side = cb->playerToSide(caster->getOwner());
|
||||||
if(!side)
|
if(!side)
|
||||||
return std::vector<const CStack *>();
|
return std::vector<const CStack *>();
|
||||||
auto attackedHexes = rangeInHexes(ctx.destination, ctx.schoolLvl, side.get());
|
auto attackedHexes = rangeInHexes(destination, spellLvl, side.get());
|
||||||
|
|
||||||
//hackfix for banned creature massive spells
|
//hackfix for banned creature massive spells
|
||||||
if(!ctx.ti.massive && owner->getLevelInfo(ctx.schoolLvl).range == "X")
|
if(!ti.massive && owner->getLevelInfo(spellLvl).range == "X")
|
||||||
attackedHexes.push_back(ctx.destination);
|
attackedHexes.push_back(destination);
|
||||||
|
|
||||||
auto mainFilter = [=](const CStack * s)
|
auto mainFilter = [&](const CStack * s)
|
||||||
{
|
{
|
||||||
const bool ownerMatches = cb->battleMatchOwner(ctx.caster->getOwner(), s, owner->getPositiveness());
|
const bool ownerMatches = cb->battleMatchOwner(caster->getOwner(), s, owner->getPositiveness());
|
||||||
const bool validTarget = s->isValidTarget(!ctx.ti.onlyAlive); //todo: this should be handled by spell class
|
const bool validTarget = s->isValidTarget(!ti.onlyAlive); //todo: this should be handled by spell class
|
||||||
const bool positivenessFlag = !ctx.ti.smart || ownerMatches;
|
const bool positivenessFlag = !ti.smart || ownerMatches;
|
||||||
|
|
||||||
return positivenessFlag && validTarget;
|
return positivenessFlag && validTarget;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(ctx.ti.type == CSpell::CREATURE && attackedHexes.size() == 1)
|
if(ti.type == CSpell::CREATURE && attackedHexes.size() == 1)
|
||||||
{
|
{
|
||||||
//for single target spells we must select one target. Alive stack is preferred (issue #1763)
|
//for single target spells we must select one target. Alive stack is preferred (issue #1763)
|
||||||
|
|
||||||
@ -680,11 +689,9 @@ std::vector<const CStack *> DefaultSpellMechanics::calculateAffectedStacks(const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(attackedCres.empty() && !stacks.empty())
|
if(attackedCres.empty() && !stacks.empty())
|
||||||
{
|
|
||||||
attackedCres.insert(stacks.front());
|
attackedCres.insert(stacks.front());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(ctx.ti.massive)
|
else if(ti.massive)
|
||||||
{
|
{
|
||||||
TStacks stacks = cb->battleGetStacksIf(mainFilter);
|
TStacks stacks = cb->battleGetStacksIf(mainFilter);
|
||||||
for(auto stack : stacks)
|
for(auto stack : stacks)
|
||||||
@ -694,7 +701,7 @@ std::vector<const CStack *> DefaultSpellMechanics::calculateAffectedStacks(const
|
|||||||
{
|
{
|
||||||
for(BattleHex hex : attackedHexes)
|
for(BattleHex hex : attackedHexes)
|
||||||
{
|
{
|
||||||
if(const CStack * st = cb->battleGetStackByPos(hex, ctx.ti.onlyAlive))
|
if(const CStack * st = cb->battleGetStackByPos(hex, ti.onlyAlive))
|
||||||
if(mainFilter(st))
|
if(mainFilter(st))
|
||||||
attackedCres.insert(st);
|
attackedCres.insert(st);
|
||||||
}
|
}
|
||||||
@ -712,18 +719,19 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBat
|
|||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const
|
||||||
{
|
{
|
||||||
if(ctx.mode == ECastingMode::CREATURE_ACTIVE_CASTING || ctx.mode == ECastingMode::HERO_CASTING)
|
if(mode == ECastingMode::CREATURE_ACTIVE_CASTING || mode == ECastingMode::HERO_CASTING)
|
||||||
{
|
{
|
||||||
std::vector<const CStack *> affected = getAffectedStacks(cb, ctx);
|
const auto level = caster->getSpellSchoolLevel(owner);
|
||||||
|
std::vector<const CStack *> affected = getAffectedStacks(cb, mode, caster, level, destination);
|
||||||
|
|
||||||
//allow to cast spell if it affects at least one smart target
|
//allow to cast spell if it affects at least one smart target
|
||||||
bool targetExists = false;
|
bool targetExists = false;
|
||||||
|
|
||||||
for(const CStack * stack : affected)
|
for(const CStack * stack : affected)
|
||||||
{
|
{
|
||||||
targetExists = cb->battleMatchOwner(ctx.caster->getOwner(), stack, owner->getPositiveness());
|
targetExists = cb->battleMatchOwner(caster->getOwner(), stack, owner->getPositiveness());
|
||||||
if(targetExists)
|
if(targetExists)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -778,18 +786,6 @@ bool DefaultSpellMechanics::canDispell(const IBonusBearer * obj, const CSelector
|
|||||||
return obj->hasBonus(selector.And(dispellSelector), Selector::all, cachingStr);
|
return obj->hasBonus(selector.And(dispellSelector), Selector::all, cachingStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultSpellMechanics::handleImmunities(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx, std::vector<const CStack*> & stacks) const
|
|
||||||
{
|
|
||||||
auto predicate = [&, this](const CStack * s)->bool
|
|
||||||
{
|
|
||||||
bool hitDirectly = ctx.ti.alwaysHitDirectly && s->coversPos(ctx.destination);
|
|
||||||
bool notImmune = (ESpellCastProblem::OK == owner->isImmuneByStack(ctx.caster, s));
|
|
||||||
|
|
||||||
return !(hitDirectly || notImmune);
|
|
||||||
};
|
|
||||||
vstd::erase_if(stacks, predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultSpellMechanics::handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const
|
void DefaultSpellMechanics::handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const
|
||||||
{
|
{
|
||||||
//reflection is applied only to negative spells
|
//reflection is applied only to negative spells
|
||||||
@ -865,14 +861,14 @@ SpecialSpellMechanics::SpecialSpellMechanics(const CSpell * s):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem SpecialSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem SpecialSpellMechanics::canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const
|
||||||
{
|
{
|
||||||
//no problems by default
|
//no problems by default
|
||||||
//common problems handled by CSpell
|
//common problems handled by CSpell
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CStack *> SpecialSpellMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
std::vector<const CStack *> SpecialSpellMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const
|
||||||
{
|
{
|
||||||
return std::vector<const CStack *>();
|
return std::vector<const CStack *>();
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,10 @@ public:
|
|||||||
DefaultSpellMechanics(const CSpell * s);
|
DefaultSpellMechanics(const CSpell * s);
|
||||||
|
|
||||||
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override;
|
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override;
|
||||||
std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override final;
|
std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) 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 ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const override;
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
virtual void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
||||||
|
|
||||||
virtual std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const;
|
virtual std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
||||||
@ -81,7 +81,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;
|
void cast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, std::vector <const CStack*> & reflected) const;
|
||||||
|
|
||||||
void handleImmunities(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx, std::vector<const CStack *> & stacks) const;
|
|
||||||
void handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const;
|
void handleMagicMirror(const SpellCastEnvironment * env, SpellCastContext & ctx, std::vector <const CStack*> & reflected) const;
|
||||||
void handleResistance(const SpellCastEnvironment * env, SpellCastContext & ctx) const;
|
void handleResistance(const SpellCastEnvironment * env, SpellCastContext & ctx) const;
|
||||||
|
|
||||||
@ -96,7 +95,7 @@ class DLL_LINKAGE SpecialSpellMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
SpecialSpellMechanics(const CSpell * s);
|
SpecialSpellMechanics(const CSpell * s);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const override;
|
||||||
protected:
|
protected:
|
||||||
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const override;
|
||||||
};
|
};
|
||||||
|
@ -243,8 +243,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
|
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, mode, caster, spellLvl, destination);
|
||||||
return mechanics->getAffectedStacks(cb, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSpell::ETargetType CSpell::getTargetType() const
|
CSpell::ETargetType CSpell::getTargetType() const
|
||||||
@ -405,9 +404,7 @@ ESpellCastProblem::ESpellCastProblem CSpell::canBeCastAt(const CBattleInfoCallba
|
|||||||
if(problem != ESpellCastProblem::OK)
|
if(problem != ESpellCastProblem::OK)
|
||||||
return problem;
|
return problem;
|
||||||
|
|
||||||
SpellTargetingContext ctx(this, mode, caster, caster->getSpellSchoolLevel(this), destination);
|
return mechanics->canBeCastAt(cb, mode, caster, destination);
|
||||||
|
|
||||||
return mechanics->canBeCast(cb, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSpell::adjustRawDamage(const ISpellCaster * caster, const CStack * affectedCreature, int rawDamage) const
|
int CSpell::adjustRawDamage(const ISpellCaster * caster, const CStack * affectedCreature, int rawDamage) const
|
||||||
|
@ -93,19 +93,6 @@ private:
|
|||||||
int effectValue;
|
int effectValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_LINKAGE SpellTargetingContext
|
|
||||||
{
|
|
||||||
CSpell::TargetInfo ti;
|
|
||||||
ECastingMode::ECastingMode mode;
|
|
||||||
BattleHex destination;
|
|
||||||
const ISpellCaster * caster;
|
|
||||||
int schoolLvl;
|
|
||||||
|
|
||||||
SpellTargetingContext(const CSpell * s, ECastingMode::ECastingMode mode_, const ISpellCaster * caster_, int schoolLvl_, BattleHex destination_)
|
|
||||||
: ti(s,schoolLvl_, mode_), mode(mode_), destination(destination_), caster(caster_), schoolLvl(schoolLvl_)
|
|
||||||
{};
|
|
||||||
};
|
|
||||||
|
|
||||||
class DLL_LINKAGE ISpellMechanics
|
class DLL_LINKAGE ISpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -113,11 +100,11 @@ public:
|
|||||||
virtual ~ISpellMechanics(){};
|
virtual ~ISpellMechanics(){};
|
||||||
|
|
||||||
virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
|
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, const SpellTargetingContext & ctx) const = 0;
|
virtual std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const = 0;
|
||||||
|
|
||||||
virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const = 0;
|
virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const = 0;
|
||||||
|
|
||||||
virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const = 0;
|
virtual ESpellCastProblem::ESpellCastProblem canBeCastAt(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster, BattleHex destination) const = 0;
|
||||||
|
|
||||||
virtual ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const = 0;
|
virtual ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const = 0;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user