1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- Fixed wrong creature teleported

- Support for Sacrifice
This commit is contained in:
DjWarmonger 2012-04-28 19:40:27 +00:00
parent f5e47474c5
commit 25bdcd3cab
8 changed files with 68 additions and 25 deletions

View File

@ -92,7 +92,7 @@ void CBattleInterface::addNewAnim(CBattleAnimation * anim)
CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen) CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen)
: queue(NULL), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), : queue(NULL), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
activeStack(NULL), stackToActivate(NULL), mouseHoveredStack(-1), lastMouseHoveredStackAnimationTime(-1), previouslyHoveredHex(-1), activeStack(NULL), stackToActivate(NULL), selectedStack(NULL), mouseHoveredStack(-1), lastMouseHoveredStackAnimationTime(-1), previouslyHoveredHex(-1),
currentlyHoveredHex(-1), attackingHex(-1), tacticianInterface(NULL), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(NULL), sp(NULL), currentlyHoveredHex(-1), attackingHex(-1), tacticianInterface(NULL), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(NULL), sp(NULL),
siegeH(NULL), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0), bfield(GameConstants::BFIELD_SIZE), siegeH(NULL), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0), bfield(GameConstants::BFIELD_SIZE),
givenCommand(NULL), myTurn(false), resWindow(NULL), moveStarted(false), moveSh(-1), bresult(NULL) givenCommand(NULL), myTurn(false), resWindow(NULL), moveStarted(false), moveSh(-1), bresult(NULL)
@ -1385,7 +1385,7 @@ void CBattleInterface::newRound(int number)
} }
void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stackID, si32 additional) void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stackID, si32 additional, si32 selected)
{ {
const CStack *stack = curInt->cb->battleGetStackByID(stackID); const CStack *stack = curInt->cb->battleGetStackByID(stackID);
if(!stack && action != BattleAction::HERO_SPELL && action != BattleAction::RETREAT && action != BattleAction::SURRENDER) if(!stack && action != BattleAction::HERO_SPELL && action != BattleAction::RETREAT && action != BattleAction::SURRENDER)
@ -1402,6 +1402,7 @@ void CBattleInterface::giveCommand(ui8 action, BattleHex tile, ui32 stackID, si3
ba->destinationTile = tile; ba->destinationTile = tile;
ba->stackNumber = stackID; ba->stackNumber = stackID;
ba->additionalInfo = additional; ba->additionalInfo = additional;
ba->selectedStack = selected;
//some basic validations //some basic validations
switch(action) switch(action)
@ -1591,6 +1592,7 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
case Spells::RESURRECTION: case Spells::RESURRECTION:
case Spells::ANIMATE_DEAD: case Spells::ANIMATE_DEAD:
case Spells::DISPEL_HELPFUL_SPELLS: case Spells::DISPEL_HELPFUL_SPELLS:
case Spells::SACRIFICE: //TODO: animation upon killed stack
for(std::set<ui32>::const_iterator it = sc->affectedCres.begin(); it != sc->affectedCres.end(); ++it) for(std::set<ui32>::const_iterator it = sc->affectedCres.begin(); it != sc->affectedCres.end(); ++it)
{ {
displayEffect(spell.mainEffectAnim, curInt->cb->battleGetStackByID(*it, false)->position); displayEffect(spell.mainEffectAnim, curInt->cb->battleGetStackByID(*it, false)->position);
@ -1600,10 +1602,10 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
case Spells::SUMMON_EARTH_ELEMENTAL: case Spells::SUMMON_EARTH_ELEMENTAL:
case Spells::SUMMON_WATER_ELEMENTAL: case Spells::SUMMON_WATER_ELEMENTAL:
case Spells::SUMMON_AIR_ELEMENTAL: case Spells::SUMMON_AIR_ELEMENTAL:
case Spells::CLONE: //TODO: make it smarter? case Spells::CLONE:
case Spells::REMOVE_OBSTACLE: case Spells::REMOVE_OBSTACLE:
case Spells::CHAIN_LIGHTNING: case Spells::CHAIN_LIGHTNING:
addNewAnim(new CDummyAnimation(this, 2)); addNewAnim(new CDummyAnimation(this, 2)); //interface won't return until animation is played. TODO: make it smarter?
break; break;
} //switch(sc->id) } //switch(sc->id)
@ -2744,7 +2746,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
legalAction = true; legalAction = true;
break; break;
case RISING_SPELL: case RISING_SPELL:
if (shere && shere->canBeHealed() && isCastingPossibleHere (sactive, shere, myNumber)) //TODO: at least one stack has to be raised by resurrection / animate dead if (shere && shere->canBeHealed() && ourStack && isCastingPossibleHere (sactive, shere, myNumber)) //TODO: at least one stack has to be raised by resurrection / animate dead
legalAction = true; legalAction = true;
break; break;
case RANDOM_GENIE_SPELL: case RANDOM_GENIE_SPELL:
@ -2771,13 +2773,17 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
else else
skill = getActiveHero()->getSpellSchoolLevel (CGI->spellh->spells[spellToCast->additionalInfo]); skill = getActiveHero()->getSpellSchoolLevel (CGI->spellh->spells[spellToCast->additionalInfo]);
//TODO: explicitely save power, skill //TODO: explicitely save power, skill
if (curInt->cb->battleCanTeleportTo(activeStack, myNumber, skill)) if (curInt->cb->battleCanTeleportTo(selectedStack, myNumber, skill))
legalAction = true; legalAction = true;
else else
notLegal = true; notLegal = true;
} }
break; break;
case SACRIFICE: //TODO case SACRIFICE: //choose our living stack to sacrifice
if (shere && shere != selectedStack && ourStack && shere->alive())
legalAction = true;
else
notLegal = true;
break; break;
case CATAPULT: case CATAPULT:
if (isCatapultAttackable(myNumber)) if (isCatapultAttackable(myNumber))
@ -2899,8 +2905,9 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % sp->name % shere->getName()); //Cast %s on %s consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % sp->name % shere->getName()); //Cast %s on %s
switch (sp->id) switch (sp->id)
{ {
case Spells::TELEPORT:
case Spells::SACRIFICE: case Spells::SACRIFICE:
case Spells::TELEPORT:
selectedStack = shere; //remember firts target
secondaryTarget = true; secondaryTarget = true;
break; break;
} }
@ -2919,6 +2926,12 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
consoleMsg = CGI->generaltexth->allTexts[550]; consoleMsg = CGI->generaltexth->allTexts[550];
isCastingPossible = true; isCastingPossible = true;
break; break;
case SACRIFICE:
cursorFrame = ECursor::COMBAT_SACRIFICE;
consoleMsg = (boost::format(CGI->generaltexth->allTexts[549]) % shere->getName()).str(); //sacrifice the %s
spellToCast->selectedStack = shere->ID; //sacrificed creature is selected
isCastingPossible = true;
break;
case HEAL: case HEAL:
cursorFrame = ECursor::COMBAT_HEAL; cursorFrame = ECursor::COMBAT_HEAL;
consoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s consoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s
@ -2970,6 +2983,9 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
case TELEPORT: case TELEPORT:
consoleMsg = CGI->generaltexth->allTexts[24]; //Invalid Teleport Destination consoleMsg = CGI->generaltexth->allTexts[24]; //Invalid Teleport Destination
break; break;
case SACRIFICE:
consoleMsg = CGI->generaltexth->allTexts[543]; //choose army to sacrifice
break;
default: default:
cursorFrame = ECursor::COMBAT_BLOCKED; cursorFrame = ECursor::COMBAT_BLOCKED;
break; break;
@ -2992,6 +3008,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
{ {
case Spells::TELEPORT: //don't cast spell yet, only select target case Spells::TELEPORT: //don't cast spell yet, only select target
possibleActions.push_back (TELEPORT); possibleActions.push_back (TELEPORT);
spellToCast->selectedStack = selectedStack->ID;
break; break;
case Spells::SACRIFICE: case Spells::SACRIFICE:
possibleActions.push_back (SACRIFICE); possibleActions.push_back (SACRIFICE);
@ -3013,10 +3030,19 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
} }
else else
{ {
spellToCast->destinationTile = myNumber; switch (sp->id)
{
case Spells::SACRIFICE:
spellToCast->destinationTile = selectedStack->position; //cast on first creature that will be resurrected
break;
default:
spellToCast->destinationTile = myNumber;
break;
}
curInt->cb->battleMakeAction(spellToCast); curInt->cb->battleMakeAction(spellToCast);
endCastingSpell(); endCastingSpell();
} }
selectedStack = NULL;
} }
}; };
} }

