ソースを参照

Ensure that ghost stacks are created only by BattleStacksRemoved packet.
This will allow client to receive notification.

AlexVinS 9 年 前
コミット
4bf9036c7b
5 ファイル変更22 行追加4 行削除
  1. 1 2
      lib/BattleState.cpp
  2. 1 0
      lib/BattleState.h
  3. 2 1
      lib/GameConstants.h
  4. 4 1
      lib/NetPacksLib.cpp
  5. 14 0
      server/CGameHandler.cpp

+ 1 - 2
lib/BattleState.cpp

@@ -1164,8 +1164,7 @@ bool CStack::canBeHealed() const
 void CStack::makeGhost()
 {
 	state.erase(EBattleStackState::ALIVE);
-	state.insert(EBattleStackState::GHOST);
-	detachFromAll();//TODO: may be some bonuses should remain
+	state.insert(EBattleStackState::GHOST_PENDING);
 }
 
 ui32 CStack::calculateHealedHealthPoints(ui32 toHeal, const bool resurrect) const

+ 1 - 0
lib/BattleState.h

@@ -246,6 +246,7 @@ public:
 
 	const PlayerColor getOwner() const override;
 
+	///stack will be ghost in next battle state update
 	void makeGhost();
 
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 2 - 1
lib/GameConstants.h

@@ -480,7 +480,8 @@ namespace EBattleStackState
 		//remember to drain mana only once per turn
 		DRAINED_MANA,
 		//only for defending animation
-		DEFENDING_ANIM
+		DEFENDING_ANIM,
+		GHOST_PENDING// stack will become GHOST in next battle state update
 	};
 }
 

+ 4 - 1
lib/NetPacksLib.cpp

@@ -1639,7 +1639,10 @@ DLL_LINKAGE void BattleStacksRemoved::applyGs( CGameState *gs )
 			{
 				CStack * toRemove = gs->curB->stacks[b];
 
-				toRemove->makeGhost();
+				toRemove->state.erase(EBattleStackState::ALIVE);
+				toRemove->state.erase(EBattleStackState::GHOST_PENDING);
+				toRemove->state.insert(EBattleStackState::GHOST);
+				toRemove->detachFromAll();//TODO: may be some bonuses should remain
 
 				//stack may be removed instantly (not being killed first)
 				//handle clone remove also here

+ 14 - 0
server/CGameHandler.cpp

@@ -5606,6 +5606,20 @@ void CGameHandler::runBattle()
 
 		const BattleInfo & curB = *gs->curB;
 
+		std::set <const CStack *> stacksToRemove;
+		for(auto stack : curB.stacks)
+		{
+			if(vstd::contains(stack->state, EBattleStackState::GHOST_PENDING))
+				stacksToRemove.insert(stack);
+		}
+
+		for(auto stack : stacksToRemove)
+		{
+			BattleStacksRemoved bsr;
+			bsr.stackIDs.insert(stack->ID);
+			sendAndApply(&bsr);
+		}
+
 		//stack loop
 
 		const CStack *next;