浏览代码

Do not remove battle stacks, make them ghosts instead.
* exclude ghost stacks from (hopefully all) get* results for now

AlexVinS 9 年之前
父节点
当前提交
9036d39241
共有 6 个文件被更改,包括 19 次插入70 次删除
  1. 5 8
      client/battle/CBattleInterface.cpp
  2. 0 20
      lib/BattleState.cpp
  3. 0 1
      lib/BattleState.h
  4. 1 1
      lib/CBattleCallback.cpp
  5. 13 4
      lib/NetPacksLib.cpp
  6. 0 36
      server/CGameHandler.cpp

+ 5 - 8
client/battle/CBattleInterface.cpp

@@ -1071,9 +1071,6 @@ void CBattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attacked
 			stackRemoved(attackedInfo.defender->ID);
 	}
 
-/*	if (attackedInfos.front().cloneKilled) //FIXME: cloned stack is already removed
-		return;*/
-
 	if (targets > 1)
 		printConsoleAttacked(attackedInfos.front().defender, damage, killed, attackedInfos.front().attacker, true); //creatures perish
 	else
@@ -2169,14 +2166,14 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 			case RISE_DEMONS:
 				if (shere && ourStack && !shere->alive())
 				{
-					if(!(shere->hasBonusOfType(Bonus::UNDEAD) 
-						|| shere->hasBonusOfType(Bonus::NON_LIVING) 
+					if(!(shere->hasBonusOfType(Bonus::UNDEAD)
+						|| shere->hasBonusOfType(Bonus::NON_LIVING)
 						|| vstd::contains(shere->state, EBattleStackState::SUMMONED)
 						|| vstd::contains(shere->state, EBattleStackState::CLONED)
 						|| shere->hasBonusOfType(Bonus::SIEGE_WEAPON)
 						))
 						legalAction = true;
-				}					
+				}
 				break;
 		}
 		if (legalAction)
@@ -2334,8 +2331,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 			case RISE_DEMONS:
 				cursorType = ECursor::SPELLBOOK;
 				realizeAction = [=]
-				{ 
-					giveCommand(Battle::DAEMON_SUMMONING, myNumber, activeStack->ID); 
+				{
+					giveCommand(Battle::DAEMON_SUMMONING, myNumber, activeStack->ID);
 				};
 				break;
 			case CATAPULT:

+ 0 - 20
lib/BattleState.cpp

@@ -142,26 +142,6 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
 	return ret;
 }
 
-const CStack * BattleInfo::battleGetStack(BattleHex pos, bool onlyAlive)
-{
-	CStack * stack = nullptr;
-	for(auto & elem : stacks)
-	{
-		if(elem->position == pos
-			|| (elem->doubleWide()
-			&&( (elem->attackerOwned && elem->position-1 == pos)
-			||	(!elem->attackerOwned && elem->position+1 == pos)	)
-			) )
-		{
-			if (elem->alive())
-				return elem; //we prefer living stacks - there can be only one stack on the tile, so return it immediately
-			else if (!onlyAlive)
-				stack = elem; //dead stacks are only accessible when there's no alive stack on this tile
-		}
-	}
-	return stack;
-}
-
 const CGHeroInstance * BattleInfo::battleGetOwner(const CStack * stack) const
 {
 	return sides[!stack->attackerOwned].hero;

+ 0 - 1
lib/BattleState.h

@@ -142,7 +142,6 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 
 	const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
 
-	const CStack * battleGetStack(BattleHex pos, bool onlyAlive); //returns stack at given tile
 	const CGHeroInstance * battleGetOwner(const CStack * stack) const; //returns hero that owns given stack; nullptr if none
 	void localInit();
 

+ 1 - 1
lib/CBattleCallback.cpp

@@ -189,7 +189,7 @@ TStacks CBattleInfoEssentials::battleGetStacksIf(TStackFilter predicate, bool in
 	RETURN_IF_NOT_BATTLE(ret);
 
 	vstd::copy_if(getBattle()->stacks, std::back_inserter(ret), [=](const CStack * s){
-		return predicate(s) && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
+		return predicate(s) && (!vstd::contains(s->state, EBattleStackState::GHOST))  && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
 	});
 
 	return ret;

+ 13 - 4
lib/NetPacksLib.cpp

@@ -1312,7 +1312,10 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
 		{
 			//remove clone as well
 			CStack * clone = gs->curB->getStack(at->cloneID);
-			clone->state.insert(EBattleStackState::GHOST);
+			if(clone)
+			{
+				clone->state.insert(EBattleStackState::GHOST);
+			}
 			at->cloneID = -1;
 		}
 	}
@@ -1340,7 +1343,9 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
 
 	//killed summoned creature should be removed like clone
 	if(killed() && vstd::contains(at->state, EBattleStackState::SUMMONED))
+	{
 		at->state.insert(EBattleStackState::GHOST);
+	}
 }
 
 DLL_LINKAGE void BattleAttack::applyGs( CGameState *gs )
@@ -1635,15 +1640,19 @@ DLL_LINKAGE void BattleStacksRemoved::applyGs( CGameState *gs )
 			{
 				CStack * toRemove = gs->curB->stacks[b];
 
+				toRemove->state.erase(EBattleStackState::ALIVE); //just in case
+				toRemove->state.insert(EBattleStackState::GHOST);
+
 				//stack may be removed instantly (not being killed first)
 				//handle clone remove also here
 				if(toRemove->cloneID >= 0)
+				{
 					stackIDs.insert(toRemove->cloneID);
-
-				gs->curB->stacks.erase(gs->curB->stacks.begin() + b); //remove
+					toRemove->cloneID = -1;
+				}
 
 				toRemove->detachFromAll();
-				delete toRemove;
+
 				break;
 			}
 		}

+ 0 - 36
server/CGameHandler.cpp

@@ -5606,19 +5606,6 @@ void CGameHandler::runBattle()
 
 		const BattleInfo & curB = *gs->curB;
 
-		//remove clones after all mechanics and animations are handled!
-		std::set <const CStack*> stacksToRemove;
-		for (auto stack : curB.stacks)
-		{
-			if (stack->isGhost())
-				stacksToRemove.insert(stack);
-		}
-		for (auto stack : stacksToRemove)
-		{
-			BattleStacksRemoved bsr;
-			bsr.stackIDs.insert(stack->ID);
-			sendAndApply(&bsr);
-		}
 		//stack loop
 
 		const CStack *next;
@@ -6106,29 +6093,6 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
 		}
 	};
 
-	//1. Find removed stacks.
-	for(const auto & slotInfo : army->stacks)
-	{
-		const SlotID slot = slotInfo.first;
-		const CStackInstance * instance = slotInfo.second;
-
-		if(nullptr != instance)//just in case
-		{
-			bool found = false;
-			for(const CStack * sta : bat->stacks)
-			{
-				if(sta->base == instance)
-				{
-					found = true;
-					break;
-				}
-			}
-			//stack in this slot was removed == it is dead
-			if(!found)
-				killStack(slot, instance);
-		}
-	}
-
 	for(CStack *st : bat->stacks)
 	{
 		if(vstd::contains(st->state, EBattleStackState::SUMMONED)) //don't take into account temporary summoned stacks