mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* canceling of casting a spell by pressing Escape or R-click (R-click on a creatures does not cancel a spell)
* new spells: - frost ring - fireball - inferno - meteor shower - death ripple - destroy undead * spellbook button is inactive when hero cannot cast any spell * obstacles will be placed more properly when resolution is different than 800x600 * minor changes
This commit is contained in:
parent
06bb6dcce9
commit
7319e5cb0e
@ -344,6 +344,7 @@ void CBattleInterface::activate()
|
|||||||
{
|
{
|
||||||
KeyInterested::activate();
|
KeyInterested::activate();
|
||||||
MotionInterested::activate();
|
MotionInterested::activate();
|
||||||
|
ClickableR::activate();
|
||||||
subInt = NULL;
|
subInt = NULL;
|
||||||
bOptions->activate();
|
bOptions->activate();
|
||||||
bSurrender->activate();
|
bSurrender->activate();
|
||||||
@ -370,6 +371,7 @@ void CBattleInterface::deactivate()
|
|||||||
{
|
{
|
||||||
KeyInterested::deactivate();
|
KeyInterested::deactivate();
|
||||||
MotionInterested::deactivate();
|
MotionInterested::deactivate();
|
||||||
|
ClickableR::deactivate();
|
||||||
bOptions->deactivate();
|
bOptions->deactivate();
|
||||||
bSurrender->deactivate();
|
bSurrender->deactivate();
|
||||||
bFlee->deactivate();
|
bFlee->deactivate();
|
||||||
@ -482,7 +484,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
|||||||
bConsoleUp->show(to);
|
bConsoleUp->show(to);
|
||||||
bConsoleDown->show(to);
|
bConsoleDown->show(to);
|
||||||
|
|
||||||
|
//prevents blitting outside this window
|
||||||
SDL_GetClipRect(to, &buf);
|
SDL_GetClipRect(to, &buf);
|
||||||
SDL_SetClipRect(to, &pos);
|
SDL_SetClipRect(to, &pos);
|
||||||
|
|
||||||
@ -490,9 +492,9 @@ void CBattleInterface::show(SDL_Surface * to)
|
|||||||
std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
|
std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
|
||||||
for(int b=0; b<obstacles.size(); ++b)
|
for(int b=0; b<obstacles.size(); ++b)
|
||||||
{
|
{
|
||||||
int x = ((obstacles[b].pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(obstacles[b].pos%BFIELD_WIDTH);
|
int x = ((obstacles[b].pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(obstacles[b].pos%BFIELD_WIDTH) + pos.x;
|
||||||
int y = 86 + 42 * (obstacles[b].pos/BFIELD_WIDTH);
|
int y = 86 + 42 * (obstacles[b].pos/BFIELD_WIDTH) + pos.y;
|
||||||
std::vector<Cimage> &images = idToObstacle[obstacles[b].ID]->ourImages;
|
std::vector<Cimage> &images = idToObstacle[obstacles[b].ID]->ourImages; //reference to animation of obstacle
|
||||||
blitAt(images[((animCount+1)/(4/settings.animSpeed))%images.size()].bitmap, x, y, to);
|
blitAt(images[((animCount+1)/(4/settings.animSpeed))%images.size()].bitmap, x, y, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,6 +713,10 @@ void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
|||||||
{
|
{
|
||||||
showStackQueue = key.state==SDL_PRESSED;
|
showStackQueue = key.state==SDL_PRESSED;
|
||||||
}
|
}
|
||||||
|
else if(key.keysym.sym == SDLK_ESCAPE && spellDestSelectMode)
|
||||||
|
{
|
||||||
|
endCastingSpell();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||||
{
|
{
|
||||||
@ -928,6 +934,14 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBattleInterface::clickRight(boost::logic::tribool down)
|
||||||
|
{
|
||||||
|
if(!down && spellDestSelectMode)
|
||||||
|
{
|
||||||
|
endCastingSpell();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CBattleInterface::reverseCreature(int number, int hex, bool wideTrick)
|
bool CBattleInterface::reverseCreature(int number, int hex, bool wideTrick)
|
||||||
{
|
{
|
||||||
if(creAnims[number]==NULL)
|
if(creAnims[number]==NULL)
|
||||||
@ -1076,11 +1090,13 @@ void CBattleInterface::stackActivated(int number)
|
|||||||
//block cast spell button if hero doesn't have a spellbook
|
//block cast spell button if hero doesn't have a spellbook
|
||||||
if(attackingHeroInstance && attackingHeroInstance->tempOwner==LOCPLINT->cb->battleGetStackByID(number)->owner)
|
if(attackingHeroInstance && attackingHeroInstance->tempOwner==LOCPLINT->cb->battleGetStackByID(number)->owner)
|
||||||
{
|
{
|
||||||
bSpell->block(!attackingHeroInstance->getArt(17));
|
if(!attackingHeroInstance->getArt(17)) //don't unlock if already locked
|
||||||
|
bSpell->block(!attackingHeroInstance->getArt(17));
|
||||||
}
|
}
|
||||||
else if(defendingHeroInstance && defendingHeroInstance->tempOwner==LOCPLINT->cb->battleGetStackByID(number)->owner)
|
else if(defendingHeroInstance && defendingHeroInstance->tempOwner==LOCPLINT->cb->battleGetStackByID(number)->owner)
|
||||||
{
|
{
|
||||||
bSpell->block(!defendingHeroInstance->getArt(17));
|
if(!defendingHeroInstance->getArt(17)) //don't unlock if already locked
|
||||||
|
bSpell->block(!defendingHeroInstance->getArt(17));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1293,6 +1309,7 @@ void CBattleInterface::stacksAreAttacked(std::vector<CBattleInterface::SStackAtt
|
|||||||
{
|
{
|
||||||
show(screen);
|
show(screen);
|
||||||
CSDL_Ext::update(screen);
|
CSDL_Ext::update(screen);
|
||||||
|
SDL_Delay(5);
|
||||||
SDL_framerateDelay(LOCPLINT->mainFPSmng);
|
SDL_framerateDelay(LOCPLINT->mainFPSmng);
|
||||||
for(size_t g=0; g<attackedInfos.size(); ++g)
|
for(size_t g=0; g<attackedInfos.size(); ++g)
|
||||||
{
|
{
|
||||||
@ -1492,6 +1509,9 @@ void CBattleInterface::stackAttacking(int ID, int dest)
|
|||||||
void CBattleInterface::newRound(int number)
|
void CBattleInterface::newRound(int number)
|
||||||
{
|
{
|
||||||
console->addText(CGI->generaltexth->allTexts[412]);
|
console->addText(CGI->generaltexth->allTexts[412]);
|
||||||
|
|
||||||
|
//unlock spellbook
|
||||||
|
bSpell->block(!LOCPLINT->cb->battleCanCastSpell());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional)
|
void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional)
|
||||||
@ -1549,10 +1569,7 @@ void CBattleInterface::hexLclicked(int whichOne)
|
|||||||
{
|
{
|
||||||
spellToCast->destinationTile = whichOne;
|
spellToCast->destinationTile = whichOne;
|
||||||
LOCPLINT->cb->battleMakeAction(spellToCast);
|
LOCPLINT->cb->battleMakeAction(spellToCast);
|
||||||
delete spellToCast;
|
endCastingSpell();
|
||||||
spellToCast = NULL;
|
|
||||||
spellDestSelectMode = false;
|
|
||||||
CGI->curh->changeGraphic(1, 6);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1979,6 +1996,16 @@ float CBattleInterface::getAnimSpeedMultiplier() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBattleInterface::endCastingSpell()
|
||||||
|
{
|
||||||
|
assert(spellDestSelectMode);
|
||||||
|
|
||||||
|
delete spellToCast;
|
||||||
|
spellToCast = NULL;
|
||||||
|
spellDestSelectMode = false;
|
||||||
|
CGI->curh->changeGraphic(1, 6);
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleInterface::attackingShowHelper()
|
void CBattleInterface::attackingShowHelper()
|
||||||
{
|
{
|
||||||
if(attackingInfo && !attackingInfo->reversing)
|
if(attackingInfo && !attackingInfo->reversing)
|
||||||
|
@ -151,7 +151,7 @@ struct BattleSettings
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBattleInterface : public CMainInterface, public MotionInterested, public KeyInterested
|
class CBattleInterface : public CMainInterface, public MotionInterested, public KeyInterested, public ClickableR
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
|
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
|
||||||
@ -178,6 +178,7 @@ private:
|
|||||||
bool spellDestSelectMode; //if true, player is choosing destination for his spell
|
bool spellDestSelectMode; //if true, player is choosing destination for his spell
|
||||||
int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle, -1 - no location
|
int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle, -1 - no location
|
||||||
BattleAction * spellToCast; //spell for which player is choosing destination
|
BattleAction * spellToCast; //spell for which player is choosing destination
|
||||||
|
void endCastingSpell(); //ends casting spell (eg. when spell has been casted or cancelled)
|
||||||
|
|
||||||
class CAttHelper
|
class CAttHelper
|
||||||
{
|
{
|
||||||
@ -259,6 +260,8 @@ public:
|
|||||||
void show(SDL_Surface * to);
|
void show(SDL_Surface * to);
|
||||||
void keyPressed(const SDL_KeyboardEvent & key);
|
void keyPressed(const SDL_KeyboardEvent & key);
|
||||||
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
|
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
|
||||||
|
void clickRight(boost::logic::tribool down);
|
||||||
|
|
||||||
bool reverseCreature(int number, int hex, bool wideTrick = false); //reverses animation of given creature playing animation of reversing
|
bool reverseCreature(int number, int hex, bool wideTrick = false); //reverses animation of given creature playing animation of reversing
|
||||||
void handleStartMoving(int number); //animation of starting move; some units don't have this animation (ie. halberdier)
|
void handleStartMoving(int number); //animation of starting move; some units don't have this animation (ie. halberdier)
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ bool CCallback::battleIsStackMine(int ID)
|
|||||||
return gs->curB->stacks[h]->owner == player;
|
return gs->curB->stacks[h]->owner == player;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool CCallback::battleCanShoot(int ID, int dest)
|
bool CCallback::battleCanShoot(int ID, int dest)
|
||||||
{
|
{
|
||||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
@ -570,6 +570,17 @@ bool CCallback::battleCanShoot(int ID, int dest)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCallback::battleCanCastSpell()
|
||||||
|
{
|
||||||
|
if(!gs->curB) //there is no battle
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(gs->curB->side1 == player)
|
||||||
|
return gs->curB->castedSpells[0] == 0 && gs->getHero(gs->curB->hero1)->getArt(17);
|
||||||
|
else
|
||||||
|
return gs->curB->castedSpells[1] == 0 && gs->getHero(gs->curB->hero2)->getArt(17);
|
||||||
|
}
|
||||||
|
|
||||||
void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
||||||
{
|
{
|
||||||
if(town->tempOwner != player) return;
|
if(town->tempOwner != player) return;
|
||||||
|
@ -105,6 +105,7 @@ public:
|
|||||||
virtual std::vector<int> battleGetAvailableHexes(int ID, bool addOccupiable)=0; //reutrns numbers of hexes reachable by creature with id ID
|
virtual std::vector<int> battleGetAvailableHexes(int ID, bool addOccupiable)=0; //reutrns numbers of hexes reachable by creature with id ID
|
||||||
virtual bool battleIsStackMine(int ID)=0; //returns true if stack with id ID belongs to caller
|
virtual bool battleIsStackMine(int ID)=0; //returns true if stack with id ID belongs to caller
|
||||||
virtual bool battleCanShoot(int ID, int dest)=0; //returns true if unit with id ID can shoot to dest
|
virtual bool battleCanShoot(int ID, int dest)=0; //returns true if unit with id ID can shoot to dest
|
||||||
|
virtual bool battleCanCastSpell()=0; //returns true, if caller can cast a spell
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HeroMoveDetails
|
struct HeroMoveDetails
|
||||||
@ -197,7 +198,7 @@ public:
|
|||||||
std::vector<int> battleGetAvailableHexes(int ID, bool addOccupiable); //reutrns numbers of hexes reachable by creature with id ID
|
std::vector<int> battleGetAvailableHexes(int ID, bool addOccupiable); //reutrns numbers of hexes reachable by creature with id ID
|
||||||
bool battleIsStackMine(int ID); //returns true if stack with id ID belongs to caller
|
bool battleIsStackMine(int ID); //returns true if stack with id ID belongs to caller
|
||||||
bool battleCanShoot(int ID, int dest); //returns true if unit with id ID can shoot to dest
|
bool battleCanShoot(int ID, int dest); //returns true if unit with id ID can shoot to dest
|
||||||
|
bool battleCanCastSpell(); //returns true, if caller can cast a spell
|
||||||
|
|
||||||
//XXX hmmm _tmain on _GNUC_ wtf?
|
//XXX hmmm _tmain on _GNUC_ wtf?
|
||||||
//friends
|
//friends
|
||||||
|
@ -107,7 +107,7 @@ struct DLL_EXPORT CObstacleInstance
|
|||||||
|
|
||||||
struct DLL_EXPORT BattleInfo
|
struct DLL_EXPORT BattleInfo
|
||||||
{
|
{
|
||||||
ui8 side1, side2;
|
ui8 side1, side2; //side1 - attacker, side2 - defender
|
||||||
si32 round, activeStack;
|
si32 round, activeStack;
|
||||||
ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle
|
ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle
|
||||||
int3 tile; //for background and bonuses
|
int3 tile; //for background and bonuses
|
||||||
@ -115,7 +115,7 @@ struct DLL_EXPORT BattleInfo
|
|||||||
CCreatureSet army1, army2;
|
CCreatureSet army1, army2;
|
||||||
std::vector<CStack*> stacks;
|
std::vector<CStack*> stacks;
|
||||||
std::vector<CObstacleInstance> obstacles;
|
std::vector<CObstacleInstance> obstacles;
|
||||||
ui8 castedSpells[2];
|
ui8 castedSpells[2]; //[0] - attacker, [1] - defender
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,10 @@ bool CCreature::isShooting() const
|
|||||||
{
|
{
|
||||||
return vstd::contains(abilities,SHOOTER);
|
return vstd::contains(abilities,SHOOTER);
|
||||||
}
|
}
|
||||||
|
bool CCreature::isUndead() const
|
||||||
|
{
|
||||||
|
return vstd::contains(abilities,UNDEAD);
|
||||||
|
}
|
||||||
si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatures can be bought
|
si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatures can be bought
|
||||||
{
|
{
|
||||||
int ret = 2147483645;
|
int ret = 2147483645;
|
||||||
@ -331,6 +335,8 @@ void CCreatureHandler::loadCreatures()
|
|||||||
ncre.abilities.insert(TWICE_ATTACK);
|
ncre.abilities.insert(TWICE_ATTACK);
|
||||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_free_attack"))
|
if(boost::algorithm::find_first(ncre.abilityRefs, "const_free_attack"))
|
||||||
ncre.abilities.insert(NO_ENEMY_RETALIATION);
|
ncre.abilities.insert(NO_ENEMY_RETALIATION);
|
||||||
|
if(boost::algorithm::find_first(ncre.abilityRefs, "IS_UNDEAD"))
|
||||||
|
ncre.abilities.insert(UNDEAD);
|
||||||
if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
|
if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
|
||||||
{
|
{
|
||||||
ncre.idNumber = creatures.size();
|
ncre.idNumber = creatures.size();
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
bool isDoubleWide() const; //returns true if unit is double wide on battlefield
|
bool isDoubleWide() const; //returns true if unit is double wide on battlefield
|
||||||
bool isFlying() const; //returns true if it is a flying unit
|
bool isFlying() const; //returns true if it is a flying unit
|
||||||
bool isShooting() const; //returns true if unit can shoot
|
bool isShooting() const; //returns true if unit can shoot
|
||||||
|
bool isUndead() const; //returns true if unit is undead
|
||||||
si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought
|
si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought
|
||||||
static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion
|
static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion
|
||||||
|
|
||||||
|
@ -519,6 +519,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
|||||||
handleConEnd:
|
handleConEnd:
|
||||||
tlog1 << "Ended handling connection\n";
|
tlog1 << "Ended handling connection\n";
|
||||||
#undef SPELL_CAST_TEMPLATE_1
|
#undef SPELL_CAST_TEMPLATE_1
|
||||||
|
#undef SPELL_CAST_TEMPLATE_2
|
||||||
}
|
}
|
||||||
void CGameHandler::moveStack(int stack, int dest)
|
void CGameHandler::moveStack(int stack, int dest)
|
||||||
{
|
{
|
||||||
@ -2306,6 +2307,28 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
sendAndApply(&sse); \
|
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; \
|
||||||
|
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.stackAttacked = (*it)->ID; \
|
||||||
|
prepareAttacked(bsa,*it); \
|
||||||
|
si.stacks.insert(bsa); \
|
||||||
|
} \
|
||||||
|
sendAndApply(&si); \
|
||||||
|
|
||||||
SpellCasted sc;
|
SpellCasted sc;
|
||||||
sc.side = ba.side;
|
sc.side = ba.side;
|
||||||
sc.id = ba.additionalInfo;
|
sc.id = ba.additionalInfo;
|
||||||
@ -2316,67 +2339,90 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
|||||||
{
|
{
|
||||||
case 15: //magic arrow
|
case 15: //magic arrow
|
||||||
{
|
{
|
||||||
CStack * attacked = gs->curB->getStackT(ba.destinationTile);
|
SPELL_CAST_TEMPLATE_2(64, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||||
if(!attacked) break;
|
|
||||||
BattleStackAttacked bsa;
|
|
||||||
bsa.flags |= 2;
|
|
||||||
bsa.effect = 64;
|
|
||||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)];
|
|
||||||
bsa.stackAttacked = attacked->ID;
|
|
||||||
prepareAttacked(bsa,attacked);
|
|
||||||
sendAndApply(&bsa);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 16: //ice bolt
|
case 16: //ice bolt
|
||||||
{
|
{
|
||||||
CStack * attacked = gs->curB->getStackT(ba.destinationTile);
|
SPELL_CAST_TEMPLATE_2(46, h->getPrimSkillLevel(2) * 20 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||||
if(!attacked) break;
|
|
||||||
BattleStackAttacked bsa;
|
|
||||||
bsa.flags |= 2;
|
|
||||||
bsa.effect = 46;
|
|
||||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 20 + s->powers[h->getSpellSchoolLevel(s)];
|
|
||||||
bsa.stackAttacked = attacked->ID;
|
|
||||||
prepareAttacked(bsa,attacked);
|
|
||||||
sendAndApply(&bsa);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 17: //lightning bolt
|
case 17: //lightning bolt
|
||||||
{
|
{
|
||||||
CStack * attacked = gs->curB->getStackT(ba.destinationTile);
|
SPELL_CAST_TEMPLATE_2(38, h->getPrimSkillLevel(2) * 25 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||||
if(!attacked) break;
|
|
||||||
BattleStackAttacked bsa;
|
|
||||||
bsa.flags |= 2;
|
|
||||||
bsa.effect = 38;
|
|
||||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 25 + s->powers[h->getSpellSchoolLevel(s)];
|
|
||||||
bsa.stackAttacked = attacked->ID;
|
|
||||||
prepareAttacked(bsa,attacked);
|
|
||||||
sendAndApply(&bsa);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 18: //implosion
|
case 18: //implosion
|
||||||
{
|
{
|
||||||
CStack * attacked = gs->curB->getStackT(ba.destinationTile);
|
SPELL_CAST_TEMPLATE_2(10, h->getPrimSkillLevel(2) * 75 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||||
if(!attacked) break;
|
break;
|
||||||
BattleStackAttacked bsa;
|
}
|
||||||
bsa.flags |= 2;
|
case 20: //frost ring
|
||||||
bsa.effect = 10;
|
{
|
||||||
bsa.damageAmount = h->getPrimSkillLevel(2) * 75 + s->powers[h->getSpellSchoolLevel(s)];
|
SPELL_CAST_TEMPLATE_2(45, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||||
bsa.stackAttacked = attacked->ID;
|
|
||||||
prepareAttacked(bsa,attacked);
|
|
||||||
sendAndApply(&bsa);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 21: //fireball
|
case 21: //fireball
|
||||||
{
|
{
|
||||||
std::set<ui16> attackedHexes = s->rangeInHexes(ba.destinationTile, h->getSpellSchoolLevel(s));
|
SPELL_CAST_TEMPLATE_2(53, h->getPrimSkillLevel(2) * 10 + s->powers[h->getSpellSchoolLevel(s)]);
|
||||||
std::set<CStack*> attackedCres; //set to exclude multiple occurences of two hex creatures
|
break;
|
||||||
for(std::set<ui16>::iterator it = attackedHexes.begin(); it != attackedHexes.end(); ++it)
|
}
|
||||||
|
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)]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24: //death ripple
|
||||||
|
{
|
||||||
|
std::set<CStack*> attackedCres;
|
||||||
|
|
||||||
|
for(int it=0; it<gs->curB->stacks.size(); ++it)
|
||||||
{
|
{
|
||||||
attackedCres.insert(gs->curB->getStackT(*it));
|
if(!gs->curB->stacks[it]->creature->isUndead())
|
||||||
|
attackedCres.insert(gs->curB->stacks[it]);
|
||||||
}
|
}
|
||||||
|
if(attackedCres.size() == 0) break;
|
||||||
if(attackedCres.size()) break;
|
StacksInjured si;
|
||||||
//TODO: the rest of it
|
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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 25: //destroy undead
|
||||||
|
{
|
||||||
|
std::set<CStack*> attackedCres;
|
||||||
|
|
||||||
|
for(int it=0; it<gs->curB->stacks.size(); ++it)
|
||||||
|
{
|
||||||
|
if(gs->curB->stacks[it]->creature->isUndead())
|
||||||
|
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);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 27: //shield
|
case 27: //shield
|
||||||
|
Loading…
Reference in New Issue
Block a user