| 
					
				 | 
			
			
				@@ -17,7 +17,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../../lib/CGeneralTextHandler.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../../lib/CStack.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../../lib/GameSettings.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "../../lib/battle/BattleInfo.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "../../lib/battle/CBattleInfoCallback.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "../../lib/battle/IBattleState.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../../lib/battle/BattleAction.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../../lib/gameState/CGameState.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../../lib/NetPacks.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -37,42 +38,42 @@ void BattleActionProcessor::setGameHandler(CGameHandler * newGameHandler) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gameHandler = newGameHandler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doEmptyAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doEmptyAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doEndTacticsAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doEndTacticsAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doWaitAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doWaitAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doRetreatAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doRetreatAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!gameHandler->gameState()->curB->battleCanFlee(gameHandler->gameState()->curB->sides.at(ba.side).color)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!battle.battleCanFlee(battle.sideToPlayer(ba.side))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->complain("Cannot retreat!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	owner->setBattleResult(EBattleResult::ESCAPE, !ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	owner->setBattleResult(battle, EBattleResult::ESCAPE, !ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doSurrenderAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doSurrenderAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	PlayerColor player = gameHandler->gameState()->curB->sides.at(ba.side).color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	int cost = gameHandler->gameState()->curB->battleGetSurrenderCost(player); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	PlayerColor player = battle.sideToPlayer(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int cost = battle.battleGetSurrenderCost(player); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (cost < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->complain("Cannot surrender!"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -86,13 +87,13 @@ bool BattleActionProcessor::doSurrenderAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gameHandler->giveResource(player, EGameResID::GOLD, -cost); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	owner->setBattleResult(EBattleResult::SURRENDER, !ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	owner->setBattleResult(battle, EBattleResult::SURRENDER, !ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doHeroSpellAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doHeroSpellAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CGHeroInstance *h = gameHandler->gameState()->curB->battleGetFightingHero(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CGHeroInstance *h = battle.battleGetFightingHero(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!h) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		logGlobal->error("Wrong caster!"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -106,7 +107,7 @@ bool BattleActionProcessor::doHeroSpellAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	spells::BattleCast parameters(gameHandler->gameState()->curB, h, spells::Mode::HERO, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spells::BattleCast parameters(&battle, h, spells::Mode::HERO, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	spells::detail::ProblemImpl problem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -122,17 +123,17 @@ bool BattleActionProcessor::doHeroSpellAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	parameters.cast(gameHandler->spellEnv, ba.getTarget(gameHandler->gameState()->curB)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	parameters.cast(gameHandler->spellEnv, ba.getTarget(&battle)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doWalkAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doWalkAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	battle::Target target = ba.getTarget(gameHandler->gameState()->curB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle::Target target = ba.getTarget(&battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(target.size() < 1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -141,7 +142,7 @@ bool BattleActionProcessor::doWalkAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	int walkedTiles = moveStack(ba.stackNumber, target.at(0).hexValue); //move 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int walkedTiles = moveStack(battle, ba.stackNumber, target.at(0).hexValue); //move 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!walkedTiles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->complain("Stack failed movement!"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -150,15 +151,17 @@ bool BattleActionProcessor::doWalkAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doDefendAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doDefendAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//defensive stance, TODO: filter out spell boosts from bonus (stone skin etc.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	SetStackEffect sse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	sse.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Bonus defenseBonusToAdd(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 20, -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::PERCENT_TO_ALL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Bonus bonus2(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, stack->valOfBonuses(BonusType::DEFENSIVE_STANCE), -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Bonus alternativeWeakCreatureBonus(BonusDuration::STACK_GETS_TURN, BonusType::PRIMARY_SKILL, BonusSource::OTHER, 1, -1, static_cast<int32_t>(PrimarySkill::DEFENSE), BonusValueType::ADDITIVE_VALUE); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -187,6 +190,7 @@ bool BattleActionProcessor::doDefendAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gameHandler->sendAndApply(&sse); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleLogMessage message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	message.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	MetaString text; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	stack->addText(text, EMetaText::GENERAL_TXT, 120); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -199,12 +203,12 @@ bool BattleActionProcessor::doDefendAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doAttackAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	battle::Target target = ba.getTarget(gameHandler->gameState()->curB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle::Target target = ba.getTarget(&battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(target.size() < 2) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -215,7 +219,7 @@ bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleHex attackPos = target.at(0).hexValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleHex destinationTile = target.at(1).hexValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * destinationStack = gameHandler->gameState()->curB->battleGetStackByPos(destinationTile, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * destinationStack = battle.battleGetStackByPos(destinationTile, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(!destinationStack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -224,7 +228,7 @@ bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleHex startingPos = stack->getPosition(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	int distance = moveStack(ba.stackNumber, attackPos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int distance = moveStack(battle, ba.stackNumber, attackPos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	logGlobal->trace("%s will attack %s", stack->nodeName(), destinationStack->nodeName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -256,7 +260,7 @@ bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int totalAttacks = stack->totalAttacks.getMeleeValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//TODO: move to CUnitState 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const auto * attackingHero = gameHandler->gameState()->curB->battleGetFightingHero(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const auto * attackingHero = battle.battleGetFightingHero(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(attackingHero) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		totalAttacks += attackingHero->valOfBonuses(BonusType::HERO_GRANTS_ATTACKS, stack->creatureIndex()); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -269,13 +273,13 @@ bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		//first strike 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(i == 0 && firstStrike && retaliation) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			makeAttack(destinationStack, stack, 0, stack->getPosition(), true, false, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			makeAttack(battle, destinationStack, stack, 0, stack->getPosition(), true, false, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		//move can cause death, eg. by walking into the moat, first strike can cause death or paralysis/petrification 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(stack->alive() && !stack->hasBonusOfType(BonusType::NOT_ACTIVE) && destinationStack->alive()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			makeAttack(stack, destinationStack, (i ? 0 : distance), destinationTile, i==0, false, false);//no distance travelled on second attack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			makeAttack(battle, stack, destinationStack, (i ? 0 : distance), destinationTile, i==0, false, false);//no distance travelled on second attack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		//counterattack 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -285,7 +289,7 @@ bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			&& (i == 0 && !firstStrike) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			&& retaliation && destinationStack->ableToRetaliate()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			makeAttack(destinationStack, stack, 0, stack->getPosition(), true, false, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			makeAttack(battle, destinationStack, stack, 0, stack->getPosition(), true, false, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -296,18 +300,18 @@ bool BattleActionProcessor::doAttackAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		&& startingPos == target.at(2).hexValue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		&& stack->alive()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		moveStack(ba.stackNumber, startingPos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		moveStack(battle, ba.stackNumber, startingPos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		//NOTE: curStack->unitId() == ba.stackNumber (rev 1431) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doShootAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doShootAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	battle::Target target = ba.getTarget(gameHandler->gameState()->curB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle::Target target = ba.getTarget(&battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(target.size() < 1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -318,9 +322,9 @@ bool BattleActionProcessor::doShootAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	auto destination = target.at(0).hexValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * destinationStack = gameHandler->gameState()->curB->battleGetStackByPos(destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * destinationStack = battle.battleGetStackByPos(destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!gameHandler->gameState()->curB->battleCanShoot(stack, destination)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!battle.battleCanShoot(stack, destination)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->complain("Cannot shoot!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -332,23 +336,23 @@ bool BattleActionProcessor::doShootAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	makeAttack(stack, destinationStack, 0, destination, true, true, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	makeAttack(battle, stack, destinationStack, 0, destination, true, true, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//ranged counterattack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (destinationStack->hasBonusOfType(BonusType::RANGED_RETALIATION) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		&& !stack->hasBonusOfType(BonusType::BLOCKS_RANGED_RETALIATION) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		&& destinationStack->ableToRetaliate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		&& gameHandler->gameState()->curB->battleCanShoot(destinationStack, stack->getPosition()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		&& battle.battleCanShoot(destinationStack, stack->getPosition()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		&& stack->alive()) //attacker may have died (fire shield) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		makeAttack(destinationStack, stack, 0, stack->getPosition(), true, true, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		makeAttack(battle, destinationStack, stack, 0, stack->getPosition(), true, true, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//allow more than one additional attack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int totalRangedAttacks = stack->totalAttacks.getRangedValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//TODO: move to CUnitState 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const auto * attackingHero = gameHandler->gameState()->curB->battleGetFightingHero(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const auto * attackingHero = battle.battleGetFightingHero(ba.side); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(attackingHero) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		totalRangedAttacks += attackingHero->valOfBonuses(BonusType::HERO_GRANTS_ATTACKS, stack->creatureIndex()); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -362,19 +366,19 @@ bool BattleActionProcessor::doShootAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			&& stack->shots.canUse() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			makeAttack(stack, destinationStack, 0, destination, false, true, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			makeAttack(battle, stack, destinationStack, 0, destination, false, true, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doCatapultAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doCatapultAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->gameState()->curB->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	battle::Target target = ba.getTarget(gameHandler->gameState()->curB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle::Target target = ba.getTarget(&battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	std::shared_ptr<const Bonus> catapultAbility = stack->getBonusLocalFirst(Selector::type()(BonusType::CATAPULT)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -385,7 +389,7 @@ bool BattleActionProcessor::doCatapultAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const CSpell * spell = SpellID(catapultAbility->subtype).toSpell(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		spells::BattleCast parameters(gameHandler->gameState()->curB, stack, spells::Mode::SPELL_LIKE_ATTACK, spell); //We can shot infinitely by catapult 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		spells::BattleCast parameters(&battle, stack, spells::Mode::SPELL_LIKE_ATTACK, spell); //We can shot infinitely by catapult 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		auto shotLevel = stack->valOfBonuses(Selector::typeSubtype(BonusType::CATAPULT_EXTRA_SHOTS, catapultAbility->subtype)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		parameters.setSpellLevel(shotLevel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		parameters.cast(gameHandler->spellEnv, target); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -393,28 +397,28 @@ bool BattleActionProcessor::doCatapultAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doUnitSpellAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doUnitSpellAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->gameState()->curB->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	battle::Target target = ba.getTarget(gameHandler->gameState()->curB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle::Target target = ba.getTarget(&battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	SpellID spellID = ba.spell; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	std::shared_ptr<const Bonus> randSpellcaster = stack->getBonus(Selector::type()(BonusType::RANDOM_SPELLCASTER)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	std::shared_ptr<const Bonus> spellcaster = stack->getBonus(Selector::typeSubtype(BonusType::SPELLCASTER, spellID)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//TODO special bonus for genies ability 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (randSpellcaster && gameHandler->battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_AIMED) == SpellID::NONE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		spellID = gameHandler->battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_GENIE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (randSpellcaster && battle.battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_AIMED) == SpellID::NONE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		spellID = battle.battleGetRandomStackSpell(gameHandler->getRandomGenerator(), stack, CBattleInfoCallback::RANDOM_GENIE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (spellID == SpellID::NONE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->complain("That stack can't cast spells!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const CSpell * spell = SpellID(spellID).toSpell(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		spells::BattleCast parameters(gameHandler->gameState()->curB, stack, spells::Mode::CREATURE_ACTIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		spells::BattleCast parameters(&battle, stack, spells::Mode::CREATURE_ACTIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		int32_t spellLvl = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(spellcaster) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			vstd::amax(spellLvl, spellcaster->val); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -426,12 +430,12 @@ bool BattleActionProcessor::doUnitSpellAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::doHealAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::doHealAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->gameState()->curB->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	battle::Target target = ba.getTarget(gameHandler->gameState()->curB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle::Target target = ba.getTarget(&battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!canStackAct(stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!canStackAct(battle, stack)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(target.size() < 1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -446,7 +450,7 @@ bool BattleActionProcessor::doHealAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(target.at(0).unitValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		destStack = target.at(0).unitValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		destStack = gameHandler->gameState()->curB->battleGetUnitByPos(target.at(0).hexValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		destStack = battle.battleGetUnitByPos(target.at(0).hexValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(stack == nullptr || destStack == nullptr || !healerAbility || healerAbility->subtype < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -455,7 +459,7 @@ bool BattleActionProcessor::doHealAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const CSpell * spell = SpellID(healerAbility->subtype).toSpell(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		spells::BattleCast parameters(gameHandler->gameState()->curB, stack, spells::Mode::SPELL_LIKE_ATTACK, spell); //We can heal infinitely by first aid tent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		spells::BattleCast parameters(&battle, stack, spells::Mode::SPELL_LIKE_ATTACK, spell); //We can heal infinitely by first aid tent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		auto dest = battle::Destination(destStack, target.at(0).hexValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		parameters.setSpellLevel(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		parameters.cast(gameHandler->spellEnv, {dest}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -463,7 +467,7 @@ bool BattleActionProcessor::doHealAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::canStackAct(const CStack * stack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::canStackAct(const CBattleInfoCallback & battle, const CStack * stack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!stack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -476,9 +480,9 @@ bool BattleActionProcessor::canStackAct(const CStack * stack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (gameHandler->battleTacticDist()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (battle.battleTacticDist()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (stack && stack->unitSide() != gameHandler->battleGetTacticsSide()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (stack && stack->unitSide() != battle.battleGetTacticsSide()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			gameHandler->complain("This is not a stack of side that has tactics!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -486,7 +490,7 @@ bool BattleActionProcessor::canStackAct(const CStack * stack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (stack->unitId() != gameHandler->gameState()->curB->getActiveStackID()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (stack != battle.battleActiveUnit()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			gameHandler->complain("Action has to be about active stack!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -495,81 +499,83 @@ bool BattleActionProcessor::canStackAct(const CStack * stack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::dispatchBattleAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::dispatchBattleAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	switch(ba.actionType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::BAD_MORALE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::NO_ACTION: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doEmptyAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doEmptyAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::END_TACTIC_PHASE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doEndTacticsAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doEndTacticsAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::RETREAT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doRetreatAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doRetreatAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::SURRENDER: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doSurrenderAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doSurrenderAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::HERO_SPELL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doHeroSpellAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doHeroSpellAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::WALK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doWalkAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doWalkAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::WAIT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doWaitAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doWaitAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::DEFEND: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doDefendAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doDefendAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::WALK_AND_ATTACK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doAttackAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doAttackAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::SHOOT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doShootAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doShootAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::CATAPULT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doCatapultAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doCatapultAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::MONSTER_SPELL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doUnitSpellAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doUnitSpellAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		case EActionType::STACK_HEAL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return doHealAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return doHealAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gameHandler->complain("Unrecognized action type received!!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::makeBattleActionImpl(const BattleAction &ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::makeBattleActionImpl(const CBattleInfoCallback & battle, const BattleAction &ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	logGlobal->trace("Making action: %s", ba.toString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack * stack = gameHandler->gameState()->curB->battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack * stack = battle.battleGetStackByID(ba.stackNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// for these events client does not expects StartAction/EndAction wrapper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!ba.isBattleEndAction()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		StartAction startAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		startAction.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->sendAndApply(&startAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	bool result = dispatchBattleAction(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bool result = dispatchBattleAction(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (!ba.isBattleEndAction()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		EndAction endAction; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		endAction.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->sendAndApply(&endAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(ba.actionType == EActionType::WAIT || ba.actionType == EActionType::DEFEND || ba.actionType == EActionType::SHOOT || ba.actionType == EActionType::MONSTER_SPELL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		gameHandler->handleObstacleTriggersForUnit(*gameHandler->spellEnv, *stack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		battle.handleObstacleTriggersForUnit(*gameHandler->spellEnv, *stack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int BattleActionProcessor::moveStack(const CBattleInfoCallback & battle, int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack *curStack = gameHandler->battleGetStackByID(stack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const CStack *stackAtEnd = gameHandler->gameState()->curB->battleGetStackByPos(dest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack *curStack = battle.battleGetStackByID(stack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const CStack *stackAtEnd = battle.battleGetStackByPos(dest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert(curStack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert(dest < GameConstants::BFIELD_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (gameHandler->gameState()->curB->tacticDistance) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (battle.battleGetTacticDist()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		assert(gameHandler->gameState()->curB->isInTacticRange(dest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		assert(battle.isInTacticRange(dest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	auto start = curStack->getPosition(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -577,7 +583,7 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//initing necessary tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	auto accessibility = gameHandler->getAccesibility(curStack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	auto accessibility = battle.getAccesibility(curStack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	std::set<BattleHex> passed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//Ignore obstacles on starting position 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	passed.insert(curStack->getPosition()); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -600,24 +606,24 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	bool canUseGate = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	auto dbState = gameHandler->gameState()->curB->si.gateState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if(gameHandler->battleGetSiegeLevel() > 0 && curStack->unitSide() == BattleSide::DEFENDER && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	auto dbState = battle.battleGetGateState(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if(battle.battleGetSiegeLevel() > 0 && curStack->unitSide() == BattleSide::DEFENDER && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		dbState != EGateState::DESTROYED && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		dbState != EGateState::BLOCKED) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		canUseGate = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	std::pair< std::vector<BattleHex>, int > path = gameHandler->gameState()->curB->getPath(start, dest, curStack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	std::pair< std::vector<BattleHex>, int > path = battle.getPath(start, dest, curStack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ret = path.second; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int creSpeed = curStack->speed(0, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (gameHandler->gameState()->curB->tacticDistance > 0 && creSpeed > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (battle.battleGetTacticDist() > 0 && creSpeed > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		creSpeed = GameConstants::BFIELD_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	bool hasWideMoat = vstd::contains_if(gameHandler->battleGetAllObstaclesOnPos(BattleHex(BattleHex::GATE_BRIDGE), false), [](const std::shared_ptr<const CObstacleInstance> & obst) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bool hasWideMoat = vstd::contains_if(battle.battleGetAllObstaclesOnPos(BattleHex(BattleHex::GATE_BRIDGE), false), [](const std::shared_ptr<const CObstacleInstance> & obst) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return obst->obstacleType == CObstacleInstance::MOAT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -657,12 +663,14 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				occupyGateDrawbridgeHex(dest)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				BattleUpdateGateState db; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				db.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				db.state = EGateState::OPENED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				gameHandler->sendAndApply(&db); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			//inform clients about move 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			BattleStackMoved sm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			sm.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			sm.stack = curStack->unitId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			std::vector<BattleHex> tiles; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			tiles.push_back(path.first[0]); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -772,14 +780,14 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					//if we walked onto something, finalize this portion of stack movement check into obstacle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if(!gameHandler->battleGetAllObstaclesOnPos(hex, false).empty()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if(!battle.battleGetAllObstaclesOnPos(hex, false).empty()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						obstacleHit = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					if (curStack->doubleWide()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						BattleHex otherHex = curStack->occupiedHex(hex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						//two hex creature hit obstacle by backside 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						auto obstacle2 = gameHandler->battleGetAllObstaclesOnPos(otherHex, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						auto obstacle2 = battle.battleGetAllObstaclesOnPos(otherHex, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						if(otherHex.isValid() && !obstacle2.empty()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							obstacleHit = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -792,6 +800,7 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				//commit movement 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				BattleStackMoved sm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				sm.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				sm.stack = curStack->unitId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				sm.distance = path.second; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				sm.teleporting = false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -805,7 +814,7 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if(stackIsMoving && start != curStack->getPosition()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					stackIsMoving = gameHandler->handleObstacleTriggersForUnit(*gameHandler->spellEnv, *curStack, passed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					stackIsMoving = battle.handleObstacleTriggersForUnit(*gameHandler->spellEnv, *curStack, passed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					passed.insert(curStack->getPosition()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					if(curStack->doubleWide()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						passed.insert(curStack->occupiedHex()); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -819,6 +828,7 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						if (curStack->alive()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							BattleUpdateGateState db; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							db.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							db.state = EGateState::OPENED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							gameHandler->sendAndApply(&db); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -826,7 +836,7 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					else if (curStack->getPosition() == gateMayCloseAtHex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						gateMayCloseAtHex = BattleHex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						owner->updateGateState(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						owner->updateGateState(battle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -843,19 +853,22 @@ int BattleActionProcessor::moveStack(int stack, BattleHex dest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			passed.clear(); //Just empty passed, obstacles will handled automatically 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//handling obstacle on the final field (separate, because it affects both flying and walking stacks) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	gameHandler->handleObstacleTriggersForUnit(*gameHandler->spellEnv, *curStack, passed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	battle.handleObstacleTriggersForUnit(*gameHandler->spellEnv, *curStack, passed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * defender, int distance, BattleHex targetHex, bool first, bool ranged, bool counter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void BattleActionProcessor::makeAttack(const CBattleInfoCallback & battle, const CStack * attacker, const CStack * defender, int distance, BattleHex targetHex, bool first, bool ranged, bool counter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(first && !counter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		handleAttackBeforeCasting(ranged, attacker, defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		handleAttackBeforeCasting(battle, ranged, attacker, defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	FireShieldInfo fireShield; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleAttack bat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleLogMessage blm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	blm.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bat.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bat.attackerChanges.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	bat.stackAttacking = attacker->unitId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	bat.tile = targetHex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -891,7 +904,7 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		bat.flags |= BattleAttack::DEATH_BLOW; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const auto * owner = gameHandler->gameState()->curB->getHero(attacker->unitOwner()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const auto * owner = battle.battleGetFightingHero(attacker->unitSide()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(owner) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		int chance = owner->valOfBonuses(BonusType::BONUS_DAMAGE_CHANCE, attacker->creatureIndex()); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -903,14 +916,14 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// only primary target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(defender->alive()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		drainedLife += applyBattleEffects(bat, attackerState, fireShield, defender, distance, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		drainedLife += applyBattleEffects(battle, bat, attackerState, fireShield, defender, distance, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//multiple-hex normal attack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	std::set<const CStack*> attackedCreatures = gameHandler->gameState()->curB->getAttackedCreatures(attacker, targetHex, bat.shot()); //creatures other than primary target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	std::set<const CStack*> attackedCreatures = battle.getAttackedCreatures(attacker, targetHex, bat.shot()); //creatures other than primary target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	for(const CStack * stack : attackedCreatures) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(stack != defender && stack->alive()) //do not hit same stack twice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			drainedLife += applyBattleEffects(bat, attackerState, fireShield, stack, distance, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			drainedLife += applyBattleEffects(battle, bat, attackerState, fireShield, stack, distance, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	std::shared_ptr<const Bonus> bonus = attacker->getBonusLocalFirst(Selector::type()(BonusType::SPELL_LIKE_ATTACK)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -927,7 +940,7 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		battle::Target target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		target.emplace_back(defender, targetHex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		spells::BattleCast event(gameHandler->gameState()->curB, attacker, spells::Mode::SPELL_LIKE_ATTACK, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		spells::BattleCast event(&battle, attacker, spells::Mode::SPELL_LIKE_ATTACK, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		event.setSpellLevel(bonus->val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		auto attackedCreatures = spell->battleMechanics(&event)->getAffectedStacks(target); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -938,7 +951,7 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if(stack != defender && stack->alive()) //do not hit same stack twice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				drainedLife += applyBattleEffects(bat, attackerState, fireShield, stack, distance, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				drainedLife += applyBattleEffects(battle, bat, attackerState, fireShield, stack, distance, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -965,6 +978,9 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (drainedLife > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		bat.flags |= BattleAttack::LIFE_DRAIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (BattleStackAttacked & bsa : bat.bsa) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bsa.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gameHandler->sendAndApply(&bat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1012,7 +1028,7 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const CStack * actor = item.first; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			int64_t rawDamage = item.second; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const CGHeroInstance * actorOwner = gameHandler->gameState()->curB->getHero(actor->unitOwner()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			const CGHeroInstance * actorOwner = battle.battleGetFightingHero(actor->unitOwner()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if(actorOwner) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1031,6 +1047,7 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			BattleStackAttacked bsa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			bsa.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			bsa.flags |= BattleStackAttacked::FIRE_SHIELD; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			bsa.stackAttacked = attacker->unitId(); //invert 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			bsa.attackerID = defender->unitId(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1038,6 +1055,7 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			attacker->prepareAttacked(bsa, gameHandler->getRandomGenerator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			StacksInjured pack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			pack.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			pack.stacks.push_back(bsa); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			gameHandler->sendAndApply(&pack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1055,10 +1073,10 @@ void BattleActionProcessor::makeAttack(const CStack * attacker, const CStack * d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gameHandler->sendAndApply(&blm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	handleAfterAttackCasting(ranged, attacker, defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	handleAfterAttackCasting(battle, ranged, attacker, defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void BattleActionProcessor::attackCasting(bool ranged, BonusType attackMode, const battle::Unit * attacker, const battle::Unit * defender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bool ranged, BonusType attackMode, const battle::Unit * attacker, const battle::Unit * defender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(attacker->hasBonusOfType(attackMode)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1104,7 +1122,7 @@ void BattleActionProcessor::attackCasting(bool ranged, BonusType attackMode, con 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			spells::Target target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			target.emplace_back(defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			spells::BattleCast parameters(gameHandler->gameState()->curB, &caster, spells::Mode::PASSIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			spells::BattleCast parameters(&battle, &caster, spells::Mode::PASSIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			auto m = spell->battleMechanics(¶meters); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1126,17 +1144,17 @@ void BattleActionProcessor::attackCasting(bool ranged, BonusType attackMode, con 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void BattleActionProcessor::handleAttackBeforeCasting(bool ranged, const CStack * attacker, const CStack * defender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void BattleActionProcessor::handleAttackBeforeCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	attackCasting(ranged, BonusType::SPELL_BEFORE_ATTACK, attacker, defender); //no death stare / acid breath needed? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	attackCasting(battle, ranged, BonusType::SPELL_BEFORE_ATTACK, attacker, defender); //no death stare / acid breath needed? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack * attacker, const CStack * defender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void BattleActionProcessor::handleAfterAttackCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(!attacker->alive() || !defender->alive()) // can be already dead 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	attackCasting(ranged, BonusType::SPELL_AFTER_ATTACK, attacker, defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	attackCasting(battle, ranged, BonusType::SPELL_AFTER_ATTACK, attacker, defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(!defender->alive()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1169,7 +1187,7 @@ void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			spells::AbilityCaster caster(attacker, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			spells::BattleCast parameters(gameHandler->gameState()->curB, &caster, spells::Mode::PASSIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			spells::BattleCast parameters(&battle, &caster, spells::Mode::PASSIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			spells::Target target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			target.emplace_back(defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			parameters.setEffectValue(staredCreatures); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1194,7 +1212,7 @@ void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		spells::AbilityCaster caster(attacker, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		spells::BattleCast parameters(gameHandler->gameState()->curB, &caster, spells::Mode::PASSIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		spells::BattleCast parameters(&battle, &caster, spells::Mode::PASSIVE, spell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		spells::Target target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		target.emplace_back(defender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1221,7 +1239,7 @@ void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		battle::UnitInfo resurrectInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		resurrectInfo.id = gameHandler->gameState()->curB->battleNextUnitId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		resurrectInfo.id = battle.battleNextUnitId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		resurrectInfo.summoned = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		resurrectInfo.position = defender->getPosition(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		resurrectInfo.side = defender->unitSide(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1239,10 +1257,12 @@ void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return; //wrong subtype 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		BattleUnitsChanged addUnits; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		addUnits.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		addUnits.changedStacks.emplace_back(resurrectInfo.id, UnitChanges::EOperation::ADD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		resurrectInfo.save(addUnits.changedStacks.back().data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		BattleUnitsChanged removeUnits; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		removeUnits.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		removeUnits.changedStacks.emplace_back(defender->unitId(), UnitChanges::EOperation::REMOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->sendAndApply(&removeUnits); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->sendAndApply(&addUnits); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1279,14 +1299,15 @@ void BattleActionProcessor::handleAfterAttackCasting(bool ranged, const CStack * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		defender->prepareAttacked(bsa, gameHandler->getRandomGenerator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		StacksInjured si; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		si.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		si.stacks.push_back(bsa); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->sendAndApply(&si); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		sendGenericKilledLog(defender, bsa.killedAmount, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sendGenericKilledLog(battle, defender, bsa.killedAmount, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int64_t BattleActionProcessor::applyBattleEffects(BattleAttack & bat, std::shared_ptr<battle::CUnitState> attackerState, FireShieldInfo & fireShield, const CStack * def, int distance, bool secondary) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int64_t BattleActionProcessor::applyBattleEffects(const CBattleInfoCallback & battle, BattleAttack & bat, std::shared_ptr<battle::CUnitState> attackerState, FireShieldInfo & fireShield, const CStack * def, int distance, bool secondary) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	BattleStackAttacked bsa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(secondary) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1302,8 +1323,8 @@ int64_t BattleActionProcessor::applyBattleEffects(BattleAttack & bat, std::share 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		bai.luckyStrike  = bat.lucky(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		bai.unluckyStrike  = bat.unlucky(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		auto range = gameHandler->gameState()->curB->calculateDmgRange(bai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		bsa.damageAmount = gameHandler->gameState()->curB->getActualDamage(range.damage, attackerState->getCount(), gameHandler->getRandomGenerator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		auto range = battle.calculateDmgRange(bai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bsa.damageAmount = battle.getBattle()->getActualDamage(range.damage, attackerState->getCount(), gameHandler->getRandomGenerator()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		CStack::prepareAttacked(bsa, gameHandler->getRandomGenerator(), bai.defender->acquireState()); //calculate casualties 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1353,11 +1374,12 @@ int64_t BattleActionProcessor::applyBattleEffects(BattleAttack & bat, std::share 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return drainedLife; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void BattleActionProcessor::sendGenericKilledLog(const CStack * defender, int32_t killed, bool multiple) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void BattleActionProcessor::sendGenericKilledLog(const CBattleInfoCallback & battle, const CStack * defender, int32_t killed, bool multiple) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if(killed > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		BattleLogMessage blm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		blm.battleID = battle.getBattle()->getBattleID(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		addGenericKilledLog(blm, defender, killed, multiple); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gameHandler->sendAndApply(&blm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1390,22 +1412,17 @@ void BattleActionProcessor::addGenericKilledLog(BattleLogMessage & blm, const CS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::makeAutomaticBattleAction(const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::makeAutomaticBattleAction(const CBattleInfoCallback & battle, const BattleAction & ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return makeBattleActionImpl(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return makeBattleActionImpl(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool BattleActionProcessor::makePlayerBattleAction(PlayerColor player, const BattleAction &ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool BattleActionProcessor::makePlayerBattleAction(const CBattleInfoCallback & battle, PlayerColor player, const BattleAction &ba) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const BattleInfo * battle = gameHandler->gameState()->curB; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if(!battle && gameHandler->complain("Can not make action - there is no battle ongoing!")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (ba.side != 0 && ba.side != 1 && gameHandler->complain("Can not make action - invalid battle side!")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if(battle->tacticDistance != 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if(battle.battleGetTacticDist() != 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(!ba.isTacticsAction()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1413,7 +1430,7 @@ bool BattleActionProcessor::makePlayerBattleAction(PlayerColor player, const Bat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(player != battle->sides[ba.side].color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if(player != battle.sideToPlayer(ba.side)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			gameHandler->complain("Can not make actions in battles you are not part of!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1421,21 +1438,21 @@ bool BattleActionProcessor::makePlayerBattleAction(PlayerColor player, const Bat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (ba.isUnitAction() && ba.stackNumber != battle->getActiveStackID()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		auto active = battle.battleActiveUnit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if(!active && gameHandler->complain("No active unit in battle!")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (ba.isUnitAction() && ba.stackNumber != active->unitId()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			gameHandler->complain("Can not make actions - stack is not active!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		auto active = battle->battleActiveUnit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(!active && gameHandler->complain("No active unit in battle!")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		auto unitOwner = battle->battleGetOwner(active); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		auto unitOwner = battle.battleGetOwner(active); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(player != unitOwner && gameHandler->complain("Can not make actions in battles you are not part of!")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return makeBattleActionImpl(ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return makeBattleActionImpl(battle, ba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |