mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-29 21:56:54 +02:00
Centralize dispell mechanics
This commit is contained in:
parent
756c19227b
commit
fe1233310f
@ -101,6 +101,12 @@ CSpell::~CSpell()
|
|||||||
delete mechanics;
|
delete mechanics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSpell::afterCast(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
|
{
|
||||||
|
mechanics->afterCast(battle, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSpell::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
void CSpell::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
assert(env);
|
assert(env);
|
||||||
|
@ -31,6 +31,7 @@ class BattleInfo;
|
|||||||
|
|
||||||
struct CPackForClient;
|
struct CPackForClient;
|
||||||
struct BattleSpellCast;
|
struct BattleSpellCast;
|
||||||
|
|
||||||
class CRandomGenerator;
|
class CRandomGenerator;
|
||||||
|
|
||||||
struct SpellSchoolInfo
|
struct SpellSchoolInfo
|
||||||
@ -256,6 +257,10 @@ public:
|
|||||||
}
|
}
|
||||||
friend class CSpellHandler;
|
friend class CSpellHandler;
|
||||||
friend class Graphics;
|
friend class Graphics;
|
||||||
|
public:
|
||||||
|
///Client-Server events. Shall be called only when applying packets
|
||||||
|
void afterCast(BattleInfo * battle, const BattleSpellCast * packet) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setIsOffensive(const bool val);
|
void setIsOffensive(const bool val);
|
||||||
void setIsRising(const bool val);
|
void setIsRising(const bool val);
|
||||||
@ -323,10 +328,7 @@ public:
|
|||||||
{
|
{
|
||||||
h & objects ;
|
h & objects ;
|
||||||
}
|
}
|
||||||
public:
|
|
||||||
///Client-Server events. Shall be called only when applying packets
|
|
||||||
//void afterSpellCast(BattleInfo * battle, BattleSpellCast * packet) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CSpell * loadFromJson(const JsonNode & json) override;
|
CSpell * loadFromJson(const JsonNode & json) override;
|
||||||
};
|
};
|
||||||
|
@ -1343,29 +1343,9 @@ DLL_LINKAGE void BattleSpellCast::applyGs( CGameState *gs )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle spells removing effects from stacks
|
const CSpell * spell = SpellID(id).toSpell();
|
||||||
const CSpell *spell = SpellID(id).toSpell();
|
|
||||||
const bool removeAllSpells = id == SpellID::DISPEL;
|
spell->afterCast(gs->curB, this);
|
||||||
const bool removeHelpful = id == SpellID::DISPEL_HELPFUL_SPELLS;
|
|
||||||
|
|
||||||
for(auto stackID : affectedCres)
|
|
||||||
{
|
|
||||||
if(vstd::contains(resisted, stackID))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CStack *s = gs->curB->getStack(stackID);
|
|
||||||
s->popBonuses([&](const Bonus *b) -> bool
|
|
||||||
{
|
|
||||||
//check for each bonus if it should be removed
|
|
||||||
const bool isSpellEffect = Selector::sourceType(Bonus::SPELL_EFFECT)(b);
|
|
||||||
const bool isPositiveSpell = Selector::positiveSpellEffects(b);
|
|
||||||
const int spellID = isSpellEffect ? b->sid : -1;
|
|
||||||
|
|
||||||
return (removeHelpful && isPositiveSpell)
|
|
||||||
|| (removeAllSpells && isSpellEffect)
|
|
||||||
|| vstd::contains(spell->counteredSpells, spellID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void actualizeEffect(CStack * s, const std::vector<Bonus> & ef)
|
void actualizeEffect(CStack * s, const std::vector<Bonus> & ef)
|
||||||
|
@ -141,6 +141,8 @@ public:
|
|||||||
|
|
||||||
//bool adventureCast(const SpellCastContext & context) const override;
|
//bool adventureCast(const SpellCastContext & context) const override;
|
||||||
void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const override;
|
void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const override;
|
||||||
|
|
||||||
|
void afterCast(BattleInfo * battle, const BattleSpellCast * packet) const override;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
virtual void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
||||||
@ -173,6 +175,14 @@ protected:
|
|||||||
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CureMechanics: public DefaultSpellMechanics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CureMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
|
|
||||||
|
void afterCast(BattleInfo * battle, const BattleSpellCast * packet) const override;
|
||||||
|
};
|
||||||
|
|
||||||
class DeathStareMechnics: public DefaultSpellMechanics
|
class DeathStareMechnics: public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -185,9 +195,20 @@ class DispellHelpfulMechanics: public DefaultSpellMechanics
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DispellHelpfulMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
DispellHelpfulMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
|
|
||||||
|
void afterCast(BattleInfo * battle, const BattleSpellCast * packet) const override;
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DispellMechanics: public DefaultSpellMechanics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DispellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
|
|
||||||
|
void afterCast(BattleInfo * battle, const BattleSpellCast * packet) const override;
|
||||||
|
};
|
||||||
|
|
||||||
class HypnotizeMechanics: public DefaultSpellMechanics
|
class HypnotizeMechanics: public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -270,33 +291,39 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
|
|||||||
{
|
{
|
||||||
switch (s->id)
|
switch (s->id)
|
||||||
{
|
{
|
||||||
case SpellID::CLONE:
|
case SpellID::ACID_BREATH_DAMAGE:
|
||||||
return new CloneMechanics(s);
|
return new AcidBreathDamageMechnics(s);
|
||||||
case SpellID::DISPEL_HELPFUL_SPELLS:
|
|
||||||
return new DispellHelpfulMechanics(s);
|
|
||||||
case SpellID::SACRIFICE:
|
|
||||||
return new SacrificeMechanics(s);
|
|
||||||
case SpellID::CHAIN_LIGHTNING:
|
case SpellID::CHAIN_LIGHTNING:
|
||||||
return new ChainLightningMechanics(s);
|
return new ChainLightningMechanics(s);
|
||||||
|
case SpellID::CLONE:
|
||||||
|
return new CloneMechanics(s);
|
||||||
|
case SpellID::CURE:
|
||||||
|
return new CureMechanics(s);
|
||||||
|
case SpellID::DEATH_STARE:
|
||||||
|
return new DeathStareMechnics(s);
|
||||||
|
case SpellID::DISPEL:
|
||||||
|
return new DispellMechanics(s);
|
||||||
|
case SpellID::DISPEL_HELPFUL_SPELLS:
|
||||||
|
return new DispellHelpfulMechanics(s);
|
||||||
case SpellID::FIRE_WALL:
|
case SpellID::FIRE_WALL:
|
||||||
case SpellID::FORCE_FIELD:
|
case SpellID::FORCE_FIELD:
|
||||||
return new WallMechanics(s);
|
return new WallMechanics(s);
|
||||||
|
case SpellID::HYPNOTIZE:
|
||||||
|
return new HypnotizeMechanics(s);
|
||||||
case SpellID::LAND_MINE:
|
case SpellID::LAND_MINE:
|
||||||
case SpellID::QUICKSAND:
|
case SpellID::QUICKSAND:
|
||||||
return new ObstacleMechanics(s);
|
return new ObstacleMechanics(s);
|
||||||
case SpellID::TELEPORT:
|
case SpellID::REMOVE_OBSTACLE:
|
||||||
return new TeleportMechanics(s);
|
return new RemoveObstacleMechanics(s);
|
||||||
|
case SpellID::SACRIFICE:
|
||||||
|
return new SacrificeMechanics(s);
|
||||||
case SpellID::SUMMON_FIRE_ELEMENTAL:
|
case SpellID::SUMMON_FIRE_ELEMENTAL:
|
||||||
case SpellID::SUMMON_EARTH_ELEMENTAL:
|
case SpellID::SUMMON_EARTH_ELEMENTAL:
|
||||||
case SpellID::SUMMON_WATER_ELEMENTAL:
|
case SpellID::SUMMON_WATER_ELEMENTAL:
|
||||||
case SpellID::SUMMON_AIR_ELEMENTAL:
|
case SpellID::SUMMON_AIR_ELEMENTAL:
|
||||||
return new SummonMechanics(s);
|
return new SummonMechanics(s);
|
||||||
case SpellID::REMOVE_OBSTACLE:
|
case SpellID::TELEPORT:
|
||||||
return new RemoveObstacleMechanics(s);
|
return new TeleportMechanics(s);
|
||||||
case SpellID::DEATH_STARE:
|
|
||||||
return new DeathStareMechnics(s);
|
|
||||||
case SpellID::ACID_BREATH_DAMAGE:
|
|
||||||
return new AcidBreathDamageMechnics(s);
|
|
||||||
default:
|
default:
|
||||||
if(s->isRisingSpell())
|
if(s->isRisingSpell())
|
||||||
return new SpecialRisingSpellMechanics(s);
|
return new SpecialRisingSpellMechanics(s);
|
||||||
@ -307,11 +334,28 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
|
|||||||
|
|
||||||
|
|
||||||
///DefaultSpellMechanics
|
///DefaultSpellMechanics
|
||||||
|
void DefaultSpellMechanics::afterCast(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
|
{
|
||||||
|
//TODO: may be move all from BattleSpellCast::applyGs here
|
||||||
|
|
||||||
|
//handle countering spells
|
||||||
|
for(auto stackID : packet->affectedCres)
|
||||||
|
{
|
||||||
|
if(vstd::contains(packet->resisted, stackID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CStack * s = battle->getStack(stackID);
|
||||||
|
s->popBonuses([&](const Bonus * b) -> bool
|
||||||
|
{
|
||||||
|
//check for each bonus if it should be removed
|
||||||
|
const bool isSpellEffect = Selector::sourceType(Bonus::SPELL_EFFECT)(b);
|
||||||
|
const int spellID = isSpellEffect ? b->sid : -1;
|
||||||
|
|
||||||
|
return isSpellEffect && vstd::contains(owner->counteredSpells, spellID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//bool DefaultSpellMechanics::adventureCast(const SpellCastContext& context) const
|
|
||||||
//{
|
|
||||||
// return false; //there is no general algorithm for casting adventure spells
|
|
||||||
//}
|
|
||||||
|
|
||||||
void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
@ -893,6 +937,33 @@ ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const CGHer
|
|||||||
return DefaultSpellMechanics::isImmuneByStack(caster, obj);
|
return DefaultSpellMechanics::isImmuneByStack(caster, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///CureMechanics
|
||||||
|
void CureMechanics::afterCast(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
|
{
|
||||||
|
DefaultSpellMechanics::afterCast(battle, packet);
|
||||||
|
|
||||||
|
for(auto stackID : packet->affectedCres)
|
||||||
|
{
|
||||||
|
if(vstd::contains(packet->resisted, stackID))
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Resistance to positive spell CURE";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CStack *s = battle->getStack(stackID);
|
||||||
|
s->popBonuses([&](const Bonus *b) -> bool
|
||||||
|
{
|
||||||
|
if(b->source == Bonus::SPELL_EFFECT)
|
||||||
|
{
|
||||||
|
CSpell * sp = SpellID(b->sid).toSpell();
|
||||||
|
return sp->isNegative();
|
||||||
|
}
|
||||||
|
return false; //not a spell effect
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///DeathStareMechnics
|
///DeathStareMechnics
|
||||||
void DeathStareMechnics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void DeathStareMechnics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
@ -915,6 +986,24 @@ void DeathStareMechnics::applyBattleEffects(const SpellCastEnvironment * env, Ba
|
|||||||
|
|
||||||
|
|
||||||
///DispellHelpfulMechanics
|
///DispellHelpfulMechanics
|
||||||
|
void DispellHelpfulMechanics::afterCast(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
|
{
|
||||||
|
DefaultSpellMechanics::afterCast(battle, packet);
|
||||||
|
|
||||||
|
for(auto stackID : packet->affectedCres)
|
||||||
|
{
|
||||||
|
if(vstd::contains(packet->resisted, stackID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CStack *s = battle->getStack(stackID);
|
||||||
|
s->popBonuses([&](const Bonus *b) -> bool
|
||||||
|
{
|
||||||
|
return Selector::positiveSpellEffects(b);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
TBonusListPtr spellBon = obj->getSpellBonuses();
|
TBonusListPtr spellBon = obj->getSpellBonuses();
|
||||||
@ -936,6 +1025,25 @@ ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(co
|
|||||||
return DefaultSpellMechanics::isImmuneByStack(caster,obj);
|
return DefaultSpellMechanics::isImmuneByStack(caster,obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///DispellMechanics
|
||||||
|
void DispellMechanics::afterCast(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
|
{
|
||||||
|
DefaultSpellMechanics::afterCast(battle, packet);
|
||||||
|
|
||||||
|
for(auto stackID : packet->affectedCres)
|
||||||
|
{
|
||||||
|
if(vstd::contains(packet->resisted, stackID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CStack *s = battle->getStack(stackID);
|
||||||
|
s->popBonuses([&](const Bonus *b) -> bool
|
||||||
|
{
|
||||||
|
return Selector::sourceType(Bonus::SPELL_EFFECT)(b);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///HypnotizeMechanics
|
///HypnotizeMechanics
|
||||||
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,8 @@ public:
|
|||||||
|
|
||||||
static ISpellMechanics * createMechanics(CSpell * s);
|
static ISpellMechanics * createMechanics(CSpell * s);
|
||||||
|
|
||||||
|
virtual void afterCast(BattleInfo * battle, const BattleSpellCast * packet) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CSpell * owner;
|
CSpell * owner;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user