View File

@ -116,6 +116,7 @@ private:
ui8 animCount; ui8 animCount;
const CStack * activeStack; //number of active stack; NULL - no one const CStack * activeStack; //number of active stack; NULL - no one
const CStack * stackToActivate; //when animation is playing, we should wait till the end to make the next stack active; NULL of none const CStack * stackToActivate; //when animation is playing, we should wait till the end to make the next stack active; NULL of none
const CStack * selectedStack; //for Teleport / Sacrifice
void activateStack(); //sets activeStack to stackToActivate etc. void activateStack(); //sets activeStack to stackToActivate etc.
int mouseHoveredStack; //stack hovered by mouse; if -1 -> none int mouseHoveredStack; //stack hovered by mouse; if -1 -> none
time_t lastMouseHoveredStackAnimationTime; // time when last mouse hovered animation occurred time_t lastMouseHoveredStackAnimationTime; // time when last mouse hovered animation occurred
@ -157,7 +158,7 @@ private:
std::list<ProjectileInfo> projectiles; //projectiles flying on battlefield std::list<ProjectileInfo> projectiles; //projectiles flying on battlefield
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
void giveCommand(ui8 action, BattleHex tile, ui32 stackID, si32 additional=-1); void giveCommand(ui8 action, BattleHex tile, ui32 stackID, si32 additional=-1, si32 selectedStack = -1);
bool isTileAttackable(const BattleHex & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles bool isTileAttackable(const BattleHex & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
bool isCatapultAttackable(BattleHex hex) const; //returns true if given tile can be attacked by catapult bool isCatapultAttackable(BattleHex hex) const; //returns true if given tile can be attacked by catapult

View File

@ -48,7 +48,7 @@
{ "id": 37, "effect": 1, "anim": 39, "ranges": [ "0", "0", "0", "0" ] }, { "id": 37, "effect": 1, "anim": 39, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 38, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] }, { "id": 38, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 39, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] }, { "id": 39, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 40, "effect": 1, "anim": -1, "ranges": [ "0", "0", "0", "0" ] }, { "id": 40, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] },
{ "id": 41, "effect": 1, "anim": 36, "ranges": [ "0", "0", "0", "X" ] }, { "id": 41, "effect": 1, "anim": 36, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 42, "effect": -1, "anim": 40, "ranges": [ "0", "0", "0", "X" ] }, { "id": 42, "effect": -1, "anim": 40, "ranges": [ "0", "0", "0", "X" ] },
{ "id": 43, "effect": 1, "anim": 4, "ranges": [ "0", "0", "0", "X" ] }, { "id": 43, "effect": 1, "anim": 4, "ranges": [ "0", "0", "0", "X" ] },

View File

@ -28,9 +28,11 @@ struct DLL_LINKAGE BattleAction
si8 actionType; //use ActionType enum for values si8 actionType; //use ActionType enum for values
BattleHex destinationTile; BattleHex destinationTile;
si32 additionalInfo; // e.g. spell number if type is 1 || 10; tile to attack if type is 6 si32 additionalInfo; // e.g. spell number if type is 1 || 10; tile to attack if type is 6
si32 selectedStack; //spell subject for teleport / sacrifice
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & side & stackNumber & actionType & destinationTile & additionalInfo; h & side & stackNumber & actionType & destinationTile & additionalInfo & selectedStack;
} }
BattleAction(); BattleAction();

View File

@ -1168,10 +1168,14 @@ ui32 BattleInfo::calculateSpellDmg( const CSpell * sp, const CGHeroInstance * ca
return ret; return ret;
} }
ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack) const ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack) const
{ {
bool resurrect = resurrects(spell->id); bool resurrect = resurrects(spell->id);
int healedHealth = caster->getPrimSkillLevel(2) * spell->power + spell->powers[caster->getSpellSchoolLevel(spell)]; int healedHealth;
if (spell->id == Spells::SACRIFICE && sacrificedStack)
healedHealth = (caster->getPrimSkillLevel(2) + sacrificedStack->MaxHealth() + spell->powers[caster->getSpellSchoolLevel(spell)]) * sacrificedStack->count;
else
healedHealth = caster->getPrimSkillLevel(2) * spell->power + spell->powers[caster->getSpellSchoolLevel(spell)];
healedHealth = calculateSpellBonus(healedHealth, spell, caster, stack); healedHealth = calculateSpellBonus(healedHealth, spell, caster, stack);
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0)); return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
} }
@ -2127,16 +2131,16 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int
//get dead stack if we cast resurrection or animate dead //get dead stack if we cast resurrection or animate dead
const CStack *deadStack = getStackIf([dest](const CStack *s) { return !s->alive() && s->position == dest; }); const CStack *deadStack = getStackIf([dest](const CStack *s) { return !s->alive() && s->position == dest; });
const CStack *aliveStack = getStackIf([dest](const CStack *s) { return s->alive() && s->position == dest; }); const CStack *aliveStack = getStackIf([dest](const CStack *s) { return s->alive() && s->position == dest;});
if(spell->isRisingSpell()) if(spell->isRisingSpell())
{ {
if(!deadStack || aliveStack) if(!deadStack && !aliveStack)
return ESpellCastProblem::NO_APPROPRIATE_TARGET; return ESpellCastProblem::NO_APPROPRIATE_TARGET;
if(spell->id == Spells::ANIMATE_DEAD && !deadStack->hasBonusOfType(Bonus::UNDEAD)) if(spell->id == Spells::ANIMATE_DEAD && !deadStack->hasBonusOfType(Bonus::UNDEAD))
return ESpellCastProblem::NO_APPROPRIATE_TARGET; return ESpellCastProblem::NO_APPROPRIATE_TARGET;
if(deadStack->owner != player) //you can resurrect only your own stacks if(deadStack && deadStack->owner != player) //you can resurrect only your own stacks //FIXME: it includes alive stacks as well
return ESpellCastProblem::NO_APPROPRIATE_TARGET; return ESpellCastProblem::NO_APPROPRIATE_TARGET;
} }
else if(spell->getTargetType() == CSpell::CREATURE || spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE) else if(spell->getTargetType() == CSpell::CREATURE || spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE)

View File

@ -52,7 +52,7 @@ struct DLL_LINKAGE AttackableTiles
struct DLL_LINKAGE BattleInfo : public CBonusSystemNode struct DLL_LINKAGE BattleInfo : public CBonusSystemNode
{ {
ui8 sides[2]; //sides[0] - attacker, sides[1] - defender ui8 sides[2]; //sides[0] - attacker, sides[1] - defender
si32 round, activeStack; si32 round, activeStack, selectedStack;
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
const CGTownInstance * town; //used during town siege - id of attacked town; -1 if not town defence const CGTownInstance * town; //used during town siege - id of attacked town; -1 if not town defence
int3 tile; //for background and bonuses int3 tile; //for background and bonuses
@ -71,7 +71,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & sides & round & activeStack & siege & town & tile & stacks & belligerents & obstacles h & sides & round & activeStack & selectedStack & siege & town & tile & stacks & belligerents & obstacles
& castSpells & si & battlefieldType; & castSpells & si & battlefieldType;
h & heroes; h & heroes;
h & usedSpellsHistory & enchanterCounter; h & usedSpellsHistory & enchanterCounter;
@ -120,7 +120,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode
std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex) std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex)
ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const; ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const;
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack) const; ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = NULL) const;
ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel
ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //unused ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //unused
bool resurrects(TSpell spellid) const; //TODO: move it to spellHandler? bool resurrects(TSpell spellid) const; //TODO: move it to spellHandler?

View File

@ -3509,7 +3509,8 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
} }
} }
void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero, int usedSpellPower, ECastingMode::ECastingMode mode, const CStack * stack) void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
int usedSpellPower, ECastingMode::ECastingMode mode, const CStack * stack, si32 selectedStack)
{ {
const CSpell *spell = VLC->spellh->spells[spellID]; const CSpell *spell = VLC->spellh->spells[spellID];
@ -3765,7 +3766,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
{ {
BattleStackMoved bsm; BattleStackMoved bsm;
bsm.distance = -1; bsm.distance = -1;
bsm.stack = gs->curB->activeStack; bsm.stack = selectedStack;
std::vector<BattleHex> tiles; std::vector<BattleHex> tiles;
tiles.push_back(destination); tiles.push_back(destination);
bsm.tilesToMove = tiles; bsm.tilesToMove = tiles;
@ -3776,6 +3777,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
case Spells::CURE: case Spells::CURE:
case Spells::RESURRECTION: case Spells::RESURRECTION:
case Spells::ANIMATE_DEAD: case Spells::ANIMATE_DEAD:
case Spells::SACRIFICE:
{ {
int hpGained = 0; int hpGained = 0;
if (stack) if (stack)
@ -3807,12 +3809,18 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
hi.healedHP = gs->curB->calculateHealedHP(spell, usedSpellPower, spellLvl, *it); hi.healedHP = gs->curB->calculateHealedHP(spell, usedSpellPower, spellLvl, *it);
} }
else else
hi.healedHP = gs->curB->calculateHealedHP(caster, spell, *it); hi.healedHP = gs->curB->calculateHealedHP(caster, spell, *it, gs->curB->getStack(selectedStack));
hi.lowLevelResurrection = spellLvl <= 1; hi.lowLevelResurrection = spellLvl <= 1;
shr.healedStacks.push_back(hi); shr.healedStacks.push_back(hi);
} }
if(!shr.healedStacks.empty()) if(!shr.healedStacks.empty())
sendAndApply(&shr); sendAndApply(&shr);
if (spellID == Spells::SACRIFICE) //remove victim
{
BattleStacksRemoved bsr;
bsr.stackIDs.insert (selectedStack); //somehow it works for teleport?
sendAndApply(&bsr);
}
break; break;
} }
case Spells::SUMMON_FIRE_ELEMENTAL: case Spells::SUMMON_FIRE_ELEMENTAL:
@ -4013,7 +4021,8 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
StartAction start_action(ba); StartAction start_action(ba);
sendAndApply(&start_action); //start spell casting sendAndApply(&start_action); //start spell casting
handleSpellCasting (ba.additionalInfo, skill, ba.destinationTile, ba.side, h->tempOwner, h, secondHero, h->getPrimSkillLevel(2), ECastingMode::HERO_CASTING, NULL); handleSpellCasting (ba.additionalInfo, skill, ba.destinationTile, ba.side, h->tempOwner, h, secondHero, h->getPrimSkillLevel(2),
ECastingMode::HERO_CASTING, NULL, ba.selectedStack);
sendAndApply(&end_action); sendAndApply(&end_action);
if( !gs->curB->getStack(gs->curB->activeStack, false)->alive() ) if( !gs->curB->getStack(gs->curB->activeStack, false)->alive() )

View File

@ -193,7 +193,8 @@ public:
void playerMessage( ui8 player, const std::string &message); void playerMessage( ui8 player, const std::string &message);
bool makeBattleAction(BattleAction &ba); bool makeBattleAction(BattleAction &ba);
void handleSpellCasting(int spellID, int spellLvl, BattleHex destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero, int usedSpellPower, ECastingMode::ECastingMode mode, const CStack * stack); void handleSpellCasting(int spellID, int spellLvl, BattleHex destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero,
int usedSpellPower, ECastingMode::ECastingMode mode, const CStack * stack, si32 selectedStack = -1);
bool makeCustomAction(BattleAction &ba); bool makeCustomAction(BattleAction &ba);
void stackTurnTrigger(const CStack * stack); void stackTurnTrigger(const CStack * stack);
bool queryReply( ui32 qid, ui32 answer, ui8 player ); bool queryReply( ui32 qid, ui32 answer, ui8 player );