Преглед изворни кода

Battles: more advanced drawbridge mechanics on server-side

Everything work as intended except starting point not included in path.
So we send BattleDrawbridgeStateChanged package when already standing on bridge hex.
Arseniy Shestakov пре 9 година
родитељ
комит
015a57f81c
1 измењених фајлова са 89 додато и 19 уклоњено
  1. 89 19
      server/CGameHandler.cpp

+ 89 - 19
server/CGameHandler.cpp

@@ -1060,6 +1060,65 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 		const int tilesToMove = std::max((int)(path.first.size() - creSpeed), 0);
 		int v = path.first.size()-1;
 
+		// check if gate need to be open or closed at some point
+		BattleHex openGateAtHex, gateMayCloseAtHex;
+		auto dbState = gs->curB->si.drawbridgeState;
+		if(battleGetSiegeLevel() > 0 && dbState != EDrawbridgeState::LOWERED_BORKED &&
+			dbState != EDrawbridgeState::RAISED_BLOCKED)
+		{
+			for(int i = path.first.size()-1; i >= 0; i--)
+			{
+				auto hex = path.first[i];
+				if(!openGateAtHex.isValid() && dbState != EDrawbridgeState::LOWERED)
+				{
+					if(gs->curB->town->subID == ETownType::FORTRESS)
+					{
+						if(hex == BattleHex(93) &&
+							i-1 >= 0 && path.first[i-1] == BattleHex(94))
+						{
+							openGateAtHex = path.first[i+1];
+						}
+					}
+					if(hex == BattleHex(94) && i-1 >= 0 && path.first[i-1] == BattleHex(95))
+					{
+						openGateAtHex = path.first[i+1];
+					}
+					else if(hex == BattleHex(95) || hex == BattleHex(96))
+					{
+						openGateAtHex = path.first[i+1];
+					}
+
+					if(openGateAtHex.isValid())
+						dbState = EDrawbridgeState::LOWERED;
+				}
+
+				if(!gateMayCloseAtHex.isValid() && dbState != EDrawbridgeState::RAISED)
+				{
+					if(hex == BattleHex(96) && i-1 >= 0 && path.first[i-1] != BattleHex(95))
+					{
+						gateMayCloseAtHex = path.first[i-1];
+					}
+					if(gs->curB->town->subID == ETownType::FORTRESS)
+					{
+						if(hex == BattleHex(94) && i-1 >= 0 && path.first[i-1] != BattleHex(95))
+						{
+							gateMayCloseAtHex = path.first[i-1];
+						}
+						else if(hex == BattleHex(95) && i-1 >= 0 &&
+							path.first[i-1] != BattleHex(96) &&
+							path.first[i-1] != BattleHex(94))
+						{
+							gateMayCloseAtHex = path.first[i-1];
+						}
+					}
+					else if(hex == BattleHex(95) && i-1 >= 0 && path.first[i-1] != BattleHex(96))
+					{
+						gateMayCloseAtHex = path.first[i-1];
+					}
+				}
+			}
+		}
+
 		bool stackIsMoving = true;
 
 		while(stackIsMoving)
@@ -1070,11 +1129,18 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 				break;
 			}
 
-			for(bool obstacleHit = false; (!obstacleHit) && (v >= tilesToMove); --v)
+			bool gateStateChanging = false;
+			for(bool obstacleHit = false; (!obstacleHit) && (!gateStateChanging) && (v >= tilesToMove); --v)
 			{
 				BattleHex hex = path.first[v];
 				tiles.push_back(hex);
 
+				if((openGateAtHex.isValid() && openGateAtHex == hex) ||
+					(gateMayCloseAtHex.isValid() && gateMayCloseAtHex == hex))
+				{
+					gateStateChanging = true;
+				}
+
 				//if we walked onto something, finalize this portion of stack movement check into obstacle
 				if((obstacle = battleGetObstacleOnPos(hex, false)))
 					obstacleHit = true;
@@ -1121,6 +1187,18 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 				processObstacle(obstacle);
 				if(curStack->alive())
 					processObstacle(obstacle2);
+
+				if(curStack->alive() && gateStateChanging)
+				{
+					if(curStack->position == openGateAtHex)
+					{
+						BattleDrawbridgeStateChanged db;
+						db.state = EDrawbridgeState::LOWERED;
+						sendAndApply(&db);
+					}
+					else
+						updateDrawbridgeState();
+				}
 			}
 			else
 				//movement finished normally: we reached destination
@@ -3460,28 +3538,20 @@ void CGameHandler::updateDrawbridgeState()
 	}
 	else if(db.state == EDrawbridgeState::LOWERED)
 	{
-		if(gs->curB->battleGetStackByPos(BattleHex(94), false) ||
-			gs->curB->battleGetStackByPos(BattleHex(95), false) ||
-			gs->curB->battleGetStackByPos(BattleHex(96), false))
+		if((gs->curB->town->subID != ETownType::FORTRESS || !gs->curB->battleGetStackByPos(BattleHex(94), false)) &&
+			!gs->curB->battleGetStackByPos(BattleHex(95), false) &&
+			!gs->curB->battleGetStackByPos(BattleHex(96), false))
 		{
-			db.state = EDrawbridgeState::LOWERED;
-		}
-		else
 			db.state = EDrawbridgeState::RAISED;
-	}
-	else if(db.state == EDrawbridgeState::RAISED || db.state == EDrawbridgeState::RAISED_BLOCKED)
-	{
-		if(gs->curB->battleGetStackByPos(BattleHex(94), false))
-			db.state = EDrawbridgeState::RAISED_BLOCKED;
-		else if(gs->curB->battleGetStackByPos(BattleHex(95), false) ||
-			gs->curB->battleGetStackByPos(BattleHex(96), false))
-		{
-			db.state = EDrawbridgeState::LOWERED;
 		}
-		else
-			db.state = EDrawbridgeState::RAISED;
 	}
-	sendAndApply(&db);
+	else if(gs->curB->battleGetStackByPos(BattleHex(94), false))
+		db.state = EDrawbridgeState::RAISED_BLOCKED;
+	else
+		db.state = EDrawbridgeState::RAISED;
+
+	if(db.state != gs->curB->si.drawbridgeState)
+		sendAndApply(&db);
 }
 
 bool CGameHandler::makeBattleAction( BattleAction &ba )