mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
* new spell (disrupting ray)
* a few code cleanups
This commit is contained in:
parent
c8b6858716
commit
35f63bdc5f
@ -273,6 +273,7 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
|
||||
spellToEffect[43] = 4; //bloodlust
|
||||
spellToEffect[45] = 56; //weakness
|
||||
spellToEffect[46] = 54; //stone skin
|
||||
spellToEffect[47] = 14; //disrupting ray
|
||||
spellToEffect[48] = 0; //prayer
|
||||
spellToEffect[49] = 20; //mirth
|
||||
spellToEffect[50] = 30; //sorrow
|
||||
@ -1862,7 +1863,9 @@ void CBattleInterface::spellCasted(SpellCasted * sc)
|
||||
SDL_SetClipRect(screen, &buf); //restoring previous clip rect
|
||||
break; //for 15 and 16 cases
|
||||
}
|
||||
}
|
||||
case 35: //dispel
|
||||
displayEffect(spellToEffect[sc->id], sc->tile);
|
||||
} //switch(sc->id)
|
||||
}
|
||||
|
||||
void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
|
||||
|
@ -486,6 +486,17 @@ const CStack::StackEffect * CStack::getEffect(ui16 id) const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ui8 CStack::howManyEffectsSet(ui16 id) const
|
||||
{
|
||||
ui8 ret = 0;
|
||||
for (int i=0; i< effects.size(); i++)
|
||||
if(effects[i].id == id) //effect found
|
||||
{
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
si8 CStack::Morale() const
|
||||
{
|
||||
si8 ret = morale;
|
||||
@ -1697,7 +1708,7 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
|
||||
//calculating total attack/defense skills modifier
|
||||
if(attacker->getEffect(56)) //frenzy for attacker
|
||||
{
|
||||
attackerAttackBonus += (VLC->spellh->spells[attacker->getEffect(56)->id].powers[attacker->getEffect(56)->level]/100.0) *(attacker->creature->defence + (attackerHero ? attackerHero->getPrimSkillLevel(1) : 0));
|
||||
attackerAttackBonus += (VLC->spellh->spells[56].powers[attacker->getEffect(56)->level]/100.0) *(attacker->creature->defence + (attackerHero ? attackerHero->getPrimSkillLevel(1) : 0));
|
||||
}
|
||||
if(defender->getEffect(56)) //frenzy for defender
|
||||
{
|
||||
@ -1706,23 +1717,28 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
|
||||
attackDefenseBonus = attackerAttackBonus - defenderDefenseBonus;
|
||||
if(defender->getEffect(48)) //defender's prayer handling
|
||||
{
|
||||
attackDefenseBonus -= VLC->spellh->spells[defender->getEffect(48)->id].powers[defender->getEffect(48)->level];
|
||||
attackDefenseBonus -= VLC->spellh->spells[48].powers[defender->getEffect(48)->level];
|
||||
}
|
||||
if(attacker->getEffect(48)) //attacker's prayer handling
|
||||
{
|
||||
attackDefenseBonus += VLC->spellh->spells[attacker->getEffect(48)->id].powers[attacker->getEffect(48)->level];
|
||||
attackDefenseBonus += VLC->spellh->spells[48].powers[attacker->getEffect(48)->level];
|
||||
}
|
||||
if(defender->getEffect(47)) //defender's disrupting ray handling
|
||||
{
|
||||
int howMany = defender->howManyEffectsSet(47);
|
||||
attackDefenseBonus += VLC->spellh->spells[47].powers[attacker->getEffect(47)->level] * howMany;
|
||||
}
|
||||
if(defender->getEffect(46)) //stone skin handling
|
||||
{
|
||||
attackDefenseBonus -= VLC->spellh->spells[defender->getEffect(46)->id].powers[defender->getEffect(46)->level];
|
||||
attackDefenseBonus -= VLC->spellh->spells[46].powers[defender->getEffect(46)->level];
|
||||
}
|
||||
if(attacker->getEffect(45)) //weakness handling
|
||||
{
|
||||
attackDefenseBonus -= VLC->spellh->spells[attacker->getEffect(45)->id].powers[attacker->getEffect(45)->level];
|
||||
attackDefenseBonus -= VLC->spellh->spells[45].powers[attacker->getEffect(45)->level];
|
||||
}
|
||||
if(!shooting && attacker->getEffect(43)) //bloodlust handling
|
||||
{
|
||||
attackDefenseBonus += VLC->spellh->spells[attacker->getEffect(43)->id].powers[attacker->getEffect(43)->level];
|
||||
attackDefenseBonus += VLC->spellh->spells[43].powers[attacker->getEffect(43)->level];
|
||||
}
|
||||
|
||||
float dmgBonusMultiplier = 1.0f;
|
||||
@ -1828,12 +1844,12 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
|
||||
|
||||
if(attacker->getEffect(42)) //curse handling (rest)
|
||||
{
|
||||
minDmg -= VLC->spellh->spells[attacker->getEffect(42)->id].powers[attacker->getEffect(42)->level];
|
||||
minDmg -= VLC->spellh->spells[42].powers[attacker->getEffect(42)->level];
|
||||
return minDmg;
|
||||
}
|
||||
else if(attacker->getEffect(41)) //bless handling
|
||||
{
|
||||
maxDmg += VLC->spellh->spells[attacker->getEffect(41)->id].powers[attacker->getEffect(41)->level];
|
||||
maxDmg += VLC->spellh->spells[41].powers[attacker->getEffect(41)->level];
|
||||
return maxDmg;
|
||||
}
|
||||
else
|
||||
|
@ -171,6 +171,7 @@ public:
|
||||
CStack(CCreature * C, int A, int O, int I, bool AO, int S);
|
||||
CStack() : ID(-1), creature(NULL), amount(-1), baseAmount(-1), firstHPleft(-1), owner(255), slot(255), attackerOwned(true), position(-1), counterAttacks(1), abilities(), state(), effects() {}
|
||||
const StackEffect * getEffect(ui16 id) const; //effect id (SP)
|
||||
ui8 howManyEffectsSet(ui16 id) const; //returns amount of effects with given id set for this stack
|
||||
bool willMove(); //if stack has remaining move this turn
|
||||
ui32 Speed() const;
|
||||
si8 Morale() const;
|
||||
|
@ -558,6 +558,14 @@ DLL_EXPORT void SpellCasted::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->curB->castedSpells[side]++;
|
||||
}
|
||||
if(gs->curB && id == 35) //dispel
|
||||
{
|
||||
CStack *s = gs->curB->getStackT(tile);
|
||||
if(s)
|
||||
{
|
||||
s->effects.clear(); //removing all effects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
@ -567,14 +575,7 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
CStack *s = gs->curB->getStack(id);
|
||||
if(s)
|
||||
{
|
||||
if(effect.id == 35) //dispel - removing all effects
|
||||
{
|
||||
s->effects.clear();
|
||||
}
|
||||
else //adding effect
|
||||
{
|
||||
s->effects.push_back(effect);
|
||||
}
|
||||
s->effects.push_back(effect); //adding effect
|
||||
}
|
||||
else
|
||||
tlog1 << "Cannot find stack " << id << std::endl;
|
||||
|
@ -2281,42 +2281,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
|
||||
//TODO: check resistances
|
||||
|
||||
#define SPELL_CAST_TEMPLATE_1(NUMBER, DURATION) SetStackEffect sse; \
|
||||
if(h->getSpellSchoolLevel(s) < 3) /*not expert */ \
|
||||
{ \
|
||||
sse.stacks.insert(gs->curB->getStackT(ba.destinationTile)->ID); \
|
||||
sse.effect.id = (NUMBER); \
|
||||
sse.effect.level = h->getSpellSchoolLevel(s); \
|
||||
sse.effect.turnsRemain = (DURATION); /*! - any duration */ \
|
||||
sendAndApply(&sse); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for(int it=0; it<gs->curB->stacks.size(); ++it) \
|
||||
{ \
|
||||
/*if it's non negative spell and our unit or non positive spell and hostile unit */ \
|
||||
if((VLC->spellh->spells[ba.additionalInfo].positiveness >= 0 && gs->curB->stacks[it]->owner == h->tempOwner) \
|
||||
||(VLC->spellh->spells[ba.additionalInfo].positiveness <= 0 && gs->curB->stacks[it]->owner != h->tempOwner ) \
|
||||
) \
|
||||
{ \
|
||||
sse.stacks.insert(gs->curB->stacks[it]->ID); \
|
||||
} \
|
||||
} \
|
||||
sse.effect.id = (NUMBER); \
|
||||
sse.effect.level = h->getSpellSchoolLevel(s); \
|
||||
sse.effect.turnsRemain = (DURATION); \
|
||||
sendAndApply(&sse); \
|
||||
}
|
||||
|
||||
#define SPELL_CAST_TEMPLATE_2(EFFECT_ID, DAMAGE) std::set<ui16> attackedHexes = s->rangeInHexes(ba.destinationTile, h->getSpellSchoolLevel(s)); \
|
||||
std::set<CStack*> attackedCres; /*std::set to exclude multiple occurences of two hex creatures*/ \
|
||||
for(std::set<ui16>::iterator it = attackedHexes.begin(); it != attackedHexes.end(); ++it) \
|
||||
{ \
|
||||
CStack * st = gs->curB->getStackT(*it); \
|
||||
if(st) \
|
||||
attackedCres.insert(st); \
|
||||
} \
|
||||
if(attackedCres.size() == 0) break; \
|
||||
#define SPELL_CAST_TEMPLATE_2(EFFECT_ID, DAMAGE) \
|
||||
StacksInjured si; \
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it) \
|
||||
{ \
|
||||
@ -2336,6 +2301,49 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
sc.skill = skill;
|
||||
sc.tile = ba.destinationTile;
|
||||
sendAndApply(&sc);
|
||||
|
||||
//calculating affected creatures - not for all spells, but for many of them
|
||||
//it should spoil anything for other spells
|
||||
std::set<ui16> attackedHexes = s->rangeInHexes(ba.destinationTile, h->getSpellSchoolLevel(s));
|
||||
std::set<CStack*> attackedCres; /*std::set to exclude multiple occurences of two hex creatures*/
|
||||
if(VLC->spellh->spells[ba.additionalInfo].attributes.find("CREATURE_TARGET") != std::string::npos) //spell to be cast on one specific creature
|
||||
{
|
||||
CStack * st = gs->curB->getStackT(ba.destinationTile);
|
||||
if(st)
|
||||
attackedCres.insert(st);
|
||||
}
|
||||
else if(VLC->spellh->spells[ba.additionalInfo].attributes.find("CREATURE_TARGET_2") != std::string::npos) //spell to be cast on a specific creature but massive on expert
|
||||
{
|
||||
if(h->getSpellSchoolLevel(s) < 3) /*not expert */
|
||||
{
|
||||
CStack * st = gs->curB->getStackT(ba.destinationTile);
|
||||
if(st)
|
||||
attackedCres.insert(st);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int it=0; it<gs->curB->stacks.size(); ++it)
|
||||
{
|
||||
/*if it's non negative spell and our unit or non positive spell and hostile unit */
|
||||
if((VLC->spellh->spells[ba.additionalInfo].positiveness >= 0 && gs->curB->stacks[it]->owner == h->tempOwner)
|
||||
||(VLC->spellh->spells[ba.additionalInfo].positiveness <= 0 && gs->curB->stacks[it]->owner != h->tempOwner )
|
||||
)
|
||||
{
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
}
|
||||
} //if(h->getSpellSchoolLevel(s) < 3)
|
||||
}
|
||||
else //custom range from attackedHexes
|
||||
{
|
||||
for(std::set<ui16>::iterator it = attackedHexes.begin(); it != attackedHexes.end(); ++it)
|
||||
{
|
||||
CStack * st = gs->curB->getStackT(*it);
|
||||
attackedCres.insert(st);
|
||||
}
|
||||
}
|
||||
//affected creatures calculated
|
||||
//applying effects
|
||||
switch(ba.additionalInfo) //spell id
|
||||
{
|
||||
case 15: //magic arrow
|
||||
@ -2388,18 +2396,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
if(attackedCres.size() == 0) break;
|
||||
StacksInjured si;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
BattleStackAttacked bsa;
|
||||
bsa.flags |= 2;
|
||||
bsa.effect = 8;
|
||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 5 + s->powers[h->getSpellSchoolLevel(s)];
|
||||
bsa.stackAttacked = (*it)->ID;
|
||||
prepareAttacked(bsa,*it);
|
||||
si.stacks.insert(bsa);
|
||||
}
|
||||
sendAndApply(&si);
|
||||
SPELL_CAST_TEMPLATE_2(8, h->getPrimSkillLevel(2) * 5 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 25: //destroy undead
|
||||
@ -2412,18 +2409,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
if(attackedCres.size() == 0) break;
|
||||
StacksInjured si;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
BattleStackAttacked bsa;
|
||||
bsa.flags |= 2;
|
||||
bsa.effect = 29;
|
||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)];
|
||||
bsa.stackAttacked = (*it)->ID;
|
||||
prepareAttacked(bsa,*it);
|
||||
si.stacks.insert(bsa);
|
||||
}
|
||||
sendAndApply(&si);
|
||||
SPELL_CAST_TEMPLATE_2(29, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 26: //armageddon
|
||||
@ -2435,28 +2421,17 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
if(attackedCres.size() == 0) break;
|
||||
StacksInjured si;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
BattleStackAttacked bsa;
|
||||
bsa.flags |= 2;
|
||||
bsa.effect = 12;
|
||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)];
|
||||
bsa.stackAttacked = (*it)->ID;
|
||||
prepareAttacked(bsa,*it);
|
||||
si.stacks.insert(bsa);
|
||||
}
|
||||
sendAndApply(&si);
|
||||
SPELL_CAST_TEMPLATE_2(12, h->getPrimSkillLevel(2) * 50 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 27: //shield
|
||||
case 28: //air shield
|
||||
case 35: //dispel
|
||||
case 41: //bless
|
||||
case 42: //curse
|
||||
case 43: //bloodlust
|
||||
case 45: //weakness
|
||||
case 46: //stone skin
|
||||
case 47: //disrupting ray
|
||||
case 48: //prayer
|
||||
case 49: //mirth
|
||||
case 50: //sorrow
|
||||
@ -2466,13 +2441,29 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
case 54: //slow
|
||||
case 61: //forgetfulness
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_1(ba.additionalInfo, h->getPrimSkillLevel(2) + h->valOfBonuses(HeroBonus::SPELL_DURATION) )
|
||||
break;
|
||||
SetStackEffect sse;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case 56: //frenzy
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_1(ba.additionalInfo, 1)
|
||||
break;
|
||||
SetStackEffect sse;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
|
||||
{
|
||||
sse.stacks.insert((*it)->ID);
|
||||
}
|
||||
sse.effect.id = ba.additionalInfo;
|
||||
sse.effect.level = h->getSpellSchoolLevel(s);
|
||||
sse.effect.turnsRemain = 1;
|
||||
sendAndApply(&sse);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sendAndApply(&EndAction());
|
||||
|
Loading…
x
Reference in New Issue
Block a user