Bläddra i källkod

Try to handle queries by ai

nordsoft 3 år sedan
förälder
incheckning
e9cf3ede2a
6 ändrade filer med 66 tillägg och 41 borttagningar
  1. 3 0
      AI/Nullkiller/AIGateway.cpp
  2. 3 0
      AI/VCAI/VCAI.cpp
  3. 20 0
      lib/NetPacks.h
  4. 18 11
      lib/NetPacksLib.cpp
  5. 1 0
      lib/registerTypes/RegisterTypes.h
  6. 21 30
      server/CGameHandler.cpp

+ 3 - 0
AI/Nullkiller/AIGateway.cpp

@@ -1075,6 +1075,9 @@ void AIGateway::battleEnd(const BattleResult * br, QueryID queryID)
 	bool won = br->winner == myCb->battleGetMySide();
 	logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
 	battlename.clear();
+	status.addQuery(queryID, "Combat result dialog");
+	answerQuery(queryID, 0);
+	status.removeQuery(queryID); //do not wait for answer
 	CAdventureAI::battleEnd(br, queryID);
 }
 

+ 3 - 0
AI/VCAI/VCAI.cpp

@@ -1591,6 +1591,9 @@ void VCAI::battleEnd(const BattleResult * br, QueryID queryID)
 	bool won = br->winner == myCb->battleGetMySide();
 	logAi->debug("Player %d (%s): I %s the %s!", playerID, playerID.getStr(), (won ? "won" : "lost"), battlename);
 	battlename.clear();
+	status.addQuery(queryID, "Combat result dialog");
+	answerQuery(queryID, 0);
+	status.removeQuery(queryID); //do not wait for answer
 	CAdventureAI::battleEnd(br, queryID);
 }
 

+ 20 - 0
lib/NetPacks.h

@@ -1434,6 +1434,26 @@ struct BattleSetActiveStack : public CPackForClient
 	}
 };
 
+struct BattleResultAccepted : public CPackForClient
+{
+	void applyGs(CGameState * gs);
+	
+	CGHeroInstance * hero1 = nullptr;
+	CGHeroInstance * hero2 = nullptr;
+	CArmedInstance * army1 = nullptr;
+	CArmedInstance * army2 = nullptr;
+	TExpType exp[2];
+	
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & hero1;
+		h & hero2;
+		h & army1;
+		h & army2;
+		h & exp;
+	}
+};
+
 struct BattleResult : public Query
 {
 	enum EResult {NORMAL = 0, ESCAPE = 1, SURRENDER = 2};

+ 18 - 11
lib/NetPacksLib.cpp

@@ -1390,10 +1390,17 @@ void BattleResult::applyGs(CGameState *gs)
 	for (auto & elem : gs->curB->stacks)
 		delete elem;
 
+	for(int i = 0; i < 2; i++)
+		gs->curB->battleGetArmyObject(i)->battle = nullptr;
+
+	gs->curB.dellNull();
+}
 
-	for(int i = 0; i < 2; ++i)
+void BattleResultAccepted::applyGs(CGameState * gs)
+{
+	for(auto * h : {hero1, hero2})
 	{
-		if(auto h = gs->curB->battleGetFightingHero(i))
+		if(h)
 		{
 			h->removeBonusesRecursive(Bonus::OneBattle); 	//remove any "until next battle" bonuses
 			if (h->commander && h->commander->alive)
@@ -1405,20 +1412,20 @@ void BattleResult::applyGs(CGameState *gs)
 			}
 		}
 	}
-
+	
 	if(VLC->modh->modules.STACK_EXP)
 	{
 		for(int i = 0; i < 2; i++)
+		{
 			if(exp[i])
-				gs->curB->battleGetArmyObject(i)->giveStackExp(exp[i]);
-
+			{
+				if(auto * army = (i == 0 ? army1 : army2))
+					army->giveStackExp(exp[i]);
+			}
+		}
+		
 		CBonusSystemNode::treeHasChanged();
-	}
-
-	for(int i = 0; i < 2; i++)
-		gs->curB->battleGetArmyObject(i)->battle = nullptr;
-
-	gs->curB.dellNull();
+	}	
 }
 
 DLL_LINKAGE void BattleLogMessage::applyGs(CGameState *gs)

+ 1 - 0
lib/registerTypes/RegisterTypes.h

@@ -280,6 +280,7 @@ void registerTypesClientPacks2(Serializer &s)
 	s.template registerType<CPackForClient, BattleNextRound>();
 	s.template registerType<CPackForClient, BattleSetActiveStack>();
 	s.template registerType<CPackForClient, BattleResult>();
+	s.template registerType<CPackForClient, BattleResultAccepted>();
 	s.template registerType<CPackForClient, BattleLogMessage>();
 	s.template registerType<CPackForClient, BattleStackMoved>();
 	s.template registerType<CPackForClient, BattleAttack>();

+ 21 - 30
server/CGameHandler.cpp

@@ -703,25 +703,14 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
 		battleResult.data->exp[0] = heroAttacker->calculateXp(battleResult.data->exp[0]);//scholar skill
 	if(heroDefender)
 		battleResult.data->exp[1] = heroDefender->calculateXp(battleResult.data->exp[1]);
-	
-	auto findBattleQuery = [this]() -> std::shared_ptr<CBattleQuery>
-	{
-		for (auto &q : queries.allQueries())
-		{
-			if (auto bq = std::dynamic_pointer_cast<CBattleQuery>(q))
-				if (bq->bi == gs->curB)
-					return bq;
-		}
-		return std::shared_ptr<CBattleQuery>();
-	};
 
-	auto battleQuery = findBattleQuery();
+	auto battleQuery = std::dynamic_pointer_cast<CBattleQuery>(queries.topQuery(gs->curB->sides[0].color));
 	if (!battleQuery)
 	{
 		logGlobal->error("Cannot find battle query!");
+		complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0].color) + " has no battle query at the top!");
+		return;
 	}
-	if (battleQuery != queries.topQuery(gs->curB->sides[0].color))
-		complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0].color) + " although in battle has no battle query at the top!");
 
 	battleQuery->result = boost::make_optional(*battleResult.data);
 
@@ -737,24 +726,13 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
 
 void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
 {
-	auto findBattleQuery = [this, battleInfo]() -> std::shared_ptr<CBattleQuery>
-	{
-		for (auto &q : queries.allQueries())
-		{
-			if (auto bq = std::dynamic_pointer_cast<CBattleQuery>(q))
-				if (bq->bi == battleInfo)
-					return bq;
-		}
-		return std::shared_ptr<CBattleQuery>();
-	};
-	
-	auto battleQuery = findBattleQuery();
-	if (!battleQuery)
+	auto battleQuery = std::dynamic_pointer_cast<CBattleQuery>(queries.topQuery(battleInfo->sides.at(0).color));
+	if(!battleQuery)
 	{
 		logGlobal->error("Cannot find battle query!");
+		complain("Player " + boost::lexical_cast<std::string>(battleInfo->sides.at(0).color) + " has no battle query at the top!");
+		return;
 	}
-	if (battleQuery != queries.topQuery(battleInfo->sides[0].color))
-		complain("Player " + boost::lexical_cast<std::string>(battleInfo->sides[0].color) + " although in battle has no battle query at the top!");
 	
 	const CArmedInstance *bEndArmy1 = battleInfo->sides.at(0).armyObject;
 	const CArmedInstance *bEndArmy2 = battleInfo->sides.at(1).armyObject;
@@ -926,6 +904,15 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
 		changePrimSkill(finishingBattle->winnerHero, PrimarySkill::EXPERIENCE, battleResult.data->exp[finishingBattle->winnerSide]);
 	
 	queries.popIfTop(battleQuery);
+	
+	BattleResultAccepted raccepted;
+	raccepted.army1 = const_cast<CArmedInstance*>(bEndArmy1);
+	raccepted.army2 = const_cast<CArmedInstance*>(bEndArmy2);
+	raccepted.hero1 = const_cast<CGHeroInstance*>(battleInfo->sides.at(0).hero);
+	raccepted.hero2 = const_cast<CGHeroInstance*>(battleInfo->sides.at(1).hero);
+	raccepted.exp[0] = battleResult.data->exp[0];
+	raccepted.exp[1] = battleResult.data->exp[1];
+	sendAndApply(&raccepted);
 
 	//--> continuation (battleAfterLevelUp) occurs after level-up queries are handled or on removing query (above)
 }
@@ -934,7 +921,9 @@ void CGameHandler::battleAfterLevelUp(const BattleResult &result)
 {
 	LOG_TRACE(logGlobal);
 
-
+	if(!finishingBattle)
+		return;
+	
 	finishingBattle->remainingBattleQueriesCount--;
 	logGlobal->trace("Decremented queries count to %d", finishingBattle->remainingBattleQueriesCount);
 
@@ -1016,6 +1005,8 @@ void CGameHandler::battleAfterLevelUp(const BattleResult &result)
 			sendAndApply(&sah);
 		}
 	}
+	
+	finishingBattle.reset();
 }
 
 void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender, int distance, BattleHex targetHex, bool first, bool ranged, bool counter)