1
0
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:
mateuszb 2009-04-21 17:32:43 +00:00
parent c8b6858716
commit 35f63bdc5f
5 changed files with 106 additions and 94 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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());