mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* new spells
- protection from air - protection from fire - protection from water - protection from earth * a bit of refactoring in spell handling code
This commit is contained in:
parent
e88ba16ffa
commit
d14083272d
@ -261,28 +261,6 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
|
||||
SDL_SetColorKey(idToObstacle[obst[t].ID]->ourImages[n].bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(idToObstacle[obst[t].ID]->ourImages[n].bitmap->format,0,255,255));
|
||||
}
|
||||
}
|
||||
|
||||
//initializing spellToEffect
|
||||
spellToEffect[17] = 1; //lightning bolt
|
||||
spellToEffect[18] = 10; //implosion
|
||||
spellToEffect[27] = 27; //shield
|
||||
spellToEffect[28] = 2; //air shield
|
||||
spellToEffect[35] = 41; //dispel
|
||||
spellToEffect[41] = 36; //bless
|
||||
spellToEffect[42] = 40; //curse
|
||||
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
|
||||
spellToEffect[51] = 18; //fortune
|
||||
spellToEffect[52] = 48; //misfortune
|
||||
spellToEffect[53] = 31; //haste
|
||||
spellToEffect[54] = 19; //slow
|
||||
spellToEffect[56] = 17; //frenzy
|
||||
spellToEffect[61] = 42; //forgetfulness
|
||||
}
|
||||
|
||||
CBattleInterface::~CBattleInterface()
|
||||
@ -1863,8 +1841,11 @@ void CBattleInterface::spellCasted(SpellCasted * sc)
|
||||
SDL_SetClipRect(screen, &buf); //restoring previous clip rect
|
||||
break; //for 15 and 16 cases
|
||||
}
|
||||
case 17: //lightning bolt
|
||||
displayEffect(1, sc->tile);
|
||||
displayEffect(CGI->spellh->spells[sc->id].mainEffectAnim, sc->tile);
|
||||
case 35: //dispel
|
||||
displayEffect(spellToEffect[sc->id], sc->tile);
|
||||
displayEffect(CGI->spellh->spells[sc->id].mainEffectAnim, sc->tile);
|
||||
} //switch(sc->id)
|
||||
}
|
||||
|
||||
@ -1872,7 +1853,7 @@ void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
|
||||
{
|
||||
for(std::set<ui32>::const_iterator ci = sse.stacks.begin(); ci!=sse.stacks.end(); ++ci)
|
||||
{
|
||||
displayEffect(spellToEffect[sse.effect.id], LOCPLINT->cb->battleGetStackByID(*ci)->position);
|
||||
displayEffect(CGI->spellh->spells[sse.effect.id].mainEffectAnim, LOCPLINT->cb->battleGetStackByID(*ci)->position);
|
||||
}
|
||||
redrawBackgroundWithHexes(activeStack);
|
||||
}
|
||||
|
@ -165,7 +165,6 @@ private:
|
||||
std::map< int, CDefHandler * > idToProjectile; //projectiles of creaures (creatureID, defhandler)
|
||||
std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield
|
||||
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
|
||||
std::map< int, int > spellToEffect; //which effect should be played when different spells are casted (spellID, effectID)
|
||||
unsigned char animCount;
|
||||
int activeStack; //number of active stack; -1 - no one
|
||||
int mouseHoveredStack; //stack hovered by mouse; if -1 -> none
|
||||
|
@ -1,73 +1,73 @@
|
||||
//additional spell info, not included in original heroes III files
|
||||
//[spellID - -1 is the end of data in file] [-1 -> spell is negative for influenced creatures; 0 - spell is indifferent for them; 1 - spell is poitive for them] [spell range description in SRSL, none magic] [basic] [advanced] [expert]
|
||||
0 0 X X X X
|
||||
1 0 X X X X
|
||||
2 0 X X X X
|
||||
3 0 X X X X
|
||||
4 0 X X X X
|
||||
5 0 X X X X
|
||||
6 0 X X X X
|
||||
7 0 X X X X
|
||||
8 0 X X X X
|
||||
9 0 X X X X
|
||||
10 0 X X X X
|
||||
11 0 X X X X
|
||||
12 0 0 0 0 0
|
||||
13 0 0 0 0 0
|
||||
14 0 X X X X
|
||||
15 -1 0 0 0 0
|
||||
16 -1 0 0 0 0
|
||||
17 -1 0 0 0 0
|
||||
18 -1 0 0 0 0
|
||||
19 -1 0 0 0 0
|
||||
20 -1 1 1 1 1
|
||||
21 -1 0,1 0,1 0,1 0,1
|
||||
22 -1 0-2 0-2 0-2 0-2
|
||||
23 -1 0,1 0,1 0,1 0,1
|
||||
24 -1 X X X X
|
||||
25 -1 X X X X
|
||||
26 -1 X X X X
|
||||
27 1 0 0 0 X
|
||||
28 1 0 0 0 X
|
||||
29 1 0 0 0 X
|
||||
30 1 0 0 0 X
|
||||
31 1 0 0 0 X
|
||||
32 1 0 0 0 X
|
||||
33 1 0 0 0 X
|
||||
34 1 0 0 0 X
|
||||
35 0 0 0 0 X
|
||||
36 1 0 0 0 0
|
||||
37 1 0 0 0 0
|
||||
38 1 0 0 0 0
|
||||
39 1 0 0 0 0
|
||||
40 1 0 0 0 0
|
||||
41 1 0 0 0 X
|
||||
42 -1 0 0 0 X
|
||||
43 1 0 0 0 X
|
||||
44 1 0 0 0 X
|
||||
45 -1 0 0 0 X
|
||||
46 1 0 0 0 X
|
||||
47 -1 0 0 0 X
|
||||
48 1 0 0 0 X
|
||||
49 1 0 0 0 X
|
||||
50 -1 0 0 0 X
|
||||
51 1 0 0 0 X
|
||||
52 -1 0 0 0 X
|
||||
53 1 0 0 0 X
|
||||
54 -1 0 0 0 X
|
||||
55 1 0 0 0 0
|
||||
56 1 0 0 0 0
|
||||
57 -1 0 0 0 0
|
||||
58 1 0 0 0 X
|
||||
59 -1 0 0 0-1 0-2
|
||||
60 -1 0 0 0 0
|
||||
61 -1 0 0 0 X
|
||||
62 -1 0 0 0 0
|
||||
63 1 0 0 0 0
|
||||
64 0 X X X X
|
||||
65 1 0 0 0 0
|
||||
66 0 X X X X
|
||||
67 0 X X X X
|
||||
68 0 X X X X
|
||||
69 0 X X X X
|
||||
//[spellID - -1 is the end of data in file] [-1 -> spell is negative for influenced creatures; 0 - spell is indifferent for them; 1 - spell is poitive for them] [main effect animation (AC format), -1 - none] [spell range description in SRSL, none magic] [basic] [advanced] [expert]
|
||||
0 0 -1 X X X X
|
||||
1 0 -1 X X X X
|
||||
2 0 -1 X X X X
|
||||
3 0 -1 X X X X
|
||||
4 0 -1 X X X X
|
||||
5 0 -1 X X X X
|
||||
6 0 -1 X X X X
|
||||
7 0 -1 X X X X
|
||||
8 0 -1 X X X X
|
||||
9 0 -1 X X X X
|
||||
10 0 -1 X X X X
|
||||
11 0 -1 X X X X
|
||||
12 0 -1 0 0 0 0
|
||||
13 0 -1 0 0 0 0
|
||||
14 0 -1 X X X X
|
||||
15 -1 64 0 0 0 0
|
||||
16 -1 46 0 0 0 0
|
||||
17 -1 38 0 0 0 0
|
||||
18 -1 10 0 0 0 0
|
||||
19 -1 -1 0 0 0 0
|
||||
20 -1 45 1 1 1 1
|
||||
21 -1 53 0,1 0,1 0,1 0,1
|
||||
22 -1 9 0-2 0-2 0-2 0-2
|
||||
23 -1 16 0,1 0,1 0,1 0,1
|
||||
24 -1 8 X X X X
|
||||
25 -1 29 X X X X
|
||||
26 -1 12 X X X X
|
||||
27 1 27 0 0 0 X
|
||||
28 1 2 0 0 0 X
|
||||
29 1 -1 0 0 0 X
|
||||
30 1 22 0 0 0 X
|
||||
31 1 24 0 0 0 X
|
||||
32 1 23 0 0 0 X
|
||||
33 1 26 0 0 0 X
|
||||
34 1 -1 0 0 0 X
|
||||
35 0 41 0 0 0 X
|
||||
36 1 -1 0 0 0 0
|
||||
37 1 -1 0 0 0 0
|
||||
38 1 -1 0 0 0 0
|
||||
39 1 -1 0 0 0 0
|
||||
40 1 -1 0 0 0 0
|
||||
41 1 36 0 0 0 X
|
||||
42 -1 40 0 0 0 X
|
||||
43 1 4 0 0 0 X
|
||||
44 1 -1 0 0 0 X
|
||||
45 -1 56 0 0 0 X
|
||||
46 1 54 0 0 0 X
|
||||
47 -1 14 0 0 0 X
|
||||
48 1 0 0 0 0 X
|
||||
49 1 20 0 0 0 X
|
||||
50 -1 30 0 0 0 X
|
||||
51 1 18 0 0 0 X
|
||||
52 -1 48 0 0 0 X
|
||||
53 1 31 0 0 0 X
|
||||
54 -1 19 0 0 0 X
|
||||
55 1 -1 0 0 0 0
|
||||
56 1 17 0 0 0 0
|
||||
57 -1 -1 0 0 0 0
|
||||
58 1 -1 0 0 0 X
|
||||
59 -1 -1 0 0 0-1 0-2
|
||||
60 -1 -1 0 0 0 0
|
||||
61 -1 42 0 0 0 X
|
||||
62 -1 -1 0 0 0 0
|
||||
63 1 -1 0 0 0 0
|
||||
64 0 -1 X X X X
|
||||
65 1 -1 0 0 0 0
|
||||
66 0 -1 X X X X
|
||||
67 0 -1 X X X X
|
||||
68 0 -1 X X X X
|
||||
69 0 -1 X X X X
|
||||
-1
|
@ -255,6 +255,7 @@ void CSpellHandler::loadSpells()
|
||||
nsp.id = spells.size();
|
||||
nsp.combatSpell = combSpells;
|
||||
nsp.creatureAbility = creatureAbility;
|
||||
nsp.mainEffectAnim = -1;
|
||||
spells.push_back(nsp);
|
||||
}
|
||||
//loading of additional spell traits
|
||||
@ -268,15 +269,18 @@ void CSpellHandler::loadSpells()
|
||||
{
|
||||
//reading header
|
||||
std::string dump;
|
||||
for(int i=0; i<52; ++i) ast>>dump;
|
||||
for(int i=0; i<60; ++i) ast>>dump;
|
||||
//reading exact info
|
||||
int spellID;
|
||||
ast>>spellID;
|
||||
while(spellID != -1)
|
||||
{
|
||||
int buf;
|
||||
ast>>buf;
|
||||
ast >> buf;
|
||||
spells[spellID].positiveness = buf;
|
||||
ast >> buf;
|
||||
spells[spellID].mainEffectAnim = buf;
|
||||
|
||||
spells[spellID].range.resize(4);
|
||||
for(int g=0; g<4; ++g)
|
||||
ast>>spells[spellID].range[g];
|
||||
|
@ -38,12 +38,12 @@ public:
|
||||
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::set<ui16> rangeInHexes(unsigned int centralHex, ui8 schoolLvl ) const; //convert range to specific hexes
|
||||
|
||||
si16 mainEffectAnim; //main spell effect animation, in AC format (or -1 when none)
|
||||
|
||||
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;
|
||||
& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness & range & mainEffectAnim;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2246,6 +2246,81 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
}
|
||||
}
|
||||
|
||||
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature)
|
||||
{
|
||||
ui32 ret = 0; //value to return
|
||||
switch(sp->id)
|
||||
{
|
||||
case 15: //magic arrow
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 16: //ice bolt
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 20 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 17: //lightning bolt
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 25 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 18: //implosion
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 75 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 20: //frost ring
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 21: //fireball
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 22: //inferno
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 23: //meteor shower
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 24: //death ripple
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 5 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 25: //destroy undead
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 10 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
case 26: //armageddon
|
||||
{
|
||||
ret = caster->getPrimSkillLevel(2) * 50 + sp->powers[caster->getSpellSchoolLevel(sp)];
|
||||
}
|
||||
}
|
||||
//applying protections - when spell has more then one elements, only one protection should be applied (I think)
|
||||
if(sp->air && affectedCreature->getEffect(30)) //air spell & protection from air
|
||||
{
|
||||
ret *= VLC->spellh->spells[30].powers[affectedCreature->getEffect(30)->level];
|
||||
ret /= 100;
|
||||
}
|
||||
else if(sp->fire && affectedCreature->getEffect(31)) //fire spell & protection from fire
|
||||
{
|
||||
ret *= VLC->spellh->spells[31].powers[affectedCreature->getEffect(31)->level];
|
||||
ret /= 100;
|
||||
}
|
||||
else if(sp->water && affectedCreature->getEffect(32)) //water spell & protection from water
|
||||
{
|
||||
ret *= VLC->spellh->spells[32].powers[affectedCreature->getEffect(32)->level];
|
||||
ret /= 100;
|
||||
}
|
||||
else if (sp->earth && affectedCreature->getEffect(33)) //earth spell & protection from earth
|
||||
{
|
||||
ret *= VLC->spellh->spells[33].powers[affectedCreature->getEffect(33)->level];
|
||||
ret /= 100;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
{
|
||||
switch(ba.actionType)
|
||||
@ -2281,14 +2356,14 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
|
||||
//TODO: check resistances
|
||||
|
||||
#define SPELL_CAST_TEMPLATE_2(EFFECT_ID, DAMAGE) \
|
||||
#define SPELL_CAST_TEMPLATE_2 \
|
||||
StacksInjured si; \
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it) \
|
||||
{ \
|
||||
BattleStackAttacked bsa; \
|
||||
bsa.flags |= 2; \
|
||||
bsa.effect = EFFECT_ID; \
|
||||
bsa.damageAmount = DAMAGE; \
|
||||
bsa.effect = VLC->spellh->spells[ba.additionalInfo].mainEffectAnim; \
|
||||
bsa.damageAmount = calculateSpellDmg(&VLC->spellh->spells[ba.additionalInfo], h, *it); \
|
||||
bsa.stackAttacked = (*it)->ID; \
|
||||
prepareAttacked(bsa,*it); \
|
||||
si.stacks.insert(bsa); \
|
||||
@ -2306,13 +2381,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
//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(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 */
|
||||
{
|
||||
@ -2334,11 +2403,18 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
}
|
||||
} //if(h->getSpellSchoolLevel(s) < 3)
|
||||
}
|
||||
else 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 //custom range from attackedHexes
|
||||
{
|
||||
for(std::set<ui16>::iterator it = attackedHexes.begin(); it != attackedHexes.end(); ++it)
|
||||
{
|
||||
CStack * st = gs->curB->getStackT(*it);
|
||||
if(st)
|
||||
attackedCres.insert(st);
|
||||
}
|
||||
}
|
||||
@ -2347,43 +2423,15 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
switch(ba.additionalInfo) //spell id
|
||||
{
|
||||
case 15: //magic arrow
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(64, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 16: //ice bolt
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(46, h->getPrimSkillLevel(2) * 20 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 17: //lightning bolt
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(38, h->getPrimSkillLevel(2) * 25 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 18: //implosion
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(10, h->getPrimSkillLevel(2) * 75 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 20: //frost ring
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(45, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 21: //fireball
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(53, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 22: //inferno
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(9, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
break;
|
||||
}
|
||||
case 23: //meteor shower
|
||||
{
|
||||
SPELL_CAST_TEMPLATE_2(16, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
SPELL_CAST_TEMPLATE_2;
|
||||
break;
|
||||
}
|
||||
case 24: //death ripple
|
||||
@ -2396,7 +2444,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
if(attackedCres.size() == 0) break;
|
||||
SPELL_CAST_TEMPLATE_2(8, h->getPrimSkillLevel(2) * 5 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
SPELL_CAST_TEMPLATE_2;
|
||||
break;
|
||||
}
|
||||
case 25: //destroy undead
|
||||
@ -2409,7 +2457,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
if(attackedCres.size() == 0) break;
|
||||
SPELL_CAST_TEMPLATE_2(29, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
SPELL_CAST_TEMPLATE_2;
|
||||
break;
|
||||
}
|
||||
case 26: //armageddon
|
||||
@ -2421,11 +2469,15 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
attackedCres.insert(gs->curB->stacks[it]);
|
||||
}
|
||||
if(attackedCres.size() == 0) break;
|
||||
SPELL_CAST_TEMPLATE_2(12, h->getPrimSkillLevel(2) * 50 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||
SPELL_CAST_TEMPLATE_2;
|
||||
break;
|
||||
}
|
||||
case 27: //shield
|
||||
case 28: //air shield
|
||||
case 30: //protection from air
|
||||
case 31: //protection from fire
|
||||
case 32: //protection from water
|
||||
case 33: //protection from earth
|
||||
case 41: //bless
|
||||
case 42: //curse
|
||||
case 43: //bloodlust
|
||||
|
Loading…
Reference in New Issue
Block a user