mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* support for spell resistance, including secondary skill (resistance) and new artifacts (Garniture of Interference, Surcoat of Counterpoise, Boots of Polarity) and unit's resistance (such as dwarfs' resistance)
This commit is contained in:
parent
0d408bc6c2
commit
27dda485a4
@ -1870,6 +1870,13 @@ void CBattleInterface::spellCast(SpellCast * sc)
|
||||
case 35: //dispel
|
||||
displayEffect(spell.mainEffectAnim, sc->tile);
|
||||
} //switch(sc->id)
|
||||
|
||||
//support for resistance
|
||||
for(int j=0; j<sc->resisted.size(); ++j)
|
||||
{
|
||||
int tile = LOCPLINT->cb->battleGetStackByID(sc->resisted[j])->position;
|
||||
displayEffect(78, tile);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
|
||||
|
@ -519,6 +519,9 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
||||
|
||||
ui32 CStack::Speed() const
|
||||
{
|
||||
if(hasFeatureOfType(StackFeature::SIEGE_WEAPON)) //war machnes cannot move
|
||||
return 0;
|
||||
|
||||
int speed = creature->speed;
|
||||
|
||||
speed += valOfFeatures(StackFeature::SPEED_BONUS);
|
||||
|
@ -886,9 +886,10 @@ struct SpellCast : public CPackForClient//3009
|
||||
ui32 id;
|
||||
ui8 skill;
|
||||
ui16 tile; //destination tile (may not be set in some global/mass spells
|
||||
std::vector<ui32> resisted; //ids of creatures that resisted this spell
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & side & id & skill & tile;
|
||||
h & side & id & skill & tile & resisted;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -692,10 +692,11 @@ DLL_EXPORT void SpellCast::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->curB->castSpells[side]++;
|
||||
}
|
||||
|
||||
if(gs->curB && id == 35) //dispel
|
||||
{
|
||||
CStack *s = gs->curB->getStackT(tile);
|
||||
if(s)
|
||||
if(s && !vstd::contains(resisted, s->ID)) //if stack exists and it didn't resist
|
||||
{
|
||||
s->effects.clear(); //removing all effects
|
||||
//removing all features from spells
|
||||
|
@ -2604,6 +2604,41 @@ static ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const std::set<CStack*> affectedCreatures)
|
||||
{
|
||||
std::vector<ui32> ret;
|
||||
for(std::set<CStack*>::const_iterator it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
|
||||
{
|
||||
//non-negative spells on friendly stacks should always succeed
|
||||
if(sp->positiveness >= 0 && (*it)->owner == caster->tempOwner)
|
||||
continue;
|
||||
|
||||
int prob = (*it)->valOfFeatures(StackFeature::MAGIC_RESISTANCE); //probability of resistance in %
|
||||
//caster's resistance support (secondary skils and artifacts)
|
||||
prob += caster->valOfBonuses(HeroBonus::MAGIC_RESISTANCE);
|
||||
|
||||
switch(caster->getSecSkillLevel(26)) //resistance
|
||||
{
|
||||
case 1: //basic
|
||||
prob += 5;
|
||||
break;
|
||||
case 2: //advanced
|
||||
prob += 10;
|
||||
break;
|
||||
case 3: //expert
|
||||
prob += 20;
|
||||
break;
|
||||
}
|
||||
|
||||
if(prob > 100) prob = 100;
|
||||
|
||||
if(rand()%100 < prob)
|
||||
ret.push_back((*it)->ID);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
{
|
||||
switch(ba.actionType)
|
||||
@ -2640,18 +2675,20 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
|
||||
sendAndApply(&StartAction(ba)); //start spell casting
|
||||
|
||||
//TODO: check resistances
|
||||
|
||||
SpellCast sc;
|
||||
sc.side = ba.side;
|
||||
sc.id = ba.additionalInfo;
|
||||
sc.skill = skill;
|
||||
sc.tile = ba.destinationTile;
|
||||
sendAndApply(&sc);
|
||||
|
||||
//calculating affected creatures for all spells
|
||||
std::set<CStack*> attackedCres = gs->curB->getAttackedCreatures(s, h, ba.destinationTile);
|
||||
|
||||
//checking if creatures resist
|
||||
sc.resisted = calculateResistedStacks(s, h, attackedCres);
|
||||
|
||||
sendAndApply(&sc);
|
||||
|
||||
//applying effects
|
||||
switch(ba.additionalInfo) //spell id
|
||||
{
|
||||
@ -2670,6 +2707,9 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
StacksInjured si;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
if(vstd::contains(sc.resisted, (*it)->ID)) //this creature resisted the spell
|
||||
continue;
|
||||
|
||||
BattleStackAttacked bsa;
|
||||
bsa.flags |= 2;
|
||||
bsa.effect = VLC->spellh->spells[ba.additionalInfo].mainEffectAnim;
|
||||
@ -2678,7 +2718,8 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
prepareAttacked(bsa,*it);
|
||||
si.stacks.insert(bsa);
|
||||
}
|
||||
sendAndApply(&si);
|
||||
if(!si.stacks.empty())
|
||||
sendAndApply(&si);
|
||||
break;
|
||||
}
|
||||
case 27: //shield
|
||||
@ -2707,12 +2748,15 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
SetStackEffect sse;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
if(vstd::contains(sc.resisted, (*it)->ID)) //this creature resisted the spell
|
||||
continue;
|
||||
sse.stacks.insert((*it)->ID);
|
||||
}
|
||||
sse.effect.id = ba.additionalInfo;
|
||||
sse.effect.level = h->getSpellSchoolLevel(s);
|
||||
sse.effect.turnsRemain = h->getPrimSkillLevel(2) + h->valOfBonuses(HeroBonus::SPELL_DURATION);
|
||||
sendAndApply(&sse);
|
||||
if(!sse.stacks.empty())
|
||||
sendAndApply(&sse);
|
||||
break;
|
||||
}
|
||||
case 56: //frenzy
|
||||
@ -2720,12 +2764,15 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
SetStackEffect sse;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
if(vstd::contains(sc.resisted, (*it)->ID)) //this creature resisted the spell
|
||||
continue;
|
||||
sse.stacks.insert((*it)->ID);
|
||||
}
|
||||
sse.effect.id = ba.additionalInfo;
|
||||
sse.effect.level = h->getSpellSchoolLevel(s);
|
||||
sse.effect.turnsRemain = 1;
|
||||
sendAndApply(&sse);
|
||||
if(!sse.stacks.empty())
|
||||
sendAndApply(&sse);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user