Răsfoiți Sursa

Centralize GHOST state handling

AlexVinS 9 ani în urmă
părinte
comite
47b619a543

+ 8 - 1
lib/BattleState.cpp

@@ -1141,7 +1141,7 @@ std::string CStack::getName() const
 
 bool CStack::isValidTarget(bool allowDead/* = false*/) const /*alive non-turret stacks (can be attacked or be object of magic effect) */
 {
-	return (alive() || allowDead) && position.isValid();
+	return !isGhost() && (alive() || allowDead) && position.isValid();
 }
 
 bool CStack::canBeHealed() const
@@ -1151,6 +1151,13 @@ bool CStack::canBeHealed() const
 		&& !hasBonusOfType(Bonus::SIEGE_WEAPON);
 }
 
+void CStack::makeGhost()
+{
+	state.erase(EBattleStackState::ALIVE);
+	state.insert(EBattleStackState::GHOST);
+	detachFromAll();//TODO: may be some bonuses should remain
+}
+
 ui32 CStack::calculateHealedHealthPoints(ui32 toHeal, const bool resurrect) const
 {
 	if(!resurrect && !alive())

+ 2 - 0
lib/BattleState.h

@@ -247,6 +247,8 @@ public:
 
 	const PlayerColor getOwner() const override;
 
+	void makeGhost();
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		assert(isIndependentNode());

+ 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) && (!vstd::contains(s->state, EBattleStackState::GHOST))  && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
+		return predicate(s) && (!s->isGhost()) && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
 	});
 
 	return ret;

+ 5 - 9
lib/NetPacksLib.cpp

@@ -1313,9 +1313,8 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
 			//remove clone as well
 			CStack * clone = gs->curB->getStack(at->cloneID);
 			if(clone)
-			{
-				clone->state.insert(EBattleStackState::GHOST);
-			}
+				clone->makeGhost();
+
 			at->cloneID = -1;
 		}
 	}
@@ -1332,7 +1331,7 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
 	if (cloneKilled())
 	{
 		//"hide" killed creatures instead so we keep info about it
-		at->state.insert(EBattleStackState::GHOST);
+		at->makeGhost();
 
 		for(CStack * s : gs->curB->stacks)
 		{
@@ -1344,7 +1343,7 @@ 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);
+		at->makeGhost();
 	}
 }
 
@@ -1640,8 +1639,7 @@ 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);
+				toRemove->makeGhost();
 
 				//stack may be removed instantly (not being killed first)
 				//handle clone remove also here
@@ -1651,8 +1649,6 @@ DLL_LINKAGE void BattleStacksRemoved::applyGs( CGameState *gs )
 					toRemove->cloneID = -1;
 				}
 
-				toRemove->detachFromAll();
-
 				break;
 			}
 		}

+ 0 - 2
lib/spells/BattleSpellMechanics.cpp

@@ -586,8 +586,6 @@ void SacrificeMechanics::applyBattleEffects(const SpellCastEnvironment * env, co
 	RisingSpellMechanics::applyBattleEffects(env, parameters, ctx);
 	//it is safe to remove even active stack
 	BattleStacksRemoved bsr;
-	if(victim->cloneID >= 0)
-		bsr.stackIDs.insert(victim->cloneID);
 	bsr.stackIDs.insert(victim->ID);
 	env->sendAndApply(&bsr);
 }