浏览代码

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

Michał W. Urbańczyk 12 年之前
父节点
当前提交
5c6d12400f
共有 4 个文件被更改,包括 30 次插入15 次删除
  1. 1 1
      AI/BattleAI/BattleAI.cpp
  2. 25 0
      lib/CBattleCallback.cpp
  3. 2 0
      lib/CBattleCallback.h
  4. 2 14
      server/CGameHandler.cpp

+ 1 - 1
AI/BattleAI/BattleAI.cpp

@@ -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 )

+ 25 - 0
lib/CBattleCallback.cpp

@@ -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);

+ 2 - 0
lib/CBattleCallback.h

@@ -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;

+ 2 - 14
server/CGameHandler.cpp

@@ -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(stack->alive() && !stack->hasBonusOfType(Bonus::SIEGE_WEAPON))
-		{
-			hasStack[1-stack->attackerOwned] = true;
-		}
-	}
-	if(!hasStack[0] || !hasStack[1]) //somebody has won
+	if(auto result = battleIsFinished())
 	{
-		setBattleResult(BattleResult::NORMAL, hasStack[1]);
+		setBattleResult(BattleResult::NORMAL, *result);
 	}
 }