mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Merge branch 'dispellFixes' into develop
This commit is contained in:
@@ -2177,6 +2177,10 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
legalAction = true;
|
||||
}
|
||||
break;
|
||||
case ANY_CREATURE:
|
||||
if (shere && shere->alive() && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
legalAction = true;
|
||||
break;
|
||||
case HOSTILE_CREATURE_SPELL:
|
||||
if (shere && shere->alive() && !ourStack && isCastingPossibleHere (sactive, shere, myNumber))
|
||||
legalAction = true;
|
||||
@@ -2372,6 +2376,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
break;
|
||||
case HOSTILE_CREATURE_SPELL:
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
case ANY_CREATURE:
|
||||
sp = CGI->spellh->objects[creatureCasting ? creatureSpellToCast : spellToCast->additionalInfo]; //necessary if creature has random Genie spell at same time
|
||||
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % sp->name % shere->getName()); //Cast %s on %s
|
||||
switch (sp->id)
|
||||
@@ -2442,6 +2447,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
{
|
||||
switch (illegalAction)
|
||||
{
|
||||
case ANY_CREATURE:
|
||||
case HOSTILE_CREATURE_SPELL:
|
||||
case FRIENDLY_CREATURE_SPELL:
|
||||
case RANDOM_GENIE_SPELL:
|
||||
|
@@ -106,15 +106,20 @@
|
||||
"cast": "DISPELL"
|
||||
},
|
||||
"levels" : {
|
||||
"base":{
|
||||
"range" : "0"
|
||||
"base":{
|
||||
"targetModifier":{"smart":true},
|
||||
"range" : "0"
|
||||
},
|
||||
"advanced":{
|
||||
"targetModifier":{"smart":false}
|
||||
},
|
||||
"expert":{
|
||||
"range" : "X"
|
||||
}
|
||||
"expert":{
|
||||
"targetModifier":{"smart":false},
|
||||
"range" : "X"
|
||||
}
|
||||
},
|
||||
"flags" : {
|
||||
"indifferent": true
|
||||
"positive": true
|
||||
}
|
||||
},
|
||||
"cure" : {
|
||||
|
@@ -14,6 +14,31 @@
|
||||
#include "../NetPacks.h"
|
||||
#include "../BattleState.h"
|
||||
|
||||
///AntimagicMechanics
|
||||
void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||
{
|
||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||
|
||||
for(auto stackID : packet->affectedCres)
|
||||
{
|
||||
if(vstd::contains(packet->resisted, stackID))
|
||||
{
|
||||
logGlobal->errorStream() << "Resistance to positive spell " << owner->name;
|
||||
continue;
|
||||
}
|
||||
|
||||
CStack * s = battle->getStack(stackID);
|
||||
s->popBonuses([&](const Bonus *b) -> bool
|
||||
{
|
||||
if(b->source == Bonus::SPELL_EFFECT)
|
||||
{
|
||||
return b->sid != owner->id; //effect from this spell
|
||||
}
|
||||
return false; //not a spell effect
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
///ChainLightningMechanics
|
||||
std::set<const CStack *> ChainLightningMechanics::getAffectedStacks(SpellTargetingContext & ctx) const
|
||||
{
|
||||
@@ -142,7 +167,10 @@ void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast *
|
||||
for(auto stackID : packet->affectedCres)
|
||||
{
|
||||
if(vstd::contains(packet->resisted, stackID))
|
||||
{
|
||||
logGlobal->errorStream() << "Resistance to DISPELL";
|
||||
continue;
|
||||
}
|
||||
|
||||
CStack *s = battle->getStack(stackID);
|
||||
s->popBonuses([&](const Bonus *b) -> bool
|
||||
@@ -152,6 +180,42 @@ void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast *
|
||||
}
|
||||
}
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
|
||||
{
|
||||
//DISPELL ignores all immunities, so do not call default
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "source_" << Bonus::SPELL_EFFECT;
|
||||
|
||||
if(obj->hasBonus(Selector::sourceType(Bonus::SPELL_EFFECT), cachingStr.str()))
|
||||
{
|
||||
return ESpellCastProblem::OK;
|
||||
}
|
||||
|
||||
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
||||
}
|
||||
|
||||
void DispellMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||
{
|
||||
DefaultSpellMechanics::applyBattleEffects(env, parameters, ctx);
|
||||
|
||||
if(parameters.spellLvl > 2)
|
||||
{
|
||||
//expert DISPELL also removes spell-created obstacles
|
||||
ObstaclesRemoved packet;
|
||||
|
||||
for(const auto obstacle : parameters.cb->obstacles)
|
||||
{
|
||||
if(obstacle->obstacleType == CObstacleInstance::FIRE_WALL
|
||||
|| obstacle->obstacleType == CObstacleInstance::FORCE_FIELD
|
||||
|| obstacle->obstacleType == CObstacleInstance::LAND_MINE)
|
||||
packet.obstacles.insert(obstacle->uniqueID);
|
||||
}
|
||||
|
||||
if(!packet.obstacles.empty())
|
||||
env->sendAndApply(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
///EarthquakeMechanics
|
||||
void EarthquakeMechanics::applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||
{
|
||||
@@ -421,7 +485,7 @@ void RemoveObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * en
|
||||
ESpellCastProblem::ESpellCastProblem SacrificeMechanics::canBeCasted(const CBattleInfoCallback * cb, PlayerColor player) const
|
||||
{
|
||||
// for sacrifice we have to check for 2 targets (one dead to resurrect and one living to destroy)
|
||||
|
||||
|
||||
bool targetExists = false;
|
||||
bool targetToSacrificeExists = false;
|
||||
|
||||
@@ -442,9 +506,9 @@ ESpellCastProblem::ESpellCastProblem SacrificeMechanics::canBeCasted(const CBatt
|
||||
if(targetExists && targetToSacrificeExists)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(targetExists && targetToSacrificeExists)
|
||||
return ESpellCastProblem::OK;
|
||||
else
|
||||
|
@@ -12,6 +12,14 @@
|
||||
|
||||
#include "CDefaultSpellMechanics.h"
|
||||
|
||||
class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
AntimagicMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||
|
||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE ChainLightningMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
@@ -40,17 +48,20 @@ class DLL_LINKAGE DispellMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
DispellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
|
||||
|
||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||
protected:
|
||||
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE EarthquakeMechanics : public DefaultSpellMechanics
|
||||
{
|
||||
public:
|
||||
EarthquakeMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||
ESpellCastProblem::ESpellCastProblem canBeCasted(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
||||
ESpellCastProblem::ESpellCastProblem canBeCasted(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
||||
protected:
|
||||
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE HypnotizeMechanics : public DefaultSpellMechanics
|
||||
@@ -115,7 +126,7 @@ class DLL_LINKAGE SummonMechanics : public DefaultSpellMechanics
|
||||
public:
|
||||
SummonMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem canBeCasted(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
||||
ESpellCastProblem::ESpellCastProblem canBeCasted(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
||||
protected:
|
||||
void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||
};
|
||||
|
@@ -216,7 +216,6 @@ bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * e
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
||||
{
|
||||
BattleSpellCast sc;
|
||||
|
@@ -28,6 +28,8 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
|
||||
{
|
||||
switch (s->id)
|
||||
{
|
||||
case SpellID::ANTI_MAGIC:
|
||||
return new AntimagicMechanics(s);
|
||||
case SpellID::ACID_BREATH_DAMAGE:
|
||||
return new AcidBreathDamageMechanics(s);
|
||||
case SpellID::CHAIN_LIGHTNING:
|
||||
|
Reference in New Issue
Block a user