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

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 пре 10 година
родитељ
комит
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 )