AlexVinS 10 years ago
parent
commit
bd70f672c3
5 changed files with 27 additions and 6 deletions
  1. 5 2
      lib/BattleState.cpp
  2. 2 1
      lib/BattleState.h
  3. 1 2
      lib/NetPacks.h
  4. 11 1
      lib/NetPacksLib.cpp
  5. 8 0
      lib/spells/BattleSpellMechanics.cpp

+ 5 - 2
lib/BattleState.cpp

@@ -763,7 +763,7 @@ CGHeroInstance * BattleInfo::battleGetFightingHero(ui8 side) const
 
 CStack::CStack(const CStackInstance *Base, PlayerColor O, int I, bool AO, SlotID S)
 	: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
-	counterAttacksPerformed(0),counterAttacksTotalCache(0)
+	counterAttacksPerformed(0),counterAttacksTotalCache(0), cloneID(-1)
 {
 	assert(base);
 	type = base->type;
@@ -776,7 +776,8 @@ CStack::CStack()
 	setNodeType(STACK_BATTLE);
 }
 CStack::CStack(const CStackBasicDescriptor *stack, PlayerColor O, int I, bool AO, SlotID S)
-	: base(nullptr), ID(I), owner(O), slot(S), attackerOwned(AO), counterAttacksPerformed(0)
+	: base(nullptr), ID(I), owner(O), slot(S), attackerOwned(AO), counterAttacksPerformed(0),
+	 cloneID(-1)
 {
 	type = stack->type;
 	count = baseAmount = stack->count;
@@ -796,6 +797,7 @@ void CStack::init()
 	position = BattleHex();
 	counterAttacksPerformed = 0;
 	counterAttacksTotalCache = 0;
+	cloneID = -1;
 }
 
 void CStack::postInit()
@@ -809,6 +811,7 @@ void CStack::postInit()
 	counterAttacksTotalCache = 0;
 	casts = valOfBonuses(Bonus::CASTS);
 	resurrected = 0;
+	cloneID = -1;
 }
 
 ui32 CStack::level() const

+ 2 - 1
lib/BattleState.h

@@ -178,7 +178,8 @@ public:
 	si16 shots; //how many shots left
 	ui8 casts; //how many casts left
 	TQuantity resurrected; // these units will be taken back after battle is over
-
+	///id of alive clone of this stack clone if any
+	si32 cloneID;
 	std::set<EBattleStackState::EBattleStackState> state;
 	//overrides
 	const CCreature* getCreature() const {return type;}

+ 1 - 2
lib/NetPacks.h

@@ -1641,10 +1641,9 @@ struct BattleSetStackProperty : public CPackForClient //3018
 {
 	BattleSetStackProperty(){type = 3018;};
 
-	enum BattleStackProperty {CASTS, ENCHANTER_COUNTER, UNBIND, CLONED};
+	enum BattleStackProperty {CASTS, ENCHANTER_COUNTER, UNBIND, CLONED, HAS_CLONE};
 
 	DLL_LINKAGE void applyGs(CGameState *gs);
-	//void applyCl(CClient *cl){};
 
 	int stackID;
 	BattleStackProperty which;

+ 11 - 1
lib/NetPacksLib.cpp

@@ -1248,7 +1248,12 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
 	{
 		//"hide" killed creatures instead so we keep info about it
 		at->state.insert(EBattleStackState::DEAD_CLONE);
-
+		
+		for(CStack * s : gs->curB->stacks)
+		{
+			if(s->cloneID == at->ID)
+				s->cloneID = -1;
+		}
 	}
 }
 
@@ -1604,6 +1609,11 @@ DLL_LINKAGE void BattleSetStackProperty::applyGs(CGameState *gs)
 			stack->state.insert(EBattleStackState::CLONED);
 			break;
 		}
+		case HAS_CLONE:
+		{
+			stack->cloneID = val;
+			break;
+		}
 	}
 }
 

+ 8 - 0
lib/spells/BattleSpellMechanics.cpp

@@ -93,6 +93,12 @@ void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, Battle
 	ssp.val = 0;
 	ssp.absolute = 1;
 	env->sendAndApply(&ssp);
+	
+	ssp.stackID = clonedStack->ID;
+	ssp.which = BattleSetStackProperty::HAS_CLONE;
+	ssp.val = bsa.newStackID;
+	ssp.absolute = 1;
+	env->sendAndApply(&ssp);	
 }
 
 ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
@@ -100,6 +106,8 @@ ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const CGHer
 	//can't clone already cloned creature
 	if(vstd::contains(obj->state, EBattleStackState::CLONED))
 		return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
+	if(obj->cloneID != -1)
+		return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
 	//TODO: how about stacks casting Clone?
 	//currently Clone casted by stack is assumed Expert level
 	ui8 schoolLevel;