1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Fixed crashes when clone dies #1357, #1441.

This commit is contained in:
DjWarmonger 2013-09-08 17:43:10 +00:00
parent e13dc872e0
commit 99352a7220
5 changed files with 26 additions and 7 deletions

View File

@ -1201,7 +1201,7 @@ bool CStack::isMeleeAttackPossible(const CStack * attacker, const CStack * defen
} }
bool CStack::ableToRetaliate() const bool CStack::ableToRetaliate() const //FIXME: crash after clone is killed
{ {
return alive() return alive()
&& (counterAttacks > 0 || hasBonusOfType(Bonus::UNLIMITED_RETALIATIONS)) && (counterAttacks > 0 || hasBonusOfType(Bonus::UNLIMITED_RETALIATIONS))

View File

@ -264,6 +264,10 @@ public:
{ {
return vstd::contains(state,EBattleStackState::ALIVE); return vstd::contains(state,EBattleStackState::ALIVE);
} }
bool idDeadClone() const //determines if stack is alive
{
return vstd::contains(state,EBattleStackState::DEAD_CLONE);
}
bool isValidTarget(bool allowDead = false) const; //alive non-turret stacks (can be attacked or be object of magic effect) bool isValidTarget(bool allowDead = false) const; //alive non-turret stacks (can be attacked or be object of magic effect)
}; };

View File

@ -429,7 +429,7 @@ namespace EMarketMode
namespace EBattleStackState namespace EBattleStackState
{ {
enum EBattleStackState{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING, FEAR, enum EBattleStackState{ALIVE = 180, SUMMONED, CLONED, DEAD_CLONE, HAD_MORALE, WAITING, MOVED, DEFENDING, FEAR,
DRAINED_MANA /*remember to drain mana only once per turn*/}; DRAINED_MANA /*remember to drain mana only once per turn*/};
} }

View File

@ -1185,9 +1185,9 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
} }
if (cloneKilled()) if (cloneKilled())
{ {
BattleStacksRemoved bsr; //remove body //"hide" killed creatures instead so we keep info about it
bsr.stackIDs.insert(at->ID); at->state.insert(EBattleStackState::DEAD_CLONE);
bsr.applyGs(gs);
} }
} }

View File

@ -3433,7 +3433,8 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
} }
//counterattack //counterattack
if (!stack->hasBonusOfType(Bonus::BLOCKS_RETALIATION) if (stackAtEnd
&& !stack->hasBonusOfType(Bonus::BLOCKS_RETALIATION)
&& stackAtEnd->ableToRetaliate() && stackAtEnd->ableToRetaliate()
&& stack->alive()) //attacker may have died (fire shield) && stack->alive()) //attacker may have died (fire shield)
{ {
@ -3451,6 +3452,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
moveStack(ba.stackNumber, startingPos); moveStack(ba.stackNumber, startingPos);
//NOTE: curStack->ID == ba.stackNumber (rev 1431) //NOTE: curStack->ID == ba.stackNumber (rev 1431)
} }
sendAndApply(&end_action); sendAndApply(&end_action);
break; break;
} }
@ -3773,7 +3775,6 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
handleSpellCasting(spellID, spellLvl, destination, casterSide, stack->owner, nullptr, secHero, 0, ECastingMode::CREATURE_ACTIVE_CASTING, stack); handleSpellCasting(spellID, spellLvl, destination, casterSide, stack->owner, nullptr, secHero, 0, ECastingMode::CREATURE_ACTIVE_CASTING, stack);
} }
sendAndApply(&end_action); sendAndApply(&end_action);
break; break;
} }
@ -5895,7 +5896,21 @@ void CGameHandler::runBattle()
const BattleInfo & curB = *gs->curB; const BattleInfo & curB = *gs->curB;
//remove clones after all mechanics and animations are handled!
std::set <const CStack*> stacksToRemove;
for (auto stack : curB.stacks)
{
if (stack->idDeadClone())
stacksToRemove.insert(stack);
}
for (auto stack : stacksToRemove)
{
BattleStacksRemoved bsr;
bsr.stackIDs.insert(stack->ID);
sendAndApply(&bsr);
}
//stack loop //stack loop
const CStack *next; const CStack *next;
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove()) while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
{ {