浏览代码

Fix battle timer logic

nordsoft 2 年之前
父节点
当前提交
0bc2302f1f
共有 3 个文件被更改,包括 55 次插入56 次删除
  1. 2 2
      server/CGameHandler.cpp
  2. 48 50
      server/TurnTimerHandler.cpp
  3. 5 4
      server/TurnTimerHandler.h

+ 2 - 2
server/CGameHandler.cpp

@@ -604,7 +604,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
 void CGameHandler::onPlayerTurnStarted(PlayerColor which)
 {
 	events::PlayerGotTurn::defaultExecute(serverEventBus.get(), which);
-	turnTimerHandler.onPlayerGetTurn(gs->players[which]);
+	turnTimerHandler.onPlayerGetTurn(which);
 }
 
 void CGameHandler::onPlayerTurnEnded(PlayerColor which)
@@ -991,7 +991,7 @@ void CGameHandler::run(bool resume)
 		onNewTurn();
 		events::TurnStarted::defaultExecute(serverEventBus.get());
 		for(auto & player : gs->players)
-			turnTimerHandler.onGameplayStart(player.second);
+			turnTimerHandler.onGameplayStart(player.first);
 	}
 	else
 		events::GameResumed::defaultExecute(serverEventBus.get());

+ 48 - 50
server/TurnTimerHandler.cpp

@@ -26,63 +26,65 @@ TurnTimerHandler::TurnTimerHandler(CGameHandler & gh):
 	
 }
 
-void TurnTimerHandler::onGameplayStart(PlayerState & state)
+void TurnTimerHandler::onGameplayStart(PlayerColor player)
 {
 	if(const auto * si = gameHandler.getStartInfo())
 	{
 		if(si->turnTimerInfo.isEnabled())
 		{
-			state.turnTimer = si->turnTimerInfo;
-			state.turnTimer.turnTimer = 0;
+			timers[player] = si->turnTimerInfo;
+			timers[player].turnTimer = 0;
 		}
 	}
 }
 
-void TurnTimerHandler::onPlayerGetTurn(PlayerState & state)
+void TurnTimerHandler::onPlayerGetTurn(PlayerColor player)
 {
 	if(const auto * si = gameHandler.getStartInfo())
 	{
 		if(si->turnTimerInfo.isEnabled())
 		{
-			state.turnTimer.baseTimer += state.turnTimer.turnTimer;
-			state.turnTimer.turnTimer = si->turnTimerInfo.turnTimer;
+			timers[player].baseTimer += timers[player].turnTimer;
+			timers[player].turnTimer = si->turnTimerInfo.turnTimer;
 			
 			TurnTimeUpdate ttu;
-			ttu.player = state.color;
-			ttu.turnTimer = state.turnTimer;
+			ttu.player = player;
+			ttu.turnTimer = timers[player];
 			gameHandler.sendAndApply(&ttu);
 		}
 	}
 }
 
-void TurnTimerHandler::onPlayerMakingTurn(PlayerState & state, int waitTime)
+void TurnTimerHandler::onPlayerMakingTurn(PlayerColor player, int waitTime)
 {
 	const auto * gs = gameHandler.gameState();
 	const auto * si = gameHandler.getStartInfo();
 	if(!si || !gs)
 		return;
 	
+	auto & state = gs->players.at(player);
+	
 	if(state.human && si->turnTimerInfo.isEnabled() && !gs->curB)
 	{
-		if(state.turnTimer.turnTimer > 0)
+		if(timers[player].turnTimer > 0)
 		{
-			state.turnTimer.turnTimer -= waitTime;
-			int frequency = (state.turnTimer.creatureTimer > turnTimePropagateThreshold ? turnTimePropagateFrequency : turnTimePropagateFrequencyCrit);
+			timers[player].turnTimer -= waitTime;
+			int frequency = (timers[player].turnTimer > turnTimePropagateThreshold ? turnTimePropagateFrequency : turnTimePropagateFrequencyCrit);
 			
 			if(state.status == EPlayerStatus::INGAME //do not send message if player is not active already
-			   && state.turnTimer.turnTimer % frequency == 0)
+			   && timers[player].turnTimer % frequency == 0)
 			{
 				TurnTimeUpdate ttu;
 				ttu.player = state.color;
-				ttu.turnTimer = state.turnTimer;
+				ttu.turnTimer = timers[player];
 				gameHandler.sendAndApply(&ttu);
 			}
 		}
-		else if(state.turnTimer.baseTimer > 0)
+		else if(timers[player].baseTimer > 0)
 		{
-			state.turnTimer.turnTimer = state.turnTimer.baseTimer;
-			state.turnTimer.baseTimer = 0;
-			onPlayerMakingTurn(state, waitTime);
+			timers[player].turnTimer = timers[player].baseTimer;
+			timers[player].baseTimer = 0;
+			onPlayerMakingTurn(player, 0);
 		}
 		else if(!gameHandler.queries->topQuery(state.color)) //wait for replies to avoid pending queries
 			gameHandler.turnOrder->onPlayerEndsTurn(state.color);
@@ -103,12 +105,12 @@ void TurnTimerHandler::onBattleStart()
 	{
 		if(i.isValidPlayer())
 		{
-			const auto & state = gs->players.at(i);
+			timers[i].battleTimer = si->turnTimerInfo.battleTimer;
+			timers[i].creatureTimer = si->turnTimerInfo.creatureTimer;
+			
 			TurnTimeUpdate ttu;
-			ttu.player = state.color;
-			ttu.turnTimer = state.turnTimer;
-			ttu.turnTimer.battleTimer = si->turnTimerInfo.battleTimer;
-			ttu.turnTimer.creatureTimer = si->turnTimerInfo.creatureTimer;
+			ttu.player = i;
+			ttu.turnTimer = timers[i];
 			gameHandler.sendAndApply(&ttu);
 		}
 	}
@@ -118,24 +120,22 @@ void TurnTimerHandler::onBattleNextStack(const CStack & stack)
 {
 	const auto * gs = gameHandler.gameState();
 	const auto * si = gameHandler.getStartInfo();
-	if(!si || !gs || !gs->curB)
-		return;
-	
-	if(!stack.getOwner().isValidPlayer())
+	if(!si || !gs || !gs->curB || !si->turnTimerInfo.isBattleEnabled())
 		return;
 	
-	const auto & state = gs->players.at(stack.getOwner());
+	auto player = stack.getOwner();
 	
-	if(si->turnTimerInfo.isBattleEnabled())
-	{
-		TurnTimeUpdate ttu;
-		ttu.player = state.color;
-		ttu.turnTimer = state.turnTimer;
-		if(state.turnTimer.battleTimer < si->turnTimerInfo.battleTimer)
-			ttu.turnTimer.battleTimer = ttu.turnTimer.creatureTimer;
-		ttu.turnTimer.creatureTimer = si->turnTimerInfo.creatureTimer;
-		gameHandler.sendAndApply(&ttu);
-	}
+	if(!player.isValidPlayer())
+		return;
+		
+	if(timers[player].battleTimer < si->turnTimerInfo.battleTimer)
+		timers[player].battleTimer = timers[player].creatureTimer;
+	timers[player].creatureTimer = si->turnTimerInfo.creatureTimer;
+		
+	TurnTimeUpdate ttu;
+	ttu.player = player;
+	ttu.turnTimer = timers[player];
+	gameHandler.sendAndApply(&ttu);
 }
 
 void TurnTimerHandler::onBattleLoop(int waitTime)
@@ -151,20 +151,19 @@ void TurnTimerHandler::onBattleLoop(int waitTime)
 	
 	auto & state = gs->players.at(gs->curB->getSidePlayer(stack->unitSide()));
 	
-	auto turnTimerUpdateApplier = [&](const TurnTimerInfo & tTimer)
+	auto turnTimerUpdateApplier = [&](TurnTimerInfo & tTimer, int waitTime)
 	{
-		TurnTimerInfo turnTimerUpdate = tTimer;
 		if(tTimer.creatureTimer > 0)
 		{
-			turnTimerUpdate.creatureTimer -= waitTime;
-			int frequency = (turnTimerUpdate.creatureTimer > turnTimePropagateThreshold ? turnTimePropagateFrequency : turnTimePropagateFrequencyCrit);
+			tTimer.creatureTimer -= waitTime;
+			int frequency = (tTimer.creatureTimer > turnTimePropagateThreshold ? turnTimePropagateFrequency : turnTimePropagateFrequencyCrit);
 			
 			if(state.status == EPlayerStatus::INGAME //do not send message if player is not active already
-			   && turnTimerUpdate.creatureTimer % frequency == 0)
+			   && tTimer.creatureTimer % frequency == 0)
 			{
 				TurnTimeUpdate ttu;
 				ttu.player = state.color;
-				ttu.turnTimer = turnTimerUpdate;
+				ttu.turnTimer = tTimer;
 				gameHandler.sendAndApply(&ttu);
 			}
 			return true;
@@ -174,14 +173,13 @@ void TurnTimerHandler::onBattleLoop(int waitTime)
 	
 	if(state.human && si->turnTimerInfo.isBattleEnabled())
 	{
-		TurnTimerInfo turnTimer = state.turnTimer;
-		if(!turnTimerUpdateApplier(turnTimer))
+		if(!turnTimerUpdateApplier(timers[state.color], waitTime))
 		{
-			if(turnTimer.battleTimer > 0)
+			if(timers[state.color].battleTimer > 0)
 			{
-				turnTimer.creatureTimer = turnTimer.battleTimer;
-				turnTimer.battleTimer = 0;
-				turnTimerUpdateApplier(turnTimer);
+				timers[state.color].creatureTimer = timers[state.color].battleTimer;
+				timers[state.color].battleTimer = 0;
+				turnTimerUpdateApplier(timers[state.color], 0);
 			}
 			else
 			{

+ 5 - 4
server/TurnTimerHandler.h

@@ -14,7 +14,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 class CStack;
 class PlayerColor;
-struct PlayerState;
+struct TurnTimerInfo;
 
 VCMI_LIB_NAMESPACE_END
 
@@ -26,13 +26,14 @@ class TurnTimerHandler
 	const int turnTimePropagateFrequency = 5000;
 	const int turnTimePropagateFrequencyCrit = 1000;
 	const int turnTimePropagateThreshold = 3000;
+	std::map<PlayerColor, TurnTimerInfo> timers;
 	
 public:
 	TurnTimerHandler(CGameHandler &);
 	
-	void onGameplayStart(PlayerState & state);
-	void onPlayerGetTurn(PlayerState & state);
-	void onPlayerMakingTurn(PlayerState & state, int waitTime);
+	void onGameplayStart(PlayerColor player);
+	void onPlayerGetTurn(PlayerColor player);
+	void onPlayerMakingTurn(PlayerColor player, int waitTime);
 	void onBattleStart();
 	void onBattleNextStack(const CStack & stack);
 	void onBattleLoop(int waitTime);