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

Fixed AI detection of battle end (solves some freezes).

This commit is contained in:
Michał W. Urbańczyk 2013-09-29 20:54:29 +00:00
parent 9ee3133077
commit 5c6d12400f
4 changed files with 30 additions and 15 deletions

View File

@ -99,7 +99,7 @@ void CBattleAI::init(shared_ptr<CBattleCallback> CB)
static bool thereRemainsEnemy()
{
return cbc->battleGetStacks(CBattleInfoEssentials::ONLY_ENEMY).size();
return cbc->battleIsFinished();
}
BattleAction CBattleAI::activeStack( const CStack * stack )

View File

@ -2276,6 +2276,31 @@ si8 CBattleInfoCallback::battleMaxSpellLevel() const
return GameConstants::SPELL_LEVELS;
}
boost::optional<int> CBattleInfoCallback::battleIsFinished() const
{
auto &stacks = battleGetAllStacks();
//checking winning condition
bool hasStack[2]; //hasStack[0] - true if attacker has a living stack; defender similarly
hasStack[0] = hasStack[1] = false;
for(auto & stack : stacks)
{
if(stack->alive() && !stack->hasBonusOfType(Bonus::SIEGE_WEAPON))
{
hasStack[1-stack->attackerOwned] = true;
}
}
if(!hasStack[0] && !hasStack[1])
return 2;
if(!hasStack[1])
return 1;
if(!hasStack[0])
return 0;
return boost::none;
}
bool AccessibilityInfo::accessible(BattleHex tile, const CStack *stack) const
{
return accessible(tile, stack->doubleWide(), stack->attackerOwned);

View File

@ -222,6 +222,8 @@ public:
};
//battle
boost::optional<int> battleIsFinished() const; //return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
shared_ptr<const CObstacleInstance> battleGetObstacleOnPos(BattleHex tile, bool onlyBlocking = true) const; //blocking obstacles makes tile inaccessible, others cause special effects (like Land Mines, Moat, Quicksands)
const CStack * battleGetStackByPos(BattleHex pos, bool onlyAlive = true) const; //returns stack info by given pos
void battleGetStackQueue(std::vector<const CStack *> &out, const int howMany, const int turn = 0, int lastMoved = -1) const;

View File

@ -1555,21 +1555,9 @@ void CGameHandler::setupBattle( int3 tile, const CArmedInstance *armies[2], cons
void CGameHandler::checkForBattleEnd()
{
auto &stacks = gs->curB->stacks;
//checking winning condition
bool hasStack[2]; //hasStack[0] - true if attacker has a living stack; defender similarly
hasStack[0] = hasStack[1] = false;
for(auto & stack : stacks)
if(auto result = battleIsFinished())
{
if(stack->alive() && !stack->hasBonusOfType(Bonus::SIEGE_WEAPON))
{
hasStack[1-stack->attackerOwned] = true;
}
}
if(!hasStack[0] || !hasStack[1]) //somebody has won
{
setBattleResult(BattleResult::NORMAL, hasStack[1]);
setBattleResult(BattleResult::NORMAL, *result);
}
}