1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Implemented spell countering.

This commit is contained in:
Michał W. Urbańczyk 2012-09-13 23:41:03 +00:00
parent 96a92d0f45
commit 74f9c19a7c
4 changed files with 40 additions and 27 deletions

View File

@ -49,20 +49,20 @@
{ "id": 38, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 39, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 40, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 41, "effect": 1, "anim": 36, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 42, "effect": -1, "anim": 40, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 43, "effect": 1, "anim": 4, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 41, "effect": 1, "anim": 36, "ranges": [ "0", "0", "0", "X" ], "counters" : [42] },
{ "id": 42, "effect": -1, "anim": 40, "ranges": [ "0", "0", "0", "X" ], "counters" : [41] },
{ "id": 43, "effect": 1, "anim": 4, "ranges": [ "0", "0", "0", "X" ], "counters" : [45] },
{ "id": 44, "effect": 1, "anim": 25, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 45, "effect": -1, "anim": 56, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 45, "effect": -1, "anim": 56, "ranges": [ "0", "0", "0", "X" ], "counters" : [43] },
{ "id": 46, "effect": 1, "anim": 54, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 47, "effect": -1, "anim": 14, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 48, "effect": 1, "anim": 0, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 49, "effect": 1, "anim": 20, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 50, "effect": -1, "anim": 30, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 51, "effect": 1, "anim": 18, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 52, "effect": -1, "anim": 48, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 53, "effect": 1, "anim": 31, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 54, "effect": -1, "anim": 19, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 49, "effect": 1, "anim": 20, "ranges": [ "0", "0", "0", "X" ], "counters" : [50] },
{ "id": 50, "effect": -1, "anim": 30, "ranges": [ "0", "0", "0", "X" ], "counters" : [49] },
{ "id": 51, "effect": 1, "anim": 18, "ranges": [ "0", "0", "0", "X" ], "counters" : [52] },
{ "id": 52, "effect": -1, "anim": 48, "ranges": [ "0", "0", "0", "X" ], "counters" : [51] },
{ "id": 53, "effect": 1, "anim": 31, "ranges": [ "0", "0", "0", "X" ], "counters" : [54] },
{ "id": 54, "effect": -1, "anim": 19, "ranges": [ "0", "0", "0", "X" ], "counters" : [53] },
{ "id": 55, "effect": 1, "anim": 28, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 56, "effect": 1, "anim": 17, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 57, "effect": -1, "anim": 38, "ranges": [ "0", "0", "0", "0" ] },

View File

@ -354,14 +354,17 @@ void CSpellHandler::loadSpells()
{
//reading exact info
int spellID = spell["id"].Float();
CSpell *s = spells[spellID];
spells[spellID]->positiveness = spell["effect"].Float();
spells[spellID]->mainEffectAnim = spell["anim"].Float();
s->positiveness = spell["effect"].Float();
s->mainEffectAnim = spell["anim"].Float();
spells[spellID]->range.resize(4);
s->range.resize(4);
int idx = 0;
BOOST_FOREACH(const JsonNode &range, spell["ranges"].Vector())
spells[spellID]->range[idx++] = range.String();
s->range[idx++] = range.String();
s->counteredSpells = spell["counters"].StdVector<TSpell>();
}
spells.push_back(spells[80]); //clone Acid Breath attributes for Acid Breath damage effect

View File

@ -41,6 +41,8 @@ public:
bool creatureAbility; //if true, only creatures can use this spell
si8 positiveness; //1 if spell is positive for influenced stacks, 0 if it is indifferent, -1 if it's negative
std::vector<std::string> range; //description of spell's range in SRSL by magic school level
std::vector<TSpell> counteredSpells; //spells that are removed when effect of this spell is placed on creature (for bless-curse, haste-slow, and similar pairs)
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = NULL ) const; //convert range to specific hexes; last optional out parameter is set to true, if spell would cover unavailable hexes (that are not included in ret)
si16 mainEffectAnim; //main spell effect animation, in AC format (or -1 when none)
ETargetType getTargetType() const;
@ -53,7 +55,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id & name & abbName & descriptions & level & earth & water & fire & air & power & costs
& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness & range & mainEffectAnim;
& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness & range & counteredSpells & mainEffectAnim;
}
};

View File

@ -1239,20 +1239,28 @@ DLL_LINKAGE void BattleSpellCast::applyGs( CGameState *gs )
}
}
if(id == 35 || id == 78) //dispel and dispel helpful spells
//Handle spells removing effects from stacks
const CSpell *spell = VLC->spellh->spells[id];
const bool removeAllSpells = id == Spells::DISPEL;
const bool removeHelpful = id == Spells::DISPEL_HELPFUL_SPELLS;
BOOST_FOREACH(auto stackID, affectedCres)
{
bool onlyHelpful = id == 78;
for(std::set<ui32>::const_iterator it = affectedCres.begin(); it != affectedCres.end(); ++it)
if(vstd::contains(resisted, stackID))
continue;
CStack *s = gs->curB->getStack(stackID);
s->popBonuses([&](const Bonus *b) -> bool
{
CStack *s = gs->curB->getStack(*it);
if(s && !vstd::contains(resisted, s->ID)) //if stack exists and it didn't resist
{
if(onlyHelpful)
s->popBonuses(Selector::positiveSpellEffects);
else
s->popBonuses(Selector::sourceType(Bonus::SPELL_EFFECT));
}
}
//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);
});
}
}