Răsfoiți Sursa

Applied suggestions from review

Ivan Savenko 2 ani în urmă
părinte
comite
264f5c91e8

+ 91 - 91
client/battle/BattleActionsController.cpp

@@ -41,7 +41,7 @@ static std::string formatDmgRange(std::pair<ui32, ui32> dmgRange)
 }
 
 
-BattleActionsController::BattleActionsController(BattleInterface * owner):
+BattleActionsController::BattleActionsController(BattleInterface & owner):
 	owner(owner),
 	creatureCasting(false),
 	spellDestSelectMode(false),
@@ -62,17 +62,17 @@ void BattleActionsController::endCastingSpell()
 		spellDestSelectMode = false;
 		CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER);
 
-		if(owner->stacksController->getActiveStack())
+		if(owner.stacksController->getActiveStack())
 		{
-			possibleActions = getPossibleActionsForStack(owner->stacksController->getActiveStack()); //restore actions after they were cleared
-			owner->myTurn = true;
+			possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); //restore actions after they were cleared
+			owner.myTurn = true;
 		}
 	}
 	else
 	{
-		if(owner->stacksController->getActiveStack())
+		if(owner.stacksController->getActiveStack())
 		{
-			possibleActions = getPossibleActionsForStack(owner->stacksController->getActiveStack());
+			possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack());
 			GH.fakeMouseMove();
 		}
 	}
@@ -81,35 +81,35 @@ void BattleActionsController::endCastingSpell()
 void BattleActionsController::enterCreatureCastingMode()
 {
 	//silently check for possible errors
-	if (!owner->myTurn)
+	if (!owner.myTurn)
 		return;
 
-	if (owner->tacticsMode)
+	if (owner.tacticsMode)
 		return;
 
 	//hero is casting a spell
 	if (spellDestSelectMode)
 		return;
 
-	if (!owner->stacksController->getActiveStack())
+	if (!owner.stacksController->getActiveStack())
 		return;
 
-	if (!owner->stacksController->activeStackSpellcaster())
+	if (!owner.stacksController->activeStackSpellcaster())
 		return;
 
 	//random spellcaster
-	if (owner->stacksController->activeStackSpellToCast() == SpellID::NONE)
+	if (owner.stacksController->activeStackSpellToCast() == SpellID::NONE)
 		return;
 
 	if (vstd::contains(possibleActions, PossiblePlayerBattleAction::NO_LOCATION))
 	{
-		const spells::Caster * caster = owner->stacksController->getActiveStack();
-		const CSpell * spell = owner->stacksController->activeStackSpellToCast().toSpell();
+		const spells::Caster * caster = owner.stacksController->getActiveStack();
+		const CSpell * spell = owner.stacksController->activeStackSpellToCast().toSpell();
 
 		spells::Target target;
 		target.emplace_back();
 
-		spells::BattleCast cast(owner->curInt->cb.get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
+		spells::BattleCast cast(owner.curInt->cb.get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
 
 		auto m = spell->battleMechanics(&cast);
 		spells::detail::ProblemImpl ignored;
@@ -118,16 +118,16 @@ void BattleActionsController::enterCreatureCastingMode()
 
 		if (isCastingPossible)
 		{
-			owner->myTurn = false;
-			owner->giveCommand(EActionType::MONSTER_SPELL, BattleHex::INVALID, owner->stacksController->activeStackSpellToCast());
-			owner->stacksController->setSelectedStack(nullptr);
+			owner.myTurn = false;
+			owner.giveCommand(EActionType::MONSTER_SPELL, BattleHex::INVALID, owner.stacksController->activeStackSpellToCast());
+			owner.stacksController->setSelectedStack(nullptr);
 
 			CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER);
 		}
 	}
 	else
 	{
-		possibleActions = getPossibleActionsForStack(owner->stacksController->getActiveStack());
+		possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack());
 
 		auto actionFilterPredicate = [](const PossiblePlayerBattleAction x)
 		{
@@ -144,16 +144,16 @@ void BattleActionsController::enterCreatureCastingMode()
 std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActionsForStack(const CStack *stack) const
 {
 	BattleClientInterfaceData data; //hard to get rid of these things so for now they're required data to pass
-	data.creatureSpellToCast = owner->stacksController->activeStackSpellToCast();
-	data.tacticsMode = owner->tacticsMode;
-	auto allActions = owner->curInt->cb->getClientActionsForStack(stack, data);
+	data.creatureSpellToCast = owner.stacksController->activeStackSpellToCast();
+	data.tacticsMode = owner.tacticsMode;
+	auto allActions = owner.curInt->cb->getClientActionsForStack(stack, data);
 
 	return std::vector<PossiblePlayerBattleAction>(allActions);
 }
 
 void BattleActionsController::reorderPossibleActionsPriority(const CStack * stack, MouseHoveredHexContext context)
 {
-	if(owner->tacticsMode || possibleActions.empty()) return; //this function is not supposed to be called in tactics mode or before getPossibleActionsForStack
+	if(owner.tacticsMode || possibleActions.empty()) return; //this function is not supposed to be called in tactics mode or before getPossibleActionsForStack
 
 	auto assignPriority = [&](PossiblePlayerBattleAction const & item) -> uint8_t //large lambda assigning priority which would have to be part of possibleActions without it
 	{
@@ -205,21 +205,21 @@ void BattleActionsController::castThisSpell(SpellID spellID)
 	spellToCast = std::make_shared<BattleAction>();
 	spellToCast->actionType = EActionType::HERO_SPELL;
 	spellToCast->actionSubtype = spellID; //spell number
-	spellToCast->stackNumber = (owner->attackingHeroInstance->tempOwner == owner->curInt->playerID) ? -1 : -2;
-	spellToCast->side = owner->defendingHeroInstance ? (owner->curInt->playerID == owner->defendingHeroInstance->tempOwner) : false;
+	spellToCast->stackNumber = (owner.attackingHeroInstance->tempOwner == owner.curInt->playerID) ? -1 : -2;
+	spellToCast->side = owner.defendingHeroInstance ? (owner.curInt->playerID == owner.defendingHeroInstance->tempOwner) : false;
 	spellDestSelectMode = true;
 	creatureCasting = false;
 
 	//choosing possible targets
-	const CGHeroInstance *castingHero = (owner->attackingHeroInstance->tempOwner == owner->curInt->playerID) ? owner->attackingHeroInstance : owner->defendingHeroInstance;
+	const CGHeroInstance *castingHero = (owner.attackingHeroInstance->tempOwner == owner.curInt->playerID) ? owner.attackingHeroInstance : owner.defendingHeroInstance;
 	assert(castingHero); // code below assumes non-null hero
 	currentSpell = spellID.toSpell();
-	PossiblePlayerBattleAction spellSelMode = owner->curInt->cb->getCasterAction(currentSpell, castingHero, spells::Mode::HERO);
+	PossiblePlayerBattleAction spellSelMode = owner.curInt->cb->getCasterAction(currentSpell, castingHero, spells::Mode::HERO);
 
 	if (spellSelMode == PossiblePlayerBattleAction::NO_LOCATION) //user does not have to select location
 	{
 		spellToCast->aimToHex(BattleHex::INVALID);
-		owner->curInt->cb->battleMakeAction(spellToCast.get());
+		owner.curInt->cb->battleMakeAction(spellToCast.get());
 		endCastingSpell();
 	}
 	else
@@ -233,7 +233,7 @@ void BattleActionsController::castThisSpell(SpellID spellID)
 
 void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 {
-	if (!owner->myTurn || !owner->battleActionsStarted) //we are not permit to do anything
+	if (!owner.myTurn || !owner.battleActionsStarted) //we are not permit to do anything
 		return;
 
 	// This function handles mouse move over hexes and l-clicking on them.
@@ -252,24 +252,24 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 	std::function<void()> realizeAction;
 
 	//Get stack on the hex - first try to grab the alive one, if not found -> allow dead stacks.
-	const CStack * shere = owner->curInt->cb->battleGetStackByPos(myNumber, true);
+	const CStack * shere = owner.curInt->cb->battleGetStackByPos(myNumber, true);
 	if(!shere)
-		shere = owner->curInt->cb->battleGetStackByPos(myNumber, false);
+		shere = owner.curInt->cb->battleGetStackByPos(myNumber, false);
 
-	if(!owner->stacksController->getActiveStack())
+	if(!owner.stacksController->getActiveStack())
 		return;
 
 	bool ourStack = false;
 	if (shere)
-		ourStack = shere->owner == owner->curInt->playerID;
+		ourStack = shere->owner == owner.curInt->playerID;
 
 	//stack may have changed, update selection border
-	owner->stacksController->setHoveredStack(shere);
+	owner.stacksController->setHoveredStack(shere);
 
 	localActions.clear();
 	illegalActions.clear();
 
-	reorderPossibleActionsPriority(owner->stacksController->getActiveStack(), shere ? MouseHoveredHexContext::OCCUPIED_HEX : MouseHoveredHexContext::UNOCCUPIED_HEX);
+	reorderPossibleActionsPriority(owner.stacksController->getActiveStack(), shere ? MouseHoveredHexContext::OCCUPIED_HEX : MouseHoveredHexContext::UNOCCUPIED_HEX);
 	const bool forcedAction = possibleActions.size() == 1;
 
 	for (PossiblePlayerBattleAction action : possibleActions)
@@ -288,7 +288,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			{
 				if (!(shere && shere->alive())) //we can walk on dead stacks
 				{
-					if(canStackMoveHere(owner->stacksController->getActiveStack(), myNumber))
+					if(canStackMoveHere(owner.stacksController->getActiveStack(), myNumber))
 						legalAction = true;
 				}
 				break;
@@ -297,12 +297,12 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			case PossiblePlayerBattleAction::WALK_AND_ATTACK:
 			case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
 			{
-				if(owner->curInt->cb->battleCanAttack(owner->stacksController->getActiveStack(), shere, myNumber))
+				if(owner.curInt->cb->battleCanAttack(owner.stacksController->getActiveStack(), shere, myNumber))
 				{
-					if (owner->fieldController->isTileAttackable(myNumber)) // move isTileAttackable to be part of battleCanAttack?
+					if (owner.fieldController->isTileAttackable(myNumber)) // move isTileAttackable to be part of battleCanAttack?
 					{
-						owner->fieldController->setBattleCursor(myNumber); // temporary - needed for following function :(
-						BattleHex attackFromHex = owner->fieldController->fromWhichHexAttack(myNumber);
+						owner.fieldController->setBattleCursor(myNumber); // temporary - needed for following function :(
+						BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(myNumber);
 
 						if (attackFromHex >= 0) //we can be in this line when unreachable creature is L - clicked (as of revision 1308)
 							legalAction = true;
@@ -311,25 +311,25 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			}
 				break;
 			case PossiblePlayerBattleAction::SHOOT:
-				if(owner->curInt->cb->battleCanShoot(owner->stacksController->getActiveStack(), myNumber))
+				if(owner.curInt->cb->battleCanShoot(owner.stacksController->getActiveStack(), myNumber))
 					legalAction = true;
 				break;
 			case PossiblePlayerBattleAction::ANY_LOCATION:
 				if (myNumber > -1) //TODO: this should be checked for all actions
 				{
-					if(isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber))
+					if(isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber))
 						legalAction = true;
 				}
 				break;
 			case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
-				if(shere && isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber))
+				if(shere && isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber))
 					legalAction = true;
 				break;
 			case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL:
 			{
-				if(shere && ourStack && shere != owner->stacksController->getActiveStack() && shere->alive()) //only positive spells for other allied creatures
+				if(shere && ourStack && shere != owner.stacksController->getActiveStack() && shere->alive()) //only positive spells for other allied creatures
 				{
-					int spellID = owner->curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), shere, CBattleInfoCallback::RANDOM_GENIE);
+					int spellID = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), shere, CBattleInfoCallback::RANDOM_GENIE);
 					if(spellID > -1)
 					{
 						legalAction = true;
@@ -338,7 +338,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			}
 				break;
 			case PossiblePlayerBattleAction::OBSTACLE:
-				if(isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber))
+				if(isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber))
 					legalAction = true;
 				break;
 			case PossiblePlayerBattleAction::TELEPORT:
@@ -346,32 +346,32 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 				//todo: move to mechanics
 				ui8 skill = 0;
 				if (creatureCasting)
-					skill = owner->stacksController->getActiveStack()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell());
+					skill = owner.stacksController->getActiveStack()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell());
 				else
-					skill = owner->getActiveHero()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell());
+					skill = owner.getActiveHero()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell());
 				//TODO: explicitely save power, skill
-				if (owner->curInt->cb->battleCanTeleportTo(owner->stacksController->getSelectedStack(), myNumber, skill))
+				if (owner.curInt->cb->battleCanTeleportTo(owner.stacksController->getSelectedStack(), myNumber, skill))
 					legalAction = true;
 				else
 					notLegal = true;
 			}
 				break;
 			case PossiblePlayerBattleAction::SACRIFICE: //choose our living stack to sacrifice
-				if (shere && shere != owner->stacksController->getSelectedStack() && ourStack && shere->alive())
+				if (shere && shere != owner.stacksController->getSelectedStack() && ourStack && shere->alive())
 					legalAction = true;
 				else
 					notLegal = true;
 				break;
 			case PossiblePlayerBattleAction::FREE_LOCATION:
 				legalAction = true;
-				if(!isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber))
+				if(!isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber))
 				{
 					legalAction = false;
 					notLegal = true;
 				}
 				break;
 			case PossiblePlayerBattleAction::CATAPULT:
-				if (owner->siegeController && owner->siegeController->isAttackableByCatapult(myNumber))
+				if (owner.siegeController && owner.siegeController->isAttackableByCatapult(myNumber))
 					legalAction = true;
 				break;
 			case PossiblePlayerBattleAction::HEAL:
@@ -428,35 +428,35 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 		{
 			case PossiblePlayerBattleAction::CHOOSE_TACTICS_STACK:
 				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s
-				realizeAction = [=](){ owner->stackActivated(shere); };
+				realizeAction = [=](){ owner.stackActivated(shere); };
 				break;
 			case PossiblePlayerBattleAction::MOVE_TACTICS:
 			case PossiblePlayerBattleAction::MOVE_STACK:
-				if (owner->stacksController->getActiveStack()->hasBonusOfType(Bonus::FLYING))
+				if (owner.stacksController->getActiveStack()->hasBonusOfType(Bonus::FLYING))
 				{
 					cursorFrame = ECursor::COMBAT_FLY;
-					newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[295]) % owner->stacksController->getActiveStack()->getName()).str(); //Fly %s here
+					newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[295]) % owner.stacksController->getActiveStack()->getName()).str(); //Fly %s here
 				}
 				else
 				{
 					cursorFrame = ECursor::COMBAT_MOVE;
-					newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[294]) % owner->stacksController->getActiveStack()->getName()).str(); //Move %s here
+					newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[294]) % owner.stacksController->getActiveStack()->getName()).str(); //Move %s here
 				}
 
 				realizeAction = [=]()
 				{
-					if(owner->stacksController->getActiveStack()->doubleWide())
+					if(owner.stacksController->getActiveStack()->doubleWide())
 					{
-						std::vector<BattleHex> acc = owner->curInt->cb->battleGetAvailableHexes(owner->stacksController->getActiveStack());
-						BattleHex shiftedDest = myNumber.cloneInDirection(owner->stacksController->getActiveStack()->destShiftDir(), false);
+						std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack());
+						BattleHex shiftedDest = myNumber.cloneInDirection(owner.stacksController->getActiveStack()->destShiftDir(), false);
 						if(vstd::contains(acc, myNumber))
-							owner->giveCommand(EActionType::WALK, myNumber);
+							owner.giveCommand(EActionType::WALK, myNumber);
 						else if(vstd::contains(acc, shiftedDest))
-							owner->giveCommand(EActionType::WALK, shiftedDest);
+							owner.giveCommand(EActionType::WALK, shiftedDest);
 					}
 					else
 					{
-						owner->giveCommand(EActionType::WALK, myNumber);
+						owner.giveCommand(EActionType::WALK, myNumber);
 					}
 				};
 				break;
@@ -464,55 +464,55 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			case PossiblePlayerBattleAction::WALK_AND_ATTACK:
 			case PossiblePlayerBattleAction::ATTACK_AND_RETURN: //TODO: allow to disable return
 				{
-					owner->fieldController->setBattleCursor(myNumber); //handle direction of cursor and attackable tile
+					owner.fieldController->setBattleCursor(myNumber); //handle direction of cursor and attackable tile
 					setCursor = false; //don't overwrite settings from the call above //TODO: what does it mean?
 
 					bool returnAfterAttack = currentAction == PossiblePlayerBattleAction::ATTACK_AND_RETURN;
 
 					realizeAction = [=]()
 					{
-						BattleHex attackFromHex = owner->fieldController->fromWhichHexAttack(myNumber);
+						BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(myNumber);
 						if(attackFromHex.isValid()) //we can be in this line when unreachable creature is L - clicked (as of revision 1308)
 						{
-							auto command = new BattleAction(BattleAction::makeMeleeAttack(owner->stacksController->getActiveStack(), myNumber, attackFromHex, returnAfterAttack));
-							owner->sendCommand(command, owner->stacksController->getActiveStack());
+							auto command = new BattleAction(BattleAction::makeMeleeAttack(owner.stacksController->getActiveStack(), myNumber, attackFromHex, returnAfterAttack));
+							owner.sendCommand(command, owner.stacksController->getActiveStack());
 						}
 					};
 
-					TDmgRange damage = owner->curInt->cb->battleEstimateDamage(owner->stacksController->getActiveStack(), shere);
+					TDmgRange damage = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), shere);
 					std::string estDmgText = formatDmgRange(std::make_pair((ui32)damage.first, (ui32)damage.second)); //calculating estimated dmg
 					newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[36]) % shere->getName() % estDmgText).str(); //Attack %s (%s damage)
 				}
 				break;
 			case PossiblePlayerBattleAction::SHOOT:
 			{
-				if (owner->curInt->cb->battleHasShootingPenalty(owner->stacksController->getActiveStack(), myNumber))
+				if (owner.curInt->cb->battleHasShootingPenalty(owner.stacksController->getActiveStack(), myNumber))
 					cursorFrame = ECursor::COMBAT_SHOOT_PENALTY;
 				else
 					cursorFrame = ECursor::COMBAT_SHOOT;
 
-				realizeAction = [=](){owner->giveCommand(EActionType::SHOOT, myNumber);};
-				TDmgRange damage = owner->curInt->cb->battleEstimateDamage(owner->stacksController->getActiveStack(), shere);
+				realizeAction = [=](){owner.giveCommand(EActionType::SHOOT, myNumber);};
+				TDmgRange damage = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), shere);
 				std::string estDmgText = formatDmgRange(std::make_pair((ui32)damage.first, (ui32)damage.second)); //calculating estimated dmg
 				//printing - Shoot %s (%d shots left, %s damage)
-				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[296]) % shere->getName() % owner->stacksController->getActiveStack()->shots.available() % estDmgText).str();
+				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[296]) % shere->getName() % owner.stacksController->getActiveStack()->shots.available() % estDmgText).str();
 			}
 				break;
 			case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
-				currentSpell = CGI->spellh->objects[creatureCasting ? owner->stacksController->activeStackSpellToCast() : spellToCast->actionSubtype]; //necessary if creature has random Genie spell at same time
+				currentSpell = CGI->spellh->objects[creatureCasting ? owner.stacksController->activeStackSpellToCast() : spellToCast->actionSubtype]; //necessary if creature has random Genie spell at same time
 				newConsoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % currentSpell->name % shere->getName()); //Cast %s on %s
 				switch (currentSpell->id)
 				{
 					case SpellID::SACRIFICE:
 					case SpellID::TELEPORT:
-						owner->stacksController->setSelectedStack(shere); //remember first target
+						owner.stacksController->setSelectedStack(shere); //remember first target
 						secondaryTarget = true;
 						break;
 				}
 				isCastingPossible = true;
 				break;
 			case PossiblePlayerBattleAction::ANY_LOCATION:
-				currentSpell = CGI->spellh->objects[creatureCasting ? owner->stacksController->activeStackSpellToCast() : spellToCast->actionSubtype]; //necessary if creature has random Genie spell at same time
+				currentSpell = CGI->spellh->objects[creatureCasting ? owner.stacksController->activeStackSpellToCast() : spellToCast->actionSubtype]; //necessary if creature has random Genie spell at same time
 				newConsoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[26]) % currentSpell->name); //Cast %s
 				isCastingPossible = true;
 				break;
@@ -544,18 +544,18 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			case PossiblePlayerBattleAction::HEAL:
 				cursorFrame = ECursor::COMBAT_HEAL;
 				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s
-				realizeAction = [=](){ owner->giveCommand(EActionType::STACK_HEAL, myNumber); }; //command healing
+				realizeAction = [=](){ owner.giveCommand(EActionType::STACK_HEAL, myNumber); }; //command healing
 				break;
 			case PossiblePlayerBattleAction::RISE_DEMONS:
 				cursorType = ECursor::SPELLBOOK;
 				realizeAction = [=]()
 				{
-					owner->giveCommand(EActionType::DAEMON_SUMMONING, myNumber);
+					owner.giveCommand(EActionType::DAEMON_SUMMONING, myNumber);
 				};
 				break;
 			case PossiblePlayerBattleAction::CATAPULT:
 				cursorFrame = ECursor::COMBAT_SHOOT_CATAPULT;
-				realizeAction = [=](){ owner->giveCommand(EActionType::CATAPULT, myNumber); };
+				realizeAction = [=](){ owner.giveCommand(EActionType::CATAPULT, myNumber); };
 				break;
 			case PossiblePlayerBattleAction::CREATURE_INFO:
 			{
@@ -634,11 +634,11 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 				{
 					if (currentSpell)
 					{
-						owner->giveCommand(EActionType::MONSTER_SPELL, myNumber, owner->stacksController->activeStackSpellToCast());
+						owner.giveCommand(EActionType::MONSTER_SPELL, myNumber, owner.stacksController->activeStackSpellToCast());
 					}
 					else //unknown random spell
 					{
-						owner->giveCommand(EActionType::MONSTER_SPELL, myNumber);
+						owner.giveCommand(EActionType::MONSTER_SPELL, myNumber);
 					}
 				}
 				else
@@ -653,10 +653,10 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 						spellToCast->aimToHex(myNumber);
 						break;
 					}
-					owner->curInt->cb->battleMakeAction(spellToCast.get());
+					owner.curInt->cb->battleMakeAction(spellToCast.get());
 					endCastingSpell();
 				}
-				owner->stacksController->setSelectedStack(nullptr);
+				owner.stacksController->setSelectedStack(nullptr);
 			}
 		};
 	}
@@ -668,9 +668,9 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 				CCS->curh->changeGraphic(cursorType, cursorFrame);
 
 			if (!currentConsoleMsg.empty())
-				owner->controlPanel->console->clearIfMatching(currentConsoleMsg);
+				owner.controlPanel->console->clearIfMatching(currentConsoleMsg);
 			if (!newConsoleMsg.empty())
-				owner->controlPanel->console->write(newConsoleMsg);
+				owner.controlPanel->console->write(newConsoleMsg);
 
 			currentConsoleMsg = newConsoleMsg;
 		}
@@ -679,12 +679,12 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 			//opening creature window shouldn't affect myTurn...
 			if ((currentAction != PossiblePlayerBattleAction::CREATURE_INFO) && !secondaryTarget)
 			{
-				owner->myTurn = false; //tends to crash with empty calls
+				owner.myTurn = false; //tends to crash with empty calls
 			}
 			realizeAction();
 			if (!secondaryTarget) //do not replace teleport or sacrifice cursor
 				CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER);
-			owner->controlPanel->console->clear();
+			owner.controlPanel->console->clear();
 		}
 	}
 }
@@ -692,15 +692,15 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType)
 
 bool BattleActionsController::isCastingPossibleHere(const CStack *sactive, const CStack *shere, BattleHex myNumber)
 {
-	creatureCasting = owner->stacksController->activeStackSpellcaster() && !spellDestSelectMode; //TODO: allow creatures to cast aimed spells
+	creatureCasting = owner.stacksController->activeStackSpellcaster() && !spellDestSelectMode; //TODO: allow creatures to cast aimed spells
 
 	bool isCastingPossible = true;
 
 	int spellID = -1;
 	if (creatureCasting)
 	{
-		if (owner->stacksController->activeStackSpellToCast() != SpellID::NONE && (shere != sactive)) //can't cast on itself
-			spellID = owner->stacksController->activeStackSpellToCast(); //TODO: merge with SpellTocast?
+		if (owner.stacksController->activeStackSpellToCast() != SpellID::NONE && (shere != sactive)) //can't cast on itself
+			spellID = owner.stacksController->activeStackSpellToCast(); //TODO: merge with SpellTocast?
 	}
 	else //hero casting
 	{
@@ -714,7 +714,7 @@ bool BattleActionsController::isCastingPossibleHere(const CStack *sactive, const
 
 	if (currentSpell)
 	{
-		const spells::Caster *caster = creatureCasting ? static_cast<const spells::Caster *>(sactive) : static_cast<const spells::Caster *>(owner->curInt->cb->battleGetMyHero());
+		const spells::Caster *caster = creatureCasting ? static_cast<const spells::Caster *>(sactive) : static_cast<const spells::Caster *>(owner.curInt->cb->battleGetMyHero());
 		if (caster == nullptr)
 		{
 			isCastingPossible = false;//just in case
@@ -726,7 +726,7 @@ bool BattleActionsController::isCastingPossibleHere(const CStack *sactive, const
 			spells::Target target;
 			target.emplace_back(myNumber);
 
-			spells::BattleCast cast(owner->curInt->cb.get(), caster, mode, currentSpell);
+			spells::BattleCast cast(owner.curInt->cb.get(), caster, mode, currentSpell);
 
 			auto m = currentSpell->battleMechanics(&cast);
 			spells::detail::ProblemImpl problem; //todo: display problem in status bar
@@ -744,7 +744,7 @@ bool BattleActionsController::isCastingPossibleHere(const CStack *sactive, const
 
 bool BattleActionsController::canStackMoveHere(const CStack * stackToMove, BattleHex myNumber) const
 {
-	std::vector<BattleHex> acc = owner->curInt->cb->battleGetAvailableHexes(stackToMove);
+	std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(stackToMove);
 	BattleHex shiftedDest = myNumber.cloneInDirection(stackToMove->destShiftDir(), false);
 
 	if (vstd::contains(acc, myNumber))
@@ -757,7 +757,7 @@ bool BattleActionsController::canStackMoveHere(const CStack * stackToMove, Battl
 
 void BattleActionsController::activateStack()
 {
-	const CStack * s = owner->stacksController->getActiveStack();
+	const CStack * s = owner.stacksController->getActiveStack();
 	if(s)
 		possibleActions = getPossibleActionsForStack(s);
 }

+ 2 - 2
client/battle/BattleActionsController.h

@@ -29,7 +29,7 @@ enum class MouseHoveredHexContext
 /// As well as all relevant feedback for these actions in user interface
 class BattleActionsController
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	/// all actions possible to call at the moment by player
 	std::vector<PossiblePlayerBattleAction> possibleActions;
@@ -70,7 +70,7 @@ class BattleActionsController
 	void reorderPossibleActionsPriority(const CStack * stack, MouseHoveredHexContext context);
 
 public:
-	BattleActionsController(BattleInterface * owner);
+	BattleActionsController(BattleInterface & owner);
 
 	/// initialize list of potential actions for new active stack
 	void activateStack();

+ 92 - 92
client/battle/BattleAnimationClasses.cpp

@@ -34,9 +34,9 @@
 #include "../../lib/CTownHandler.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
 
-CBattleAnimation::CBattleAnimation(BattleInterface * _owner)
-	: owner(_owner),
-	  ID(_owner->stacksController->animIDhelper++),
+CBattleAnimation::CBattleAnimation(BattleInterface & owner)
+	: owner(owner),
+	  ID(owner.stacksController->animIDhelper++),
 	  initialized(false)
 {
 	logAnim->trace("Animation #%d created", ID);
@@ -72,22 +72,22 @@ CBattleAnimation::~CBattleAnimation()
 
 std::vector<CBattleAnimation *> & CBattleAnimation::pendingAnimations()
 {
-	return owner->stacksController->currentAnimations;
+	return owner.stacksController->currentAnimations;
 }
 
 std::shared_ptr<CreatureAnimation> CBattleAnimation::stackAnimation(const CStack * stack) const
 {
-	return owner->stacksController->stackAnimation[stack->ID];
+	return owner.stacksController->stackAnimation[stack->ID];
 }
 
 bool CBattleAnimation::stackFacingRight(const CStack * stack)
 {
-	return owner->stacksController->stackFacingRight[stack->ID];
+	return owner.stacksController->stackFacingRight[stack->ID];
 }
 
 void CBattleAnimation::setStackFacingRight(const CStack * stack, bool facingRight)
 {
-	owner->stacksController->stackFacingRight[stack->ID] = facingRight;
+	owner.stacksController->stackFacingRight[stack->ID] = facingRight;
 }
 
 bool CBattleAnimation::checkInitialConditions()
@@ -116,7 +116,7 @@ bool CBattleAnimation::checkInitialConditions()
 	return ID == lowestMoveID;
 }
 
-CBattleStackAnimation::CBattleStackAnimation(BattleInterface * owner, const CStack * stack)
+CBattleStackAnimation::CBattleStackAnimation(BattleInterface & owner, const CStack * stack)
 	: CBattleAnimation(owner),
 	  myAnim(stackAnimation(stack)),
 	  stack(stack)
@@ -172,13 +172,13 @@ bool CAttackAnimation::checkInitialConditions()
 const CCreature * CAttackAnimation::getCreature() const
 {
 	if (attackingStack->getCreature()->idNumber == CreatureID::ARROW_TOWERS)
-		return owner->siegeController->getTurretCreature();
+		return owner.siegeController->getTurretCreature();
 	else
 		return attackingStack->getCreature();
 }
 
-CAttackAnimation::CAttackAnimation(BattleInterface *_owner, const CStack *attacker, BattleHex _dest, const CStack *defender)
-	: CBattleStackAnimation(_owner, attacker),
+CAttackAnimation::CAttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender)
+	: CBattleStackAnimation(owner, attacker),
 	  shooting(false),
 	  group(CCreatureAnim::SHOOT_FRONT),
 	  soundPlayed(false),
@@ -190,8 +190,8 @@ CAttackAnimation::CAttackAnimation(BattleInterface *_owner, const CStack *attack
 	attackingStackPosBeforeReturn = attackingStack->getPosition();
 }
 
-CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface * _owner)
-	: CBattleStackAnimation(_owner, _attackedInfo.defender),
+CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface & owner)
+	: CBattleStackAnimation(owner, _attackedInfo.defender),
 	  attacker(_attackedInfo.attacker),
 	  rangedAttack(_attackedInfo.indirectAttack),
 	  killed(_attackedInfo.killed),
@@ -235,14 +235,14 @@ bool CDefenceAnimation::init()
 
 
 	//reverse unit if necessary
-	if(attacker && owner->getCurrentPlayerInterface()->cb->isToReverse(stack->getPosition(), attacker->getPosition(), stackFacingRight(stack), attacker->doubleWide(), stackFacingRight(attacker)))
+	if(attacker && owner.getCurrentPlayerInterface()->cb->isToReverse(stack->getPosition(), attacker->getPosition(), stackFacingRight(stack), attacker->doubleWide(), stackFacingRight(attacker)))
 	{
-		owner->stacksController->addNewAnim(new CReverseAnimation(owner, stack, stack->getPosition(), true));
+		owner.stacksController->addNewAnim(new CReverseAnimation(owner, stack, stack->getPosition(), true));
 		return false;
 	}
 	//unit reversed
 
-	if(rangedAttack && attacker != nullptr && owner->projectilesController->hasActiveProjectile(attacker)) //delay hit animation
+	if(rangedAttack && attacker != nullptr && owner.projectilesController->hasActiveProjectile(attacker)) //delay hit animation
 	{
 		return false;
 	}
@@ -327,8 +327,8 @@ CDefenceAnimation::~CDefenceAnimation()
 	}
 }
 
-CDummyAnimation::CDummyAnimation(BattleInterface * _owner, int howManyFrames)
-	: CBattleAnimation(_owner),
+CDummyAnimation::CDummyAnimation(BattleInterface & owner, int howManyFrames)
+	: CBattleAnimation(owner),
 	  counter(0),
 	  howMany(howManyFrames)
 {
@@ -358,11 +358,11 @@ bool CMeleeAttackAnimation::init()
 		return false;
 	}
 
-	bool toReverse = owner->getCurrentPlayerInterface()->cb->isToReverse(attackingStackPosBeforeReturn, attackedStack->getPosition(), stackFacingRight(stack), attackedStack->doubleWide(), stackFacingRight(attackedStack));
+	bool toReverse = owner.getCurrentPlayerInterface()->cb->isToReverse(attackingStackPosBeforeReturn, attackedStack->getPosition(), stackFacingRight(stack), attackedStack->doubleWide(), stackFacingRight(attackedStack));
 
 	if(toReverse)
 	{
-		owner->stacksController->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true));
+		owner.stacksController->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true));
 		return false;
 	}
 
@@ -438,14 +438,14 @@ bool CMeleeAttackAnimation::init()
 	return true;
 }
 
-CMeleeAttackAnimation::CMeleeAttackAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked)
-	: CAttackAnimation(_owner, attacker, _dest, _attacked)
+CMeleeAttackAnimation::CMeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked)
+	: CAttackAnimation(owner, attacker, _dest, _attacked)
 {
 	logAnim->debug("Created melee attack anim for %s", attacker->getName());
 }
 
-CStackMoveAnimation::CStackMoveAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex _currentHex):
-	CBattleStackAnimation(_owner, _stack),
+CStackMoveAnimation::CStackMoveAnimation(BattleInterface & owner, const CStack * _stack, BattleHex _currentHex):
+	CBattleStackAnimation(owner, _stack),
 	currentHex(_currentHex)
 {
 
@@ -471,13 +471,13 @@ bool CMovementAnimation::init()
 	}
 
 	//reverse unit if necessary
-	if(owner->stacksController->shouldRotate(stack, oldPos, currentHex))
+	if(owner.stacksController->shouldRotate(stack, oldPos, currentHex))
 	{
 		// it seems that H3 does NOT plays full rotation animation here in most situations
 		// Logical since it takes quite a lot of time
 		if (curentMoveIndex == 0) // full rotation only for moving towards first tile.
 		{
-			owner->stacksController->addNewAnim(new CReverseAnimation(owner, stack, oldPos, true));
+			owner.stacksController->addNewAnim(new CReverseAnimation(owner, stack, oldPos, true));
 			return false;
 		}
 		else
@@ -491,13 +491,13 @@ bool CMovementAnimation::init()
 		myAnim->setType(CCreatureAnim::MOVING);
 	}
 
-	if (owner->moveSoundHander == -1)
+	if (owner.moveSoundHander == -1)
 	{
-		owner->moveSoundHander = CCS->soundh->playSound(battle_sound(stack->getCreature(), move), -1);
+		owner.moveSoundHander = CCS->soundh->playSound(battle_sound(stack->getCreature(), move), -1);
 	}
 
-	Point begPosition = owner->stacksController->getStackPositionAtHex(oldPos, stack);
-	Point endPosition = owner->stacksController->getStackPositionAtHex(currentHex, stack);
+	Point begPosition = owner.stacksController->getStackPositionAtHex(oldPos, stack);
+	Point endPosition = owner.stacksController->getStackPositionAtHex(currentHex, stack);
 
 	timeToMove = AnimationControls::getMovementDuration(stack->getCreature());
 
@@ -530,7 +530,7 @@ void CMovementAnimation::nextFrame()
 	if(progress >= 1.0)
 	{
 		// Sets the position of the creature animation sprites
-		Point coords = owner->stacksController->getStackPositionAtHex(currentHex, stack);
+		Point coords = owner.stacksController->getStackPositionAtHex(currentHex, stack);
 		myAnim->pos = coords;
 
 		// true if creature haven't reached the final destination hex
@@ -553,18 +553,18 @@ CMovementAnimation::~CMovementAnimation()
 {
 	assert(stack);
 
-	myAnim->pos = owner->stacksController->getStackPositionAtHex(currentHex, stack);
-	owner->stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, currentHex));
+	myAnim->pos = owner.stacksController->getStackPositionAtHex(currentHex, stack);
+	owner.stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, currentHex));
 
-	if(owner->moveSoundHander != -1)
+	if(owner.moveSoundHander != -1)
 	{
-		CCS->soundh->stopSound(owner->moveSoundHander);
-		owner->moveSoundHander = -1;
+		CCS->soundh->stopSound(owner.moveSoundHander);
+		owner.moveSoundHander = -1;
 	}
 }
 
-CMovementAnimation::CMovementAnimation(BattleInterface *_owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance)
-	: CStackMoveAnimation(_owner, _stack, _destTiles.front()),
+CMovementAnimation::CMovementAnimation(BattleInterface & owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance)
+	: CStackMoveAnimation(owner, _stack, _destTiles.front()),
 	  destTiles(_destTiles),
 	  curentMoveIndex(0),
 	  oldPos(stack->getPosition()),
@@ -576,8 +576,8 @@ CMovementAnimation::CMovementAnimation(BattleInterface *_owner, const CStack *_s
 	logAnim->debug("Created movement anim for %s", stack->getName());
 }
 
-CMovementEndAnimation::CMovementEndAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex destTile)
-: CStackMoveAnimation(_owner, _stack, destTile)
+CMovementEndAnimation::CMovementEndAnimation(BattleInterface & owner, const CStack * _stack, BattleHex destTile)
+: CStackMoveAnimation(owner, _stack, destTile)
 {
 	logAnim->debug("Created movement end anim for %s", stack->getName());
 }
@@ -611,8 +611,8 @@ CMovementEndAnimation::~CMovementEndAnimation()
 	CCS->curh->show();
 }
 
-CMovementStartAnimation::CMovementStartAnimation(BattleInterface * _owner, const CStack * _stack)
-	: CStackMoveAnimation(_owner, _stack, _stack->getPosition())
+CMovementStartAnimation::CMovementStartAnimation(BattleInterface & owner, const CStack * _stack)
+	: CStackMoveAnimation(owner, _stack, _stack->getPosition())
 {
 	logAnim->debug("Created movement start anim for %s", stack->getName());
 }
@@ -636,8 +636,8 @@ bool CMovementStartAnimation::init()
 	return true;
 }
 
-CReverseAnimation::CReverseAnimation(BattleInterface * _owner, const CStack * stack, BattleHex dest, bool _priority)
-	: CStackMoveAnimation(_owner, stack, dest),
+CReverseAnimation::CReverseAnimation(BattleInterface & owner, const CStack * stack, BattleHex dest, bool _priority)
+	: CStackMoveAnimation(owner, stack, dest),
 	  priority(_priority)
 {
 	logAnim->debug("Created reverse anim for %s", stack->getName());
@@ -676,7 +676,7 @@ void CBattleStackAnimation::rotateStack(BattleHex hex)
 {
 	setStackFacingRight(stack, !stackFacingRight(stack));
 
-	stackAnimation(stack)->pos = owner->stacksController->getStackPositionAtHex(hex, stack);
+	stackAnimation(stack)->pos = owner.stacksController->getStackPositionAtHex(hex, stack);
 }
 
 void CReverseAnimation::setupSecondPart()
@@ -698,8 +698,8 @@ void CReverseAnimation::setupSecondPart()
 		delete this;
 }
 
-CRangedAttackAnimation::CRangedAttackAnimation(BattleInterface * owner_, const CStack * attacker, BattleHex dest_, const CStack * defender)
-	: CAttackAnimation(owner_, attacker, dest_, defender),
+CRangedAttackAnimation::CRangedAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest_, const CStack * defender)
+	: CAttackAnimation(owner, attacker, dest_, defender),
 	  projectileEmitted(false)
 {
 	logAnim->info("Ranged attack animation created");
@@ -722,9 +722,9 @@ bool CRangedAttackAnimation::init()
 	}
 
 	//reverse unit if necessary
-	if (attackingStack && attackedStack && owner->getCurrentPlayerInterface()->cb->isToReverse(attackingStack->getPosition(), attackedStack->getPosition(), stackFacingRight(attackingStack), attackingStack->doubleWide(), stackFacingRight(attackedStack)))
+	if (attackingStack && attackedStack && owner.getCurrentPlayerInterface()->cb->isToReverse(attackingStack->getPosition(), attackedStack->getPosition(), stackFacingRight(attackingStack), attackingStack->doubleWide(), stackFacingRight(attackedStack)))
 	{
-		owner->stacksController->addNewAnim(new CReverseAnimation(owner, attackingStack, attackingStack->getPosition(), true));
+		owner.stacksController->addNewAnim(new CReverseAnimation(owner, attackingStack, attackingStack->getPosition(), true));
 		return false;
 	}
 
@@ -738,7 +738,7 @@ bool CRangedAttackAnimation::init()
 void CRangedAttackAnimation::setAnimationGroup()
 {
 	Point shooterPos = stackAnimation(attackingStack)->pos.topLeft();
-	Point shotTarget = owner->stacksController->getStackPositionAtHex(dest, attackedStack);
+	Point shotTarget = owner.stacksController->getStackPositionAtHex(dest, attackedStack);
 
 	//maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
 	static const double straightAngle = 0.2;
@@ -757,7 +757,7 @@ void CRangedAttackAnimation::setAnimationGroup()
 void CRangedAttackAnimation::initializeProjectile()
 {
 	const CCreature *shooterInfo = getCreature();
-	Point shotTarget = owner->stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225);
+	Point shotTarget = owner.stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225);
 	Point shotOrigin = stackAnimation(attackingStack)->pos.topLeft() + Point(222, 265);
 	int multiplier = stackFacingRight(attackingStack) ? 1 : -1;
 
@@ -787,7 +787,7 @@ void CRangedAttackAnimation::initializeProjectile()
 void CRangedAttackAnimation::emitProjectile()
 {
 	logAnim->info("Ranged attack projectile emitted");
-	owner->projectilesController->emitStackProjectile(attackingStack);
+	owner.projectilesController->emitStackProjectile(attackingStack);
 	projectileEmitted = true;
 }
 
@@ -807,7 +807,7 @@ void CRangedAttackAnimation::nextFrame()
 	// animation should be paused if there is an active projectile
 	if (projectileEmitted)
 	{
-		if (owner->projectilesController->hasActiveProjectile(attackingStack))
+		if (owner.projectilesController->hasActiveProjectile(attackingStack))
 			stackAnimation(attackingStack)->pause();
 		else
 			stackAnimation(attackingStack)->play();
@@ -836,7 +836,7 @@ CRangedAttackAnimation::~CRangedAttackAnimation()
 {
 	logAnim->info("Ranged attack animation is over");
 	//FIXME: this assert triggers under some unclear, rare conditions. Possibly - if game window is inactive and/or in foreground/minimized?
-	assert(!owner->projectilesController->hasActiveProjectile(attackingStack));
+	assert(!owner.projectilesController->hasActiveProjectile(attackingStack));
 	assert(projectileEmitted);
 
 	// FIXME: is this possible? Animation is over but we're yet to fire projectile?
@@ -847,15 +847,15 @@ CRangedAttackAnimation::~CRangedAttackAnimation()
 	}
 }
 
-CShootingAnimation::CShootingAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked)
-	: CRangedAttackAnimation(_owner, attacker, _dest, _attacked)
+CShootingAnimation::CShootingAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked)
+	: CRangedAttackAnimation(owner, attacker, _dest, _attacked)
 {
 	logAnim->debug("Created shooting anim for %s", stack->getName());
 }
 
 void CShootingAnimation::createProjectile(const Point & from, const Point & dest) const
 {
-	owner->projectilesController->createProjectile(attackingStack, from, dest);
+	owner.projectilesController->createProjectile(attackingStack, from, dest);
 }
 
 uint32_t CShootingAnimation::getAttackClimaxFrame() const
@@ -879,8 +879,8 @@ CCreatureAnim::EAnimType CShootingAnimation::getDownwardsGroup() const
 	return CCreatureAnim::SHOOT_DOWN;
 }
 
-CCatapultAnimation::CCatapultAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, int _catapultDmg)
-	: CShootingAnimation(_owner, attacker, _dest, _attacked),
+CCatapultAnimation::CCatapultAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, int _catapultDmg)
+	: CShootingAnimation(owner, attacker, _dest, _attacked),
 	catapultDamage(_catapultDmg),
 	explosionEmitted(false)
 {
@@ -897,26 +897,26 @@ void CCatapultAnimation::nextFrame()
 	if ( !projectileEmitted)
 		return;
 
-	if (owner->projectilesController->hasActiveProjectile(attackingStack))
+	if (owner.projectilesController->hasActiveProjectile(attackingStack))
 		return;
 
 	explosionEmitted = true;
-	Point shotTarget = owner->stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225) - Point(126, 105);
+	Point shotTarget = owner.stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225) - Point(126, 105);
 
 	if(catapultDamage > 0)
-		owner->stacksController->addNewAnim( new CPointEffectAnimation(owner, soundBase::WALLHIT, "SGEXPL.DEF", shotTarget));
+		owner.stacksController->addNewAnim( new CPointEffectAnimation(owner, soundBase::WALLHIT, "SGEXPL.DEF", shotTarget));
 	else
-		owner->stacksController->addNewAnim( new CPointEffectAnimation(owner, soundBase::WALLMISS, "CSGRCK.DEF", shotTarget));
+		owner.stacksController->addNewAnim( new CPointEffectAnimation(owner, soundBase::WALLMISS, "CSGRCK.DEF", shotTarget));
 }
 
 void CCatapultAnimation::createProjectile(const Point & from, const Point & dest) const
 {
-	owner->projectilesController->createCatapultProjectile(attackingStack, from, dest);
+	owner.projectilesController->createCatapultProjectile(attackingStack, from, dest);
 }
 
 
-CCastAnimation::CCastAnimation(BattleInterface * owner_, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell)
-	: CRangedAttackAnimation(owner_, attacker, dest_, defender),
+CCastAnimation::CCastAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell)
+	: CRangedAttackAnimation(owner, attacker, dest_, defender),
 	  spell(spell)
 {
 	assert(dest.isValid());// FIXME: when?
@@ -970,7 +970,7 @@ CCreatureAnim::EAnimType CCastAnimation::getDownwardsGroup() const
 void CCastAnimation::createProjectile(const Point & from, const Point & dest) const
 {
 	if (!spell->animationInfo.projectile.empty())
-		owner->projectilesController->createSpellProjectile(attackingStack, from, dest, spell);
+		owner.projectilesController->createSpellProjectile(attackingStack, from, dest, spell);
 }
 
 uint32_t CCastAnimation::getAttackClimaxFrame() const
@@ -983,8 +983,8 @@ uint32_t CCastAnimation::getAttackClimaxFrame() const
 	return 0;
 }
 
-CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, int effects):
-	CBattleAnimation(_owner),
+CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, int effects):
+	CBattleAnimation(owner),
 	animation(std::make_shared<CAnimation>(animationName)),
 	sound(sound),
 	effectFlags(effects),
@@ -994,33 +994,33 @@ CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase
 {
 }
 
-CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<BattleHex> hex, int effects):
-	CPointEffectAnimation(_owner, sound, animationName, effects)
+CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, std::vector<BattleHex> hex, int effects):
+	CPointEffectAnimation(owner, sound, animationName, effects)
 {
 	battlehexes = hex;
 }
 
-CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, BattleHex hex, int effects):
-	CPointEffectAnimation(_owner, sound, animationName, effects)
+CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, BattleHex hex, int effects):
+	CPointEffectAnimation(owner, sound, animationName, effects)
 {
 	assert(hex.isValid());
 	battlehexes.push_back(hex);
 }
 
-CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos, int effects):
-	CPointEffectAnimation(_owner, sound, animationName, effects)
+CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos, int effects):
+	CPointEffectAnimation(owner, sound, animationName, effects)
 {
 	positions = pos;
 }
 
-CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos, int effects):
-	CPointEffectAnimation(_owner, sound, animationName, effects)
+CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, Point pos, int effects):
+	CPointEffectAnimation(owner, sound, animationName, effects)
 {
 	positions.push_back(pos);
 }
 
-CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex,   int effects):
-	CPointEffectAnimation(_owner, sound, animationName, effects)
+CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex,   int effects):
+	CPointEffectAnimation(owner, sound, animationName, effects)
 {
 	assert(hex.isValid());
 	battlehexes.push_back(hex);
@@ -1043,9 +1043,9 @@ bool CPointEffectAnimation::init()
 
 	if (screenFill())
 	{
-		for(int i=0; i * first->width() < owner->pos.w ; ++i)
-			for(int j=0; j * first->height() < owner->pos.h ; ++j)
-				positions.push_back(Point( owner->pos.x + i * first->width(), owner->pos.y + j * first->height()));
+		for(int i=0; i * first->width() < owner.pos.w ; ++i)
+			for(int j=0; j * first->height() < owner.pos.h ; ++j)
+				positions.push_back(Point( owner.pos.x + i * first->width(), owner.pos.y + j * first->height()));
 	}
 
 	BattleEffect be;
@@ -1070,8 +1070,8 @@ bool CPointEffectAnimation::init()
 		}
 		else
 		{
-			const CStack * destStack = owner->getCurrentPlayerInterface()->cb->battleGetStackByPos(battlehexes[i], false);
-			Rect tilePos = owner->fieldController->hexPositionAbsolute(battlehexes[i]);
+			const CStack * destStack = owner.getCurrentPlayerInterface()->cb->battleGetStackByPos(battlehexes[i], false);
+			Rect tilePos = owner.fieldController->hexPositionAbsolute(battlehexes[i]);
 
 			be.x = tilePos.x + tilePos.w/2 - first->width()/2;
 
@@ -1083,7 +1083,7 @@ bool CPointEffectAnimation::init()
 			else
 				be.y = tilePos.y - first->height()/2;
 		}
-		owner->effectsController->battleEffects.push_back(be);
+		owner.effectsController->battleEffects.push_back(be);
 	}
 	return true;
 }
@@ -1156,7 +1156,7 @@ void CPointEffectAnimation::playEffect()
 	if ( effectFinished )
 		return;
 
-	for(auto & elem : owner->effectsController->battleEffects)
+	for(auto & elem : owner.effectsController->battleEffects)
 	{
 		if(elem.effectID == ID)
 		{
@@ -1174,7 +1174,7 @@ void CPointEffectAnimation::playEffect()
 
 void CPointEffectAnimation::clearEffect()
 {
-	auto & effects = owner->effectsController->battleEffects;
+	auto & effects = owner.effectsController->battleEffects;
 
 	for ( auto it = effects.begin(); it != effects.end(); )
 	{
@@ -1191,8 +1191,8 @@ CPointEffectAnimation::~CPointEffectAnimation()
 	assert(soundFinished);
 }
 
-CWaitingAnimation::CWaitingAnimation(BattleInterface * owner_):
-	CBattleAnimation(owner_)
+CWaitingAnimation::CWaitingAnimation(BattleInterface & owner):
+	CBattleAnimation(owner)
 {}
 
 void CWaitingAnimation::nextFrame()
@@ -1201,8 +1201,8 @@ void CWaitingAnimation::nextFrame()
 	delete this;
 }
 
-CWaitingProjectileAnimation::CWaitingProjectileAnimation(BattleInterface * owner_, const CStack * shooter):
-	CWaitingAnimation(owner_),
+CWaitingProjectileAnimation::CWaitingProjectileAnimation(BattleInterface & owner, const CStack * shooter):
+	CWaitingAnimation(owner),
 	shooter(shooter)
 {}
 
@@ -1219,7 +1219,7 @@ bool CWaitingProjectileAnimation::init()
 		}
 	}
 
-	if(owner->projectilesController->hasActiveProjectile(shooter))
+	if(owner.projectilesController->hasActiveProjectile(shooter))
 		return false;
 
 	return true;

+ 24 - 24
client/battle/BattleAnimationClasses.h

@@ -30,7 +30,7 @@ class CBattleAnimation
 {
 
 protected:
-	BattleInterface * owner;
+	BattleInterface & owner;
 	bool initialized;
 
 	std::vector<CBattleAnimation *> & pendingAnimations();
@@ -49,7 +49,7 @@ public:
 	virtual void nextFrame() {} //call every new frame
 	virtual ~CBattleAnimation();
 
-	CBattleAnimation(BattleInterface * _owner);
+	CBattleAnimation(BattleInterface & owner);
 };
 
 /// Sub-class which is responsible for managing the battle stack animation.
@@ -59,7 +59,7 @@ public:
 	std::shared_ptr<CreatureAnimation> myAnim; //animation for our stack, managed by CBattleInterface
 	const CStack * stack; //id of stack whose animation it is
 
-	CBattleStackAnimation(BattleInterface * _owner, const CStack * _stack);
+	CBattleStackAnimation(BattleInterface & owner, const CStack * _stack);
 
 	void shiftColor(const ColorShifter * shifter);
 	void rotateStack(BattleHex hex);
@@ -83,7 +83,7 @@ public:
 	void nextFrame() override;
 	bool checkInitialConditions();
 
-	CAttackAnimation(BattleInterface *_owner, const CStack *attacker, BattleHex _dest, const CStack *defender);
+	CAttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender);
 	~CAttackAnimation();
 };
 
@@ -104,7 +104,7 @@ public:
 	bool init() override;
 	void nextFrame() override;
 
-	CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface * _owner);
+	CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface & owner);
 	~CDefenceAnimation();
 };
 
@@ -117,7 +117,7 @@ public:
 	bool init() override;
 	void nextFrame() override;
 
-	CDummyAnimation(BattleInterface * _owner, int howManyFrames);
+	CDummyAnimation(BattleInterface & owner, int howManyFrames);
 };
 
 /// Hand-to-hand attack
@@ -126,7 +126,7 @@ class CMeleeAttackAnimation : public CAttackAnimation
 public:
 	bool init() override;
 
-	CMeleeAttackAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked);
+	CMeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked);
 };
 
 /// Base class for all animations that play during stack movement
@@ -136,7 +136,7 @@ public:
 	BattleHex currentHex;
 
 protected:
-	CStackMoveAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex _currentHex);
+	CStackMoveAnimation(BattleInterface & owner, const CStack * _stack, BattleHex _currentHex);
 };
 
 /// Move animation of a creature
@@ -158,7 +158,7 @@ public:
 	bool init() override;
 	void nextFrame() override;
 
-	CMovementAnimation(BattleInterface *_owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance);
+	CMovementAnimation(BattleInterface & owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance);
 	~CMovementAnimation();
 };
 
@@ -168,7 +168,7 @@ class CMovementEndAnimation : public CStackMoveAnimation
 public:
 	bool init() override;
 
-	CMovementEndAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex destTile);
+	CMovementEndAnimation(BattleInterface & owner, const CStack * _stack, BattleHex destTile);
 	~CMovementEndAnimation();
 };
 
@@ -178,7 +178,7 @@ class CMovementStartAnimation : public CStackMoveAnimation
 public:
 	bool init() override;
 
-	CMovementStartAnimation(BattleInterface * _owner, const CStack * _stack);
+	CMovementStartAnimation(BattleInterface & owner, const CStack * _stack);
 };
 
 /// Class responsible for animation of stack chaning direction (left <-> right)
@@ -190,7 +190,7 @@ public:
 
 	void setupSecondPart();
 
-	CReverseAnimation(BattleInterface * _owner, const CStack * stack, BattleHex dest, bool _priority);
+	CReverseAnimation(BattleInterface & owner, const CStack * stack, BattleHex dest, bool _priority);
 	~CReverseAnimation();
 };
 
@@ -213,7 +213,7 @@ protected:
 	virtual uint32_t getAttackClimaxFrame() const = 0;
 
 public:
-	CRangedAttackAnimation(BattleInterface * owner_, const CStack * attacker, BattleHex dest, const CStack * defender);
+	CRangedAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest, const CStack * defender);
 	~CRangedAttackAnimation();
 
 	bool init() override;
@@ -231,7 +231,7 @@ class CShootingAnimation : public CRangedAttackAnimation
 	uint32_t getAttackClimaxFrame() const override;
 
 public:
-	CShootingAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex dest, const CStack * defender);
+	CShootingAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest, const CStack * defender);
 
 };
 
@@ -243,7 +243,7 @@ private:
 	int catapultDamage;
 
 public:
-	CCatapultAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex dest, const CStack * defender, int _catapultDmg = 0);
+	CCatapultAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest, const CStack * defender, int _catapultDmg = 0);
 
 	void createProjectile(const Point & from, const Point & dest) const override;
 	void nextFrame() override;
@@ -262,7 +262,7 @@ class CCastAnimation : public CRangedAttackAnimation
 	uint32_t getAttackClimaxFrame() const override;
 
 public:
-	CCastAnimation(BattleInterface * owner_, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell);
+	CCastAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell);
 };
 
 struct CPointEffectParameters
@@ -313,17 +313,17 @@ public:
 	};
 
 	/// Create animation with screen-wide effect
-	CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, int effects = 0);
+	CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, int effects = 0);
 
 	/// Create animation positioned at point(s). Note that positions must be are absolute, including battleint position offset
-	CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos                 , int effects = 0);
-	CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos    , int effects = 0);
+	CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, Point pos                 , int effects = 0);
+	CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos    , int effects = 0);
 
 	/// Create animation positioned at certain hex(es)
-	CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, BattleHex hex             , int effects = 0);
-	CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<BattleHex> hex, int effects = 0);
+	CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, BattleHex hex             , int effects = 0);
+	CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, std::vector<BattleHex> hex, int effects = 0);
 
-	CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex,   int effects = 0);
+	CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex,   int effects = 0);
 	 ~CPointEffectAnimation();
 
 	bool init() override;
@@ -334,7 +334,7 @@ public:
 class CWaitingAnimation : public CBattleAnimation
 {
 protected:
-	CWaitingAnimation(BattleInterface * owner_);
+	CWaitingAnimation(BattleInterface & owner);
 public:
 	void nextFrame() override;
 };
@@ -344,7 +344,7 @@ class CWaitingProjectileAnimation : public CWaitingAnimation
 {
 	const CStack * shooter;
 public:
-	CWaitingProjectileAnimation(BattleInterface * owner_, const CStack * shooter);
+	CWaitingProjectileAnimation(BattleInterface & owner, const CStack * shooter);
 
 	bool init() override;
 };

+ 61 - 61
client/battle/BattleControlPanel.cpp

@@ -29,7 +29,7 @@
 #include "../../lib/CStack.h"
 #include "../../lib/CConfigHandler.h"
 
-BattleControlPanel::BattleControlPanel(BattleInterface * owner, const Point & position):
+BattleControlPanel::BattleControlPanel(BattleInterface & owner, const Point & position):
 	owner(owner)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
@@ -53,7 +53,7 @@ BattleControlPanel::BattleControlPanel(BattleInterface * owner, const Point & po
 	console = std::make_shared<BattleConsole>(Rect(211, 4, 406,38));
 	GH.statusbar = console;
 
-	if ( owner->tacticsMode )
+	if ( owner.tacticsMode )
 		tacticPhaseStarted();
 	else
 		tacticPhaseEnded();
@@ -81,7 +81,7 @@ void BattleControlPanel::tacticPhaseStarted()
 	btactNext = std::make_shared<CButton>(Point(213, 4), "icm011.def", std::make_pair("", ""), [&]() { bTacticNextStack();}, SDLK_SPACE);
 	btactEnd = std::make_shared<CButton>(Point(419,  4), "icm012.def", std::make_pair("", ""),  [&](){ bTacticPhaseEnd();}, SDLK_RETURN);
 	menu = std::make_shared<CPicture>("COPLACBR.BMP", 0, 0);
-	menu->colorize(owner->curInt->playerID);
+	menu->colorize(owner.curInt->playerID);
 	menu->recActions &= ~(SHOWALL | UPDATE);
 }
 void BattleControlPanel::tacticPhaseEnded()
@@ -92,13 +92,13 @@ void BattleControlPanel::tacticPhaseEnded()
 	btactEnd.reset();
 
 	menu = std::make_shared<CPicture>("CBAR.BMP", 0, 0);
-	menu->colorize(owner->curInt->playerID);
+	menu->colorize(owner.curInt->playerID);
 	menu->recActions &= ~(SHOWALL | UPDATE);
 }
 
 void BattleControlPanel::bOptionsf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
 	CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
@@ -108,13 +108,13 @@ void BattleControlPanel::bOptionsf()
 
 void BattleControlPanel::bSurrenderf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
-	int cost = owner->curInt->cb->battleGetSurrenderCost();
+	int cost = owner.curInt->cb->battleGetSurrenderCost();
 	if(cost >= 0)
 	{
-		std::string enemyHeroName = owner->curInt->cb->battleGetEnemyHero().name;
+		std::string enemyHeroName = owner.curInt->cb->battleGetEnemyHero().name;
 		if(enemyHeroName.empty())
 		{
 			logGlobal->warn("Surrender performed without enemy hero, should not happen!");
@@ -122,110 +122,110 @@ void BattleControlPanel::bSurrenderf()
 		}
 
 		std::string surrenderMessage = boost::str(boost::format(CGI->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold."
-		owner->curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, nullptr);
+		owner.curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, nullptr);
 	}
 }
 
 void BattleControlPanel::bFleef()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
-	if ( owner->curInt->cb->battleCanFlee() )
+	if ( owner.curInt->cb->battleCanFlee() )
 	{
 		CFunctionList<void()> ony = std::bind(&BattleControlPanel::reallyFlee,this);
-		owner->curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
+		owner.curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
 	}
 	else
 	{
 		std::vector<std::shared_ptr<CComponent>> comps;
 		std::string heroName;
 		//calculating fleeing hero's name
-		if (owner->attackingHeroInstance)
-			if (owner->attackingHeroInstance->tempOwner == owner->curInt->cb->getMyColor())
-				heroName = owner->attackingHeroInstance->name;
-		if (owner->defendingHeroInstance)
-			if (owner->defendingHeroInstance->tempOwner == owner->curInt->cb->getMyColor())
-				heroName = owner->defendingHeroInstance->name;
+		if (owner.attackingHeroInstance)
+			if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getMyColor())
+				heroName = owner.attackingHeroInstance->name;
+		if (owner.defendingHeroInstance)
+			if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getMyColor())
+				heroName = owner.defendingHeroInstance->name;
 		//calculating text
 		auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat!
 
 		//printing message
-		owner->curInt->showInfoDialog(boost::to_string(txt), comps);
+		owner.curInt->showInfoDialog(boost::to_string(txt), comps);
 	}
 }
 
 void BattleControlPanel::reallyFlee()
 {
-	owner->giveCommand(EActionType::RETREAT);
+	owner.giveCommand(EActionType::RETREAT);
 	CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
 }
 
 void BattleControlPanel::reallySurrender()
 {
-	if (owner->curInt->cb->getResourceAmount(Res::GOLD) < owner->curInt->cb->battleGetSurrenderCost())
+	if (owner.curInt->cb->getResourceAmount(Res::GOLD) < owner.curInt->cb->battleGetSurrenderCost())
 	{
-		owner->curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold!
+		owner.curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold!
 	}
 	else
 	{
-		owner->giveCommand(EActionType::SURRENDER);
+		owner.giveCommand(EActionType::SURRENDER);
 		CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
 	}
 }
 
 void BattleControlPanel::bAutofightf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
 	//Stop auto-fight mode
-	if(owner->curInt->isAutoFightOn)
+	if(owner.curInt->isAutoFightOn)
 	{
-		assert(owner->curInt->autofightingAI);
-		owner->curInt->isAutoFightOn = false;
+		assert(owner.curInt->autofightingAI);
+		owner.curInt->isAutoFightOn = false;
 		logGlobal->trace("Stopping the autofight...");
 	}
-	else if(!owner->curInt->autofightingAI)
+	else if(!owner.curInt->autofightingAI)
 	{
-		owner->curInt->isAutoFightOn = true;
+		owner.curInt->isAutoFightOn = true;
 		blockUI(true);
 
 		auto ai = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
-		ai->init(owner->curInt->env, owner->curInt->cb);
-		ai->battleStart(owner->army1, owner->army2, int3(0,0,0), owner->attackingHeroInstance, owner->defendingHeroInstance, owner->curInt->cb->battleGetMySide());
-		owner->curInt->autofightingAI = ai;
-		owner->curInt->cb->registerBattleInterface(ai);
+		ai->init(owner.curInt->env, owner.curInt->cb);
+		ai->battleStart(owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.curInt->cb->battleGetMySide());
+		owner.curInt->autofightingAI = ai;
+		owner.curInt->cb->registerBattleInterface(ai);
 
-		owner->requestAutofightingAIToTakeAction();
+		owner.requestAutofightingAIToTakeAction();
 	}
 }
 
 void BattleControlPanel::bSpellf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
-	if (!owner->myTurn)
+	if (!owner.myTurn)
 		return;
 
-	auto myHero = owner->currentHero();
+	auto myHero = owner.currentHero();
 	if(!myHero)
 		return;
 
 	CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
 
-	ESpellCastProblem::ESpellCastProblem spellCastProblem = owner->curInt->cb->battleCanCastSpell(myHero, spells::Mode::HERO);
+	ESpellCastProblem::ESpellCastProblem spellCastProblem = owner.curInt->cb->battleCanCastSpell(myHero, spells::Mode::HERO);
 
 	if(spellCastProblem == ESpellCastProblem::OK)
 	{
-		GH.pushIntT<CSpellWindow>(myHero, owner->curInt.get());
+		GH.pushIntT<CSpellWindow>(myHero, owner.curInt.get());
 	}
 	else if (spellCastProblem == ESpellCastProblem::MAGIC_IS_BLOCKED)
 	{
 		//TODO: move to spell mechanics, add more information to spell cast problem
 		//Handle Orb of Inhibition-like effects -> we want to display dialog with info, why casting is impossible
-		auto blockingBonus = owner->currentHero()->getBonusLocalFirst(Selector::type()(Bonus::BLOCK_ALL_MAGIC));
+		auto blockingBonus = owner.currentHero()->getBonusLocalFirst(Selector::type()(Bonus::BLOCK_ALL_MAGIC));
 		if (!blockingBonus)
 			return;
 
@@ -234,7 +234,7 @@ void BattleControlPanel::bSpellf()
 			const auto artID = ArtifactID(blockingBonus->sid);
 			//If we have artifact, put name of our hero. Otherwise assume it's the enemy.
 			//TODO check who *really* is source of bonus
-			std::string heroName = myHero->hasArt(artID) ? myHero->name : owner->enemyHero().name;
+			std::string heroName = myHero->hasArt(artID) ? myHero->name : owner.enemyHero().name;
 
 			//%s wields the %s, an ancient artifact which creates a p dead to all magic.
 			LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683])
@@ -245,25 +245,25 @@ void BattleControlPanel::bSpellf()
 
 void BattleControlPanel::bWaitf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
-	if (owner->stacksController->getActiveStack() != nullptr)
-		owner->giveCommand(EActionType::WAIT);
+	if (owner.stacksController->getActiveStack() != nullptr)
+		owner.giveCommand(EActionType::WAIT);
 }
 
 void BattleControlPanel::bDefencef()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
-	if (owner->stacksController->getActiveStack() != nullptr)
-		owner->giveCommand(EActionType::DEFEND);
+	if (owner.stacksController->getActiveStack() != nullptr)
+		owner.giveCommand(EActionType::DEFEND);
 }
 
 void BattleControlPanel::bConsoleUpf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
 	console->scrollUp();
@@ -271,7 +271,7 @@ void BattleControlPanel::bConsoleUpf()
 
 void BattleControlPanel::bConsoleDownf()
 {
-	if (owner->actionsController->spellcastingModeActive())
+	if (owner.actionsController->spellcastingModeActive())
 		return;
 
 	console->scrollDown();
@@ -279,38 +279,38 @@ void BattleControlPanel::bConsoleDownf()
 
 void BattleControlPanel::bTacticNextStack()
 {
-	owner->tacticNextStack(nullptr);
+	owner.tacticNextStack(nullptr);
 }
 
 void BattleControlPanel::bTacticPhaseEnd()
 {
-	owner->tacticPhaseEnd();
+	owner.tacticPhaseEnd();
 }
 
 void BattleControlPanel::blockUI(bool on)
 {
 	bool canCastSpells = false;
-	auto hero = owner->curInt->cb->battleGetMyHero();
+	auto hero = owner.curInt->cb->battleGetMyHero();
 
 	if(hero)
 	{
-		ESpellCastProblem::ESpellCastProblem spellcastingProblem = owner->curInt->cb->battleCanCastSpell(hero, spells::Mode::HERO);
+		ESpellCastProblem::ESpellCastProblem spellcastingProblem = owner.curInt->cb->battleCanCastSpell(hero, spells::Mode::HERO);
 
 		//if magic is blocked, we leave button active, so the message can be displayed after button click
 		canCastSpells = spellcastingProblem == ESpellCastProblem::OK || spellcastingProblem == ESpellCastProblem::MAGIC_IS_BLOCKED;
 	}
 
-	bool canWait = owner->stacksController->getActiveStack() ? !owner->stacksController->getActiveStack()->waitedThisTurn : false;
+	bool canWait = owner.stacksController->getActiveStack() ? !owner.stacksController->getActiveStack()->waitedThisTurn : false;
 
 	bOptions->block(on);
-	bFlee->block(on || !owner->curInt->cb->battleCanFlee());
-	bSurrender->block(on || owner->curInt->cb->battleGetSurrenderCost() < 0);
+	bFlee->block(on || !owner.curInt->cb->battleCanFlee());
+	bSurrender->block(on || owner.curInt->cb->battleGetSurrenderCost() < 0);
 
 	// block only if during enemy turn and auto-fight is off
 	// otherwise - crash on accessing non-exisiting active stack
-	bAutofight->block(!owner->curInt->isAutoFightOn && !owner->stacksController->getActiveStack());
+	bAutofight->block(!owner.curInt->isAutoFightOn && !owner.stacksController->getActiveStack());
 
-	if (owner->tacticsMode && btactEnd && btactNext)
+	if (owner.tacticsMode && btactEnd && btactNext)
 	{
 		btactNext->block(on);
 		btactEnd->block(on);
@@ -322,7 +322,7 @@ void BattleControlPanel::blockUI(bool on)
 	}
 
 
-	bSpell->block(on || owner->tacticsMode || !canCastSpells);
-	bWait->block(on || owner->tacticsMode || !canWait);
-	bDefence->block(on || owner->tacticsMode);
+	bSpell->block(on || owner.tacticsMode || !canCastSpells);
+	bWait->block(on || owner.tacticsMode || !canWait);
+	bDefence->block(on || owner.tacticsMode);
 }

+ 2 - 2
client/battle/BattleControlPanel.h

@@ -23,7 +23,7 @@ class BattleConsole;
 /// GUI object that handles functionality of panel at the bottom of combat screen
 class BattleControlPanel : public CIntObject
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	std::shared_ptr<CPicture> menu;
 
@@ -71,6 +71,6 @@ public:
 	/// Toggle UI to displaying battle log in place of tactics UI
 	void tacticPhaseEnded();
 
-	BattleControlPanel(BattleInterface * owner, const Point & position);
+	BattleControlPanel(BattleInterface & owner, const Point & position);
 };
 

+ 9 - 9
client/battle/BattleEffectsController.cpp

@@ -31,7 +31,7 @@
 #include "../../lib/IGameEventsReceiver.h"
 #include "../../lib/CGeneralTextHandler.h"
 
-BattleEffectsController::BattleEffectsController(BattleInterface * owner):
+BattleEffectsController::BattleEffectsController(BattleInterface & owner):
 	owner(owner)
 {}
 
@@ -44,14 +44,14 @@ void BattleEffectsController::displayEffect(EBattleEffect::EBattleEffect effect,
 {
 	std::string customAnim = graphics->battleACToDef[effect][0];
 
-	owner->stacksController->addNewAnim(new CPointEffectAnimation(owner, soundBase::soundID(soundID), customAnim, destTile));
+	owner.stacksController->addNewAnim(new CPointEffectAnimation(owner, soundBase::soundID(soundID), customAnim, destTile));
 }
 
 void BattleEffectsController::displayCustomEffects(const std::vector<CustomEffectInfo> & customEffects)
 {
 	for(const CustomEffectInfo & one : customEffects)
 	{
-		const CStack * s = owner->curInt->cb->battleGetStackByID(one.stack, false);
+		const CStack * s = owner.curInt->cb->battleGetStackByID(one.stack, false);
 
 		assert(s);
 		assert(one.effect != 0);
@@ -62,7 +62,7 @@ void BattleEffectsController::displayCustomEffects(const std::vector<CustomEffec
 
 void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bte)
 {
-	const CStack * stack = owner->curInt->cb->battleGetStackByID(bte.stackID);
+	const CStack * stack = owner.curInt->cb->battleGetStackByID(bte.stackID);
 	if(!stack)
 	{
 		logGlobal->error("Invalid stack ID %d", bte.stackID);
@@ -89,7 +89,7 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
 			std::string hlp = CGI->generaltexth->allTexts[33];
 			boost::algorithm::replace_first(hlp,"%s",(stack->getName()));
 			displayEffect(EBattleEffect::GOOD_MORALE, soundBase::GOODMRLE, stack->getPosition());
-			owner->controlPanel->console->addText(hlp);
+			owner.controlPanel->console->addText(hlp);
 			break;
 		}
 		default:
@@ -100,21 +100,21 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
 
 void BattleEffectsController::startAction(const BattleAction* action)
 {
-	const CStack *stack = owner->curInt->cb->battleGetStackByID(action->stackNumber);
+	const CStack *stack = owner.curInt->cb->battleGetStackByID(action->stackNumber);
 
 	switch(action->actionType)
 	{
 	case EActionType::WAIT:
-		owner->controlPanel->console->addText(stack->formatGeneralMessage(136));
+		owner.controlPanel->console->addText(stack->formatGeneralMessage(136));
 		break;
 	case EActionType::BAD_MORALE:
-		owner->controlPanel->console->addText(stack->formatGeneralMessage(-34));
+		owner.controlPanel->console->addText(stack->formatGeneralMessage(-34));
 		displayEffect(EBattleEffect::BAD_MORALE, soundBase::BADMRLE, stack->getPosition());
 		break;
 	}
 
 	//displaying special abilities
-	auto actionTarget = action->getTarget(owner->curInt->cb.get());
+	auto actionTarget = action->getTarget(owner.curInt->cb.get());
 	switch(action->actionType)
 	{
 		case EActionType::STACK_HEAL:

+ 2 - 2
client/battle/BattleEffectsController.h

@@ -59,13 +59,13 @@ struct BattleEffect
 /// Controls rendering of effects in battle, e.g. from spells, abilities and various other actions like morale
 class BattleEffectsController
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	/// list of current effects that are being displayed on screen (spells & creature abilities)
 	std::vector<BattleEffect> battleEffects;
 
 public:
-	BattleEffectsController(BattleInterface * owner);
+	BattleEffectsController(BattleInterface & owner);
 
 	void startAction(const BattleAction* action);
 

+ 51 - 51
client/battle/BattleFieldController.cpp

@@ -33,21 +33,21 @@
 #include "../../lib/CStack.h"
 #include "../../lib/spells/ISpellMechanics.h"
 
-BattleFieldController::BattleFieldController(BattleInterface * owner):
+BattleFieldController::BattleFieldController(BattleInterface & owner):
 	owner(owner),
 	attackingHex(BattleHex::INVALID)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
-	pos.w = owner->pos.w;
-	pos.h = owner->pos.h;
+	pos.w = owner.pos.w;
+	pos.h = owner.pos.h;
 
 	//preparing cells and hexes
 	cellBorder = IImage::createFromFile("CCELLGRD.BMP");
 	cellShade = IImage::createFromFile("CCELLSHD.BMP");
 
-	if(!owner->siegeController)
+	if(!owner.siegeController)
 	{
-		auto bfieldType = owner->curInt->cb->battleGetBattlefieldType();
+		auto bfieldType = owner.curInt->cb->battleGetBattlefieldType();
 
 		if(bfieldType == BattleField::NONE)
 			logGlobal->error("Invalid battlefield returned for current battle");
@@ -56,7 +56,7 @@ BattleFieldController::BattleFieldController(BattleInterface * owner):
 	}
 	else
 	{
-		std::string backgroundName = owner->siegeController->getBattleBackgroundName();
+		std::string backgroundName = owner.siegeController->getBattleBackgroundName();
 		background = IImage::createFromFile(backgroundName);
 	}
 
@@ -80,11 +80,11 @@ BattleFieldController::BattleFieldController(BattleInterface * owner):
 		auto hex = std::make_shared<ClickableHex>();
 		hex->myNumber = h;
 		hex->pos = hexPositionAbsolute(h);
-		hex->myInterface = owner;
+		hex->myInterface = &owner;
 		bfield.push_back(hex);
 	}
 
-	auto accessibility = owner->curInt->cb->getAccesibility();
+	auto accessibility = owner.curInt->cb->getAccesibility();
 	for(int i = 0; i < accessibility.size(); i++)
 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
 }
@@ -97,12 +97,12 @@ void BattleFieldController::renderBattlefield(Canvas & canvas)
 
 	renderer.execute(canvas);
 
-	owner->projectilesController->showProjectiles(canvas);
+	owner.projectilesController->showProjectiles(canvas);
 }
 
 void BattleFieldController::showBackground(Canvas & canvas)
 {
-	if (owner->stacksController->getActiveStack() != nullptr ) //&& creAnims[stacksController->getActiveStack()->ID]->isIdle() //show everything with range
+	if (owner.stacksController->getActiveStack() != nullptr ) //&& creAnims[stacksController->getActiveStack()->ID]->isIdle() //show everything with range
 		showBackgroundImageWithHexes(canvas);
 	else
 		showBackgroundImage(canvas);
@@ -113,38 +113,38 @@ void BattleFieldController::showBackground(Canvas & canvas)
 
 void BattleFieldController::showBackgroundImage(Canvas & canvas)
 {
-	canvas.draw(background, owner->pos.topLeft());
+	canvas.draw(background, owner.pos.topLeft());
 
-	owner->obstacleController->showAbsoluteObstacles(canvas, pos.topLeft());
-	if ( owner->siegeController )
-		owner->siegeController->showAbsoluteObstacles(canvas, pos.topLeft());
+	owner.obstacleController->showAbsoluteObstacles(canvas, pos.topLeft());
+	if ( owner.siegeController )
+		owner.siegeController->showAbsoluteObstacles(canvas, pos.topLeft());
 
 	if (settings["battle"]["cellBorders"].Bool())
-		canvas.draw(*cellBorders, owner->pos.topLeft());
+		canvas.draw(*cellBorders, owner.pos.topLeft());
 }
 
 void BattleFieldController::showBackgroundImageWithHexes(Canvas & canvas)
 {
-	canvas.draw(*backgroundWithHexes.get(), owner->pos.topLeft());
+	canvas.draw(*backgroundWithHexes.get(), owner.pos.topLeft());
 }
 
 void BattleFieldController::redrawBackgroundWithHexes()
 {
-	const CStack *activeStack = owner->stacksController->getActiveStack();
+	const CStack *activeStack = owner.stacksController->getActiveStack();
 	std::vector<BattleHex> attackableHexes;
 	if (activeStack)
-		occupyableHexes = owner->curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
+		occupyableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
 
-	auto accessibility = owner->curInt->cb->getAccesibility();
+	auto accessibility = owner.curInt->cb->getAccesibility();
 
 	for(int i = 0; i < accessibility.size(); i++)
 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
 
 	//prepare background graphic with hexes and shaded hexes
 	backgroundWithHexes->draw(background, Point(0,0));
-	owner->obstacleController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0));
-	if ( owner->siegeController )
-		owner->siegeController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0));
+	owner.obstacleController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0));
+	if ( owner.siegeController )
+		owner.siegeController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0));
 
 	if (settings["battle"]["stackRange"].Bool())
 	{
@@ -173,7 +173,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
 {
 	std::set<BattleHex> result;
 
-	if ( !owner->stacksController->getActiveStack())
+	if ( !owner.stacksController->getActiveStack())
 		return result;
 
 	if ( !settings["battle"]["stackRange"].Bool())
@@ -181,15 +181,15 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
 
 	auto hoveredHex = getHoveredHex();
 
-	std::set<BattleHex> set = owner->curInt->cb->battleGetAttackedHexes(owner->stacksController->getActiveStack(), hoveredHex, attackingHex);
+	std::set<BattleHex> set = owner.curInt->cb->battleGetAttackedHexes(owner.stacksController->getActiveStack(), hoveredHex, attackingHex);
 	for(BattleHex hex : set)
 		result.insert(hex);
 
 	// display the movement shadow of the stack at b (i.e. stack under mouse)
-	const CStack * const shere = owner->curInt->cb->battleGetStackByPos(hoveredHex, false);
-	if(shere && shere != owner->stacksController->getActiveStack() && shere->alive())
+	const CStack * const shere = owner.curInt->cb->battleGetStackByPos(hoveredHex, false);
+	if(shere && shere != owner.stacksController->getActiveStack() && shere->alive())
 	{
-		std::vector<BattleHex> v = owner->curInt->cb->battleGetAvailableHexes(shere, true, nullptr);
+		std::vector<BattleHex> v = owner.curInt->cb->battleGetAvailableHexes(shere, true, nullptr);
 		for(BattleHex hex : v)
 			result.insert(hex);
 	}
@@ -209,22 +209,22 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
 
 	spells::Mode mode = spells::Mode::HERO;
 
-	if(owner->actionsController->spellcastingModeActive())//hero casts spell
+	if(owner.actionsController->spellcastingModeActive())//hero casts spell
 	{
-		spell = owner->actionsController->selectedSpell().toSpell();
-		caster = owner->getActiveHero();
+		spell = owner.actionsController->selectedSpell().toSpell();
+		caster = owner.getActiveHero();
 	}
-	else if(owner->stacksController->activeStackSpellToCast() != SpellID::NONE)//stack casts spell
+	else if(owner.stacksController->activeStackSpellToCast() != SpellID::NONE)//stack casts spell
 	{
-		spell = SpellID(owner->stacksController->activeStackSpellToCast()).toSpell();
-		caster = owner->stacksController->getActiveStack();
+		spell = SpellID(owner.stacksController->activeStackSpellToCast()).toSpell();
+		caster = owner.stacksController->getActiveStack();
 		mode = spells::Mode::CREATURE_ACTIVE;
 	}
 
 	if(caster && spell) //when casting spell
 	{
 		// printing shaded hex(es)
-		spells::BattleCast event(owner->curInt->cb.get(), caster, mode, spell);
+		spells::BattleCast event(owner.curInt->cb.get(), caster, mode, spell);
 		auto shaded = spell->battleMechanics(&event)->rangeInHexes(hoveredHex);
 
 		for(BattleHex shadedHex : shaded)
@@ -233,7 +233,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
 				result.insert(shadedHex);
 		}
 	}
-	else if(owner->active) //always highlight pointed hex
+	else if(owner.active) //always highlight pointed hex
 	{
 		if(hoveredHex.getX() != 0 && hoveredHex.getX() != GameConstants::BFIELD_WIDTH - 1)
 			result.insert(hoveredHex);
@@ -280,7 +280,7 @@ Rect BattleFieldController::hexPositionLocal(BattleHex hex) const
 
 Rect BattleFieldController::hexPositionAbsolute(BattleHex hex) const
 {
-	return hexPositionLocal(hex) + owner->pos.topLeft();
+	return hexPositionLocal(hex) + owner.pos.topLeft();
 }
 
 bool BattleFieldController::isPixelInHex(Point const & position)
@@ -317,7 +317,7 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber)
 	sectorCursor.push_back(12);
 	sectorCursor.push_back(7);
 
-	const bool doubleWide = owner->stacksController->getActiveStack()->doubleWide();
+	const bool doubleWide = owner.stacksController->getActiveStack()->doubleWide();
 	bool aboveAttackable = true, belowAttackable = true;
 
 	// Exclude directions which cannot be attacked from.
@@ -478,12 +478,12 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 	{
 	case 12: //from bottom right
 		{
-			bool doubleWide = owner->stacksController->getActiveStack()->doubleWide();
+			bool doubleWide = owner.stacksController->getActiveStack()->doubleWide();
 			destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH+1 ) +
-				(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER && doubleWide ? 1 : 0);
+				(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER && doubleWide ? 1 : 0);
 			if(vstd::contains(occupyableHexes, destHex))
 				return destHex;
-			else if(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			else if(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
 				if (vstd::contains(occupyableHexes, destHex+1))
 					return destHex+1;
@@ -500,7 +500,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 			destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH-1 : GameConstants::BFIELD_WIDTH );
 			if (vstd::contains(occupyableHexes, destHex))
 				return destHex;
-			else if(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			else if(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
 				if(vstd::contains(occupyableHexes, destHex+1))
 					return destHex+1;
@@ -514,9 +514,9 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 		}
 	case 8: //from left
 		{
-			if(owner->stacksController->getActiveStack()->doubleWide() && owner->stacksController->getActiveStack()->side == BattleSide::DEFENDER)
+			if(owner.stacksController->getActiveStack()->doubleWide() && owner.stacksController->getActiveStack()->side == BattleSide::DEFENDER)
 			{
-				std::vector<BattleHex> acc = owner->curInt->cb->battleGetAvailableHexes(owner->stacksController->getActiveStack());
+				std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack());
 				if (vstd::contains(acc, myNumber))
 					return myNumber - 1;
 				else
@@ -533,7 +533,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 			destHex = myNumber - ((myNumber/GameConstants::BFIELD_WIDTH) % 2 ? GameConstants::BFIELD_WIDTH + 1 : GameConstants::BFIELD_WIDTH);
 			if(vstd::contains(occupyableHexes, destHex))
 				return destHex;
-			else if(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			else if(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
 				if(vstd::contains(occupyableHexes, destHex+1))
 					return destHex+1;
@@ -547,12 +547,12 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 		}
 	case 10: //from top right
 		{
-			bool doubleWide = owner->stacksController->getActiveStack()->doubleWide();
+			bool doubleWide = owner.stacksController->getActiveStack()->doubleWide();
 			destHex = myNumber - ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH-1 ) +
-				(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER && doubleWide ? 1 : 0);
+				(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER && doubleWide ? 1 : 0);
 			if(vstd::contains(occupyableHexes, destHex))
 				return destHex;
-			else if(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			else if(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
 				if(vstd::contains(occupyableHexes, destHex+1))
 					return destHex+1;
@@ -566,9 +566,9 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 		}
 	case 11: //from right
 		{
-			if(owner->stacksController->getActiveStack()->doubleWide() && owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			if(owner.stacksController->getActiveStack()->doubleWide() && owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
-				std::vector<BattleHex> acc = owner->curInt->cb->battleGetAvailableHexes(owner->stacksController->getActiveStack());
+				std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack());
 				if(vstd::contains(acc, myNumber))
 					return myNumber + 1;
 				else
@@ -585,7 +585,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 			destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH+1 );
 			if(vstd::contains(occupyableHexes, destHex))
 				return destHex;
-			else if(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			else if(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
 				if(vstd::contains(occupyableHexes, destHex+1))
 					return destHex+1;
@@ -602,7 +602,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber)
 			destHex = myNumber - ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH-1 );
 			if (vstd::contains(occupyableHexes, destHex))
 				return destHex;
-			else if(owner->stacksController->getActiveStack()->side == BattleSide::ATTACKER)
+			else if(owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER)
 			{
 				if(vstd::contains(occupyableHexes, destHex+1))
 					return destHex+1;

+ 2 - 2
client/battle/BattleFieldController.h

@@ -29,7 +29,7 @@ class BattleInterface;
 /// Handles battlefield grid as well as rendering of background layer of battle interface
 class BattleFieldController : public CIntObject
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	std::shared_ptr<IImage> background;
 	std::shared_ptr<IImage> cellBorder;
@@ -63,7 +63,7 @@ class BattleFieldController : public CIntObject
 	void showHighlightedHexes(Canvas & canvas);
 
 public:
-	BattleFieldController(BattleInterface * owner);
+	BattleFieldController(BattleInterface & owner);
 
 	void redrawBackgroundWithHexes();
 	void renderBattlefield(Canvas & canvas);

+ 25 - 25
client/battle/BattleInterface.cpp

@@ -55,8 +55,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
 {
 	OBJ_CONSTRUCTION;
 
-	projectilesController.reset(new BattleProjectileController(this));
-
 	if(spectatorInt)
 	{
 		curInt = spectatorInt;
@@ -90,7 +88,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
 	else
 		embedQueue = screen->h < 700 || queueSize == "small";
 
-	queue = std::make_shared<StackQueue>(embedQueue, this);
+	queue = std::make_shared<StackQueue>(embedQueue, *this);
 	if(!embedQueue)
 	{
 		if (settings["battle"]["showQueue"].Bool())
@@ -99,10 +97,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
 		queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
 	}
 
-	//preparing siege info
-	const CGTownInstance *town = curInt->cb->battleGetDefendedTown();
-	if(town && town->hasFort())
-		siegeController.reset(new BattleSiegeController(this, town));
 
 	CPlayerInterface::battleInt = this;
 
@@ -110,13 +104,16 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
 	this->army1 = army1;
 	this->army2 = army2;
 
-	controlPanel = std::make_shared<BattleControlPanel>(this, Point(0, 556));
+	const CGTownInstance *town = curInt->cb->battleGetDefendedTown();
+	if(town && town->hasFort())
+		siegeController.reset(new BattleSiegeController(*this, town));
 
-	//preparing menu background and terrain
-	fieldController.reset( new BattleFieldController(this));
-	stacksController.reset( new BattleStacksController(this));
-	actionsController.reset( new BattleActionsController(this));
-	effectsController.reset(new BattleEffectsController(this));
+	controlPanel = std::make_shared<BattleControlPanel>(*this, Point(0, 556));
+	projectilesController.reset(new BattleProjectileController(*this));
+	fieldController.reset( new BattleFieldController(*this));
+	stacksController.reset( new BattleStacksController(*this));
+	actionsController.reset( new BattleActionsController(*this));
+	effectsController.reset(new BattleEffectsController(*this));
 
 	//loading hero animations
 	if(hero1) // attacking hero
@@ -134,7 +131,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
 				battleImage = hero1->type->heroClass->imageBattleMale;
 		}
 
-		attackingHero = std::make_shared<BattleHero>(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, this);
+		attackingHero = std::make_shared<BattleHero>(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, *this);
 
 		auto img = attackingHero->animation->getImage(0, 0, true);
 		if(img)
@@ -158,14 +155,14 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
 				battleImage = hero2->type->heroClass->imageBattleMale;
 		}
 
-		defendingHero = std::make_shared<BattleHero>(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, this);
+		defendingHero = std::make_shared<BattleHero>(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, *this);
 
 		auto img = defendingHero->animation->getImage(0, 0, true);
 		if(img)
 			defendingHero->pos = genRect(img->height(), img->width(), pos.x + 693, pos.y - 19);
 	}
 
-	obstacleController.reset(new BattleObstacleController(this));
+	obstacleController.reset(new BattleObstacleController(*this));
 
 	if(tacticsMode)
 		tacticNextStack(nullptr);
@@ -502,7 +499,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 		{
 			displaySpellCast(spellID, casterStack->getPosition());
 
-			stacksController->addNewAnim(new CCastAnimation(this, casterStack, sc->tile, curInt->cb->battleGetStackByPos(sc->tile), spell));
+			stacksController->addNewAnim(new CCastAnimation(*this, casterStack, sc->tile, curInt->cb->battleGetStackByPos(sc->tile), spell));
 		}
 		else
 		if (sc->tile.isValid() && !spell->animationInfo.projectile.empty())
@@ -518,7 +515,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 			projectilesController->emitStackProjectile( nullptr );
 
 			// wait fo projectile to end
-			stacksController->addNewAnim(new CWaitingProjectileAnimation(this, nullptr));
+			stacksController->addNewAnim(new CWaitingProjectileAnimation(*this, nullptr));
 		}
 	}
 
@@ -548,8 +545,8 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 	{
 		Point leftHero = Point(15, 30) + pos;
 		Point rightHero = Point(755, 30) + pos;
-		stacksController->addNewAnim(new CPointEffectAnimation(this, soundBase::invalid, sc->side ? "SP07_A.DEF" : "SP07_B.DEF", leftHero));
-		stacksController->addNewAnim(new CPointEffectAnimation(this, soundBase::invalid, sc->side ? "SP07_B.DEF" : "SP07_A.DEF", rightHero));
+		stacksController->addNewAnim(new CPointEffectAnimation(*this, soundBase::invalid, sc->side ? "SP07_A.DEF" : "SP07_B.DEF", leftHero));
+		stacksController->addNewAnim(new CPointEffectAnimation(*this, soundBase::invalid, sc->side ? "SP07_B.DEF" : "SP07_A.DEF", rightHero));
 	}
 }
 
@@ -589,7 +586,7 @@ void BattleInterface::displaySpellAnimationQueue(const CSpell::TAnimationQueue &
 	for(const CSpell::TAnimation & animation : q)
 	{
 		if(animation.pause > 0)
-			stacksController->addNewAnim(new CDummyAnimation(this, animation.pause));
+			stacksController->addNewAnim(new CDummyAnimation(*this, animation.pause));
 		else
 		{
 			int flags = 0;
@@ -604,9 +601,9 @@ void BattleInterface::displaySpellAnimationQueue(const CSpell::TAnimationQueue &
 				flags |= CPointEffectAnimation::SCREEN_FILL;
 
 			if (!destinationTile.isValid())
-				stacksController->addNewAnim(new CPointEffectAnimation(this, soundBase::invalid, animation.resourceName, flags));
+				stacksController->addNewAnim(new CPointEffectAnimation(*this, soundBase::invalid, animation.resourceName, flags));
 			else
-				stacksController->addNewAnim(new CPointEffectAnimation(this, soundBase::invalid, animation.resourceName, destinationTile, flags));
+				stacksController->addNewAnim(new CPointEffectAnimation(*this, soundBase::invalid, animation.resourceName, destinationTile, flags));
 		}
 	}
 }
@@ -827,10 +824,13 @@ void BattleInterface::obstaclePlaced(const std::vector<std::shared_ptr<const COb
 
 const CGHeroInstance *BattleInterface::currentHero() const
 {
-	if (attackingHeroInstance->tempOwner == curInt->playerID)
+	if (attackingHeroInstance && attackingHeroInstance->tempOwner == curInt->playerID)
 		return attackingHeroInstance;
-	else
+
+	if (defendingHeroInstance && defendingHeroInstance->tempOwner == curInt->playerID)
 		return defendingHeroInstance;
+
+	return nullptr;
 }
 
 InfoAboutHero BattleInterface::enemyHero() const

+ 12 - 12
client/battle/BattleInterfaceClasses.cpp

@@ -262,10 +262,10 @@ void BattleHero::switchToNextPhase()
 	currentFrame = firstFrame;
 }
 
-BattleHero::BattleHero(const std::string & animationPath, bool flipG, PlayerColor player, const CGHeroInstance * hero, const BattleInterface * owner):
+BattleHero::BattleHero(const std::string & animationPath, bool flipG, PlayerColor player, const CGHeroInstance * hero, const BattleInterface & owner):
     flip(flipG),
     myHero(hero),
-    myOwner(owner),
+	myOwner(&owner),
     phase(1),
     nextPhase(0),
     flagAnim(0),
@@ -331,24 +331,24 @@ HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
 	labels.push_back(std::make_shared<CLabel>(39, 186, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints)));
 }
 
-BattleOptionsWindow::BattleOptionsWindow(BattleInterface *owner):
+BattleOptionsWindow::BattleOptionsWindow(BattleInterface & owner):
 	CWindowObject(PLAYER_COLORED, "comopbck.bmp")
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 
-	auto viewGrid = std::make_shared<CToggleButton>(Point(25, 56), "sysopchk.def", CGI->generaltexth->zelp[427], [=](bool on){owner->setPrintCellBorders(on);} );
+	auto viewGrid = std::make_shared<CToggleButton>(Point(25, 56), "sysopchk.def", CGI->generaltexth->zelp[427], [&](bool on){owner.setPrintCellBorders(on);} );
 	viewGrid->setSelected(settings["battle"]["cellBorders"].Bool());
 	toggles.push_back(viewGrid);
 
-	auto movementShadow = std::make_shared<CToggleButton>(Point(25, 89), "sysopchk.def", CGI->generaltexth->zelp[428], [=](bool on){owner->setPrintStackRange(on);});
+	auto movementShadow = std::make_shared<CToggleButton>(Point(25, 89), "sysopchk.def", CGI->generaltexth->zelp[428], [&](bool on){owner.setPrintStackRange(on);});
 	movementShadow->setSelected(settings["battle"]["stackRange"].Bool());
 	toggles.push_back(movementShadow);
 
-	auto mouseShadow = std::make_shared<CToggleButton>(Point(25, 122), "sysopchk.def", CGI->generaltexth->zelp[429], [=](bool on){owner->setPrintMouseShadow(on);});
+	auto mouseShadow = std::make_shared<CToggleButton>(Point(25, 122), "sysopchk.def", CGI->generaltexth->zelp[429], [&](bool on){owner.setPrintMouseShadow(on);});
 	mouseShadow->setSelected(settings["battle"]["mouseShadow"].Bool());
 	toggles.push_back(mouseShadow);
 
-	animSpeeds = std::make_shared<CToggleGroup>([=](int value){ owner->setAnimSpeed(value);});
+	animSpeeds = std::make_shared<CToggleGroup>([&](int value){ owner.setAnimSpeed(value);});
 
 	std::shared_ptr<CToggleButton> toggle;
 	toggle = std::make_shared<CToggleButton>(Point( 28, 225), "sysopb9.def", CGI->generaltexth->zelp[422]);
@@ -360,7 +360,7 @@ BattleOptionsWindow::BattleOptionsWindow(BattleInterface *owner):
 	toggle = std::make_shared<CToggleButton>(Point(156, 225), "sysob11.def", CGI->generaltexth->zelp[424]);
 	animSpeeds->addToggle(100, toggle);
 
-	animSpeeds->setSelected(owner->getAnimSpeed());
+	animSpeeds->setSelected(owner.getAnimSpeed());
 
 	setToDefault = std::make_shared<CButton>(Point(246, 359), "codefaul.def", CGI->generaltexth->zelp[393], [&](){ bDefaultf(); });
 	setToDefault->setImageOrder(1, 0, 2, 3);
@@ -648,9 +648,9 @@ void ClickableHex::clickRight(tribool down, bool previousState)
 	}
 }
 
-StackQueue::StackQueue(bool Embedded, BattleInterface * _owner)
+StackQueue::StackQueue(bool Embedded, BattleInterface & owner)
 	: embedded(Embedded),
-	owner(_owner)
+	owner(owner)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 	if(embedded)
@@ -689,7 +689,7 @@ void StackQueue::update()
 {
 	std::vector<battle::Units> queueData;
 
-	owner->getCurrentPlayerInterface()->cb->battleGetTurnOrder(queueData, stackBoxes.size(), 0);
+	owner.getCurrentPlayerInterface()->cb->battleGetTurnOrder(queueData, stackBoxes.size(), 0);
 
 	size_t boxIndex = 0;
 
@@ -705,7 +705,7 @@ void StackQueue::update()
 
 int32_t StackQueue::getSiegeShooterIconID()
 {
-	return owner->siegeController->getSiegedTown()->town->faction->index;
+	return owner.siegeController->getSiegedTown()->town->faction->index;
 }
 
 StackQueue::StackBox::StackBox(StackQueue * owner):

+ 4 - 6
client/battle/BattleInterfaceClasses.h

@@ -97,7 +97,7 @@ public:
 	void hover(bool on) override;
 	void clickLeft(tribool down, bool previousState) override; //call-in
 	void clickRight(tribool down, bool previousState) override; //call-in
-	BattleHero(const std::string & animationPath, bool filpG, PlayerColor player, const CGHeroInstance * hero, const BattleInterface * owner);
+	BattleHero(const std::string & animationPath, bool filpG, PlayerColor player, const CGHeroInstance * hero, const BattleInterface & owner);
 };
 
 class HeroInfoWindow : public CWindowObject
@@ -119,7 +119,7 @@ private:
 	std::vector<std::shared_ptr<CLabel>> labels;
 	std::vector<std::shared_ptr<CToggleButton>> toggles;
 public:
-	BattleOptionsWindow(BattleInterface * owner);
+	BattleOptionsWindow(BattleInterface & owner);
 
 	void bDefaultf(); //default button callback
 	void bExitf(); //exit button callback
@@ -151,8 +151,6 @@ private:
 	bool setAlterText; //if true, this hex has set alternative text in console and will clean it
 public:
 	ui32 myNumber; //number of hex in commonly used format
-	//bool accessible; //if true, this hex is accessible for units
-	//CStack * ourStack;
 	bool strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering)
 	BattleInterface * myInterface; //interface that owns me
 
@@ -183,7 +181,7 @@ class StackQueue : public CIntObject
 	static const int QUEUE_SIZE = 10;
 	std::shared_ptr<CFilledTexture> background;
 	std::vector<std::shared_ptr<StackBox>> stackBoxes;
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	std::shared_ptr<CAnimation> icons;
 	std::shared_ptr<CAnimation> stateIcons;
@@ -192,6 +190,6 @@ class StackQueue : public CIntObject
 public:
 	const bool embedded;
 
-	StackQueue(bool Embedded, BattleInterface * _owner);
+	StackQueue(bool Embedded, BattleInterface & owner);
 	void update();
 };

+ 8 - 8
client/battle/BattleObstacleController.cpp

@@ -24,10 +24,10 @@
 #include "../../lib/battle/CObstacleInstance.h"
 #include "../../lib/ObstacleHandler.h"
 
-BattleObstacleController::BattleObstacleController(BattleInterface * owner):
+BattleObstacleController::BattleObstacleController(BattleInterface & owner):
 	owner(owner)
 {
-	auto obst = owner->curInt->cb->battleGetAllObstacles();
+	auto obst = owner.curInt->cb->battleGetAllObstacles();
 	for(auto & elem : obst)
 	{
 		if ( elem->obstacleType == CObstacleInstance::MOAT )
@@ -104,10 +104,10 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 		//we assume here that effect graphics have the same size as the usual obstacle image
 		// -> if we know how to blit obstacle, let's blit the effect in the same place
 		Point whereTo = getObstaclePosition(first, *oi);
-		owner->stacksController->addNewAnim(new CPointEffectAnimation(owner, soundBase::invalid, spellObstacle->appearAnimation, whereTo, oi->pos, CPointEffectAnimation::WAIT_FOR_SOUND));
+		owner.stacksController->addNewAnim(new CPointEffectAnimation(owner, soundBase::invalid, spellObstacle->appearAnimation, whereTo, oi->pos, CPointEffectAnimation::WAIT_FOR_SOUND));
 
 		//so when multiple obstacles are added, they show up one after another
-		owner->waitForAnims();
+		owner.waitForAnims();
 
 		obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin());
 		loadObstacleImage(*spellObstacle);
@@ -117,7 +117,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas, const Point & offset)
 {
 	//Blit absolute obstacles
-	for(auto & oi : owner->curInt->cb->battleGetAllObstacles())
+	for(auto & oi : owner.curInt->cb->battleGetAllObstacles())
 	{
 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
 		{
@@ -130,7 +130,7 @@ void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas, const Poin
 
 void BattleObstacleController::collectRenderableObjects(BattleRenderer & renderer)
 {
-	for (auto obstacle : owner->curInt->cb->battleGetAllObstacles())
+	for (auto obstacle : owner.curInt->cb->battleGetAllObstacles())
 	{
 		if (obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
 			continue;
@@ -151,7 +151,7 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere
 
 std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstacleInstance & oi)
 {
-	int frameIndex = (owner->animCount+1) *25 / owner->getAnimSpeed();
+	int frameIndex = (owner.animCount+1) *25 / owner.getAnimSpeed();
 	std::shared_ptr<CAnimation> animation;
 
 	if (obstacleAnimations.count(oi.uniqueID) == 0)
@@ -183,7 +183,7 @@ Point BattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> imag
 {
 	int offset = obstacle.getAnimationYOffset(image->height());
 
-	Rect r = owner->fieldController->hexPositionAbsolute(obstacle.pos);
+	Rect r = owner.fieldController->hexPositionAbsolute(obstacle.pos);
 	r.y += 42 - image->height() + offset;
 
 	return r.topLeft();

+ 2 - 2
client/battle/BattleObstacleController.h

@@ -27,7 +27,7 @@ struct Point;
 /// (with exception of moat, which is apparently handled by siege controller)
 class BattleObstacleController
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	/// cached animations of all obstacles in current battle
 	std::map<std::string, std::shared_ptr<CAnimation>> animationsCache;
@@ -45,7 +45,7 @@ class BattleObstacleController
 	Point getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle);
 
 public:
-	BattleObstacleController(BattleInterface * owner);
+	BattleObstacleController(BattleInterface & owner);
 
 	/// call-in from network pack, add newly placed obstacles with any required animations
 	void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & oi);

+ 18 - 18
client/battle/BattleProjectileController.cpp

@@ -146,16 +146,16 @@ void ProjectileRay::show(Canvas & canvas)
 	++step;
 }
 
-BattleProjectileController::BattleProjectileController(BattleInterface * owner):
+BattleProjectileController::BattleProjectileController(BattleInterface & owner):
 	owner(owner)
 {}
 
-const CCreature * BattleProjectileController::getShooter(const CStack * stack)
+const CCreature & BattleProjectileController::getShooter(const CStack * stack) const
 {
 	const CCreature * creature = stack->getCreature();
 
 	if(creature->idNumber == CreatureID::ARROW_TOWERS)
-		creature = owner->siegeController->getTurretCreature();
+		creature = owner.siegeController->getTurretCreature();
 
 	if(creature->animation.missleFrameAngles.empty())
 	{
@@ -163,17 +163,17 @@ const CCreature * BattleProjectileController::getShooter(const CStack * stack)
 		creature = CGI->creh->objects[CreatureID::ARCHER];
 	}
 
-	return creature;
+	return *creature;
 }
 
-bool BattleProjectileController::stackUsesRayProjectile(const CStack * stack)
+bool BattleProjectileController::stackUsesRayProjectile(const CStack * stack) const
 {
-	return !getShooter(stack)->animation.projectileRay.empty();
+	return !getShooter(stack).animation.projectileRay.empty();
 }
 
-bool BattleProjectileController::stackUsesMissileProjectile(const CStack * stack)
+bool BattleProjectileController::stackUsesMissileProjectile(const CStack * stack) const
 {
-	return !getShooter(stack)->animation.projectileImageName.empty();
+	return !getShooter(stack).animation.projectileImageName.empty();
 }
 
 void BattleProjectileController::initStackProjectile(const CStack * stack)
@@ -181,8 +181,8 @@ void BattleProjectileController::initStackProjectile(const CStack * stack)
 	if (!stackUsesMissileProjectile(stack))
 		return;
 
-	const CCreature * creature = getShooter(stack);
-	projectilesCache[creature->animation.projectileImageName] = createProjectileImage(creature->animation.projectileImageName);
+	const CCreature & creature = getShooter(stack);
+	projectilesCache[creature.animation.projectileImageName] = createProjectileImage(creature.animation.projectileImageName);
 }
 
 std::shared_ptr<CAnimation> BattleProjectileController::createProjectileImage(const std::string & path )
@@ -200,8 +200,8 @@ std::shared_ptr<CAnimation> BattleProjectileController::createProjectileImage(co
 
 std::shared_ptr<CAnimation> BattleProjectileController::getProjectileImage(const CStack * stack)
 {
-	const CCreature * creature = getShooter(stack);
-	std::string imageName = creature->animation.projectileImageName;
+	const CCreature & creature = getShooter(stack);
+	std::string imageName = creature.animation.projectileImageName;
 
 	if (!projectilesCache.count(imageName))
 		initStackProjectile(stack);
@@ -266,9 +266,9 @@ int BattleProjectileController::computeProjectileFlightTime( Point from, Point d
 
 int BattleProjectileController::computeProjectileFrameID( Point from, Point dest, const CStack * stack)
 {
-	const CCreature * creature = getShooter(stack);
+	const CCreature & creature = getShooter(stack);
 
-	auto & angles = creature->animation.missleFrameAngles;
+	auto & angles = creature.animation.missleFrameAngles;
 	auto animation = getProjectileImage(stack);
 
 	// only frames below maxFrame are usable: anything  higher is either no present or we don't know when it should be used
@@ -314,12 +314,12 @@ void BattleProjectileController::createCatapultProjectile(const CStack * shooter
 
 void BattleProjectileController::createProjectile(const CStack * shooter, Point from, Point dest)
 {
-	const CCreature *shooterInfo = getShooter(shooter);
+	const CCreature & shooterInfo = getShooter(shooter);
 
 	std::shared_ptr<ProjectileBase> projectile;
 	if (stackUsesRayProjectile(shooter) && stackUsesMissileProjectile(shooter))
 	{
-		logAnim->error("Mod error: Creature '%s' has both missile and ray projectiles configured. Mod should be fixed. Using ray projectile configuration...", shooterInfo->nameSing);
+		logAnim->error("Mod error: Creature '%s' has both missile and ray projectiles configured. Mod should be fixed. Using ray projectile configuration...", shooterInfo.nameSing);
 	}
 
 	if (stackUsesRayProjectile(shooter))
@@ -327,7 +327,7 @@ void BattleProjectileController::createProjectile(const CStack * shooter, Point
 		auto rayProjectile = new ProjectileRay();
 		projectile.reset(rayProjectile);
 
-		rayProjectile->rayConfig = shooterInfo->animation.projectileRay;
+		rayProjectile->rayConfig = shooterInfo.animation.projectileRay;
 	}
 	else if (stackUsesMissileProjectile(shooter))
 	{
@@ -335,7 +335,7 @@ void BattleProjectileController::createProjectile(const CStack * shooter, Point
 		projectile.reset(missileProjectile);
 
 		missileProjectile->animation = getProjectileImage(shooter);
-		missileProjectile->reverse  = !owner->stacksController->facingRight(shooter);
+		missileProjectile->reverse  = !owner.stacksController->facingRight(shooter);
 		missileProjectile->frameNum = computeProjectileFrameID(from, dest, shooter);
 	}
 

+ 5 - 5
client/battle/BattleProjectileController.h

@@ -77,7 +77,7 @@ struct ProjectileRay : ProjectileBase
 /// ... even though in H3 only 1 projectile can be on screen at any point of time
 class BattleProjectileController
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	/// all projectiles loaded during current battle
 	std::map<std::string, std::shared_ptr<CAnimation>> projectilesCache;
@@ -89,18 +89,18 @@ class BattleProjectileController
 	std::shared_ptr<CAnimation> createProjectileImage(const std::string & path );
 	void initStackProjectile(const CStack * stack);
 
-	bool stackUsesRayProjectile(const CStack * stack);
-	bool stackUsesMissileProjectile(const CStack * stack);
+	bool stackUsesRayProjectile(const CStack * stack) const;
+	bool stackUsesMissileProjectile(const CStack * stack) const;
 
 	void showProjectile(Canvas & canvas, std::shared_ptr<ProjectileBase> projectile);
 
-	const CCreature * getShooter(const CStack * stack);
+	const CCreature & getShooter(const CStack * stack) const;
 
 	int computeProjectileFrameID( Point from, Point dest, const CStack * stack);
 	int computeProjectileFlightTime( Point from, Point dest, double speed);
 
 public:
-	BattleProjectileController(BattleInterface * owner);
+	BattleProjectileController(BattleInterface & owner);
 
 	/// renders all currently active projectiles
 	void showProjectiles(Canvas & canvas);

+ 9 - 15
client/battle/BattleRenderer.cpp

@@ -18,12 +18,12 @@
 
 void BattleRenderer::collectObjects()
 {
-	owner->collectRenderableObjects(*this);
-	owner->effectsController->collectRenderableObjects(*this);
-	owner->obstacleController->collectRenderableObjects(*this);
-	owner->stacksController->collectRenderableObjects(*this);
-	if (owner->siegeController)
-		owner->siegeController->collectRenderableObjects(*this);
+	owner.collectRenderableObjects(*this);
+	owner.effectsController->collectRenderableObjects(*this);
+	owner.obstacleController->collectRenderableObjects(*this);
+	owner.stacksController->collectRenderableObjects(*this);
+	if (owner.siegeController)
+		owner.siegeController->collectRenderableObjects(*this);
 }
 
 void BattleRenderer::sortObjects()
@@ -36,13 +36,7 @@ void BattleRenderer::sortObjects()
 		if ( object.tile == BattleHex::HEX_BEFORE_ALL )
 			return -1;
 
-		if ( object.tile == BattleHex::HEX_AFTER_ALL )
-			return GameConstants::BFIELD_HEIGHT;
-
-		if ( object.tile == BattleHex::INVALID )
-			return GameConstants::BFIELD_HEIGHT;
-
-		assert(0);
+		assert( object.tile == BattleHex::HEX_AFTER_ALL || object.tile == BattleHex::INVALID);
 		return GameConstants::BFIELD_HEIGHT;
 	};
 
@@ -59,14 +53,14 @@ void BattleRenderer::renderObjects(BattleRenderer::RendererPtr targetCanvas)
 		object.functor(targetCanvas);
 }
 
-BattleRenderer::BattleRenderer(BattleInterface * owner):
+BattleRenderer::BattleRenderer(BattleInterface & owner):
 	owner(owner)
 {
 }
 
 void BattleRenderer::insert(EBattleFieldLayer layer, BattleHex tile, BattleRenderer::RenderFunctor functor)
 {
-	objects.push_back({ functor, layer, tile });
+	objects.push_back({functor, layer, tile});
 }
 
 void BattleRenderer::execute(BattleRenderer::RendererPtr targetCanvas)

+ 2 - 2
client/battle/BattleRenderer.h

@@ -33,7 +33,7 @@ public:
 	using RenderFunctor = std::function<void(RendererPtr)>;
 
 private:
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	struct RenderableInstance
 	{
@@ -47,7 +47,7 @@ private:
 	void sortObjects();
 	void renderObjects(RendererPtr targetCanvas);
 public:
-	BattleRenderer(BattleInterface * owner);
+	BattleRenderer(BattleInterface & owner);
 
 	void insert(EBattleFieldLayer layer, BattleHex tile, RenderFunctor functor);
 	void execute(RendererPtr targetCanvas);

+ 22 - 22
client/battle/BattleSiegeController.cpp

@@ -124,15 +124,15 @@ std::string BattleSiegeController::getBattleBackgroundName() const
 bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what) const
 {
 	//FIXME: use this instead of buildings test?
-	//ui8 siegeLevel = owner->curInt->cb->battleGetSiegeLevel();
+	//ui8 siegeLevel = owner.curInt->cb->battleGetSiegeLevel();
 
 	switch (what)
 	{
 	case EWallVisual::MOAT:              return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER;
 	case EWallVisual::MOAT_BANK:         return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER && town->town->faction->index != ETownType::NECROPOLIS;
-	case EWallVisual::KEEP_BATTLEMENT:   return town->hasBuilt(BuildingID::CITADEL) && EWallState::EWallState(owner->curInt->cb->battleGetWallState(EWallPart::KEEP)) != EWallState::DESTROYED;
-	case EWallVisual::UPPER_BATTLEMENT:  return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner->curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER)) != EWallState::DESTROYED;
-	case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner->curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER)) != EWallState::DESTROYED;
+	case EWallVisual::KEEP_BATTLEMENT:   return town->hasBuilt(BuildingID::CITADEL) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::KEEP)) != EWallState::DESTROYED;
+	case EWallVisual::UPPER_BATTLEMENT:  return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER)) != EWallState::DESTROYED;
+	case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER)) != EWallState::DESTROYED;
 	default:                             return true;
 	}
 }
@@ -163,11 +163,11 @@ BattleHex BattleSiegeController::getWallPiecePosition(EWallVisual::EWallVisual w
 	return wallsPositions[what];
 }
 
-BattleSiegeController::BattleSiegeController(BattleInterface * owner, const CGTownInstance *siegeTown):
+BattleSiegeController::BattleSiegeController(BattleInterface & owner, const CGTownInstance *siegeTown):
 	owner(owner),
 	town(siegeTown)
 {
-	assert(owner->fieldController.get() == nullptr); // must be created after this
+	assert(owner.fieldController.get() == nullptr); // must be created after this
 
 	for (int g = 0; g < wallPieceImages.size(); ++g)
 	{
@@ -205,7 +205,7 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con
 
 	if (posID != 0)
 	{
-		Point result = owner->pos.topLeft();
+		Point result = owner.pos.topLeft();
 		result.x += town->town->clientInfo.siegePositions[posID].x;
 		result.y += town->town->clientInfo.siegePositions[posID].y;
 		return result;
@@ -217,7 +217,7 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con
 
 void BattleSiegeController::gateStateChanged(const EGateState state)
 {
-	auto oldState = owner->curInt->cb->battleGetGateState();
+	auto oldState = owner.curInt->cb->battleGetGateState();
 	bool playSound = false;
 	auto stateId = EWallState::NONE;
 	switch(state)
@@ -272,7 +272,7 @@ BattleHex BattleSiegeController::getTurretBattleHex(EWallVisual::EWallVisual wal
 
 const CStack * BattleSiegeController::getTurretStack(EWallVisual::EWallVisual wallPiece) const
 {
-	for (auto & stack : owner->curInt->cb->battleGetAllStacks(true))
+	for (auto & stack : owner.curInt->cb->battleGetAllStacks(true))
 	{
 		if ( stack->initialPosition == getTurretBattleHex(wallPiece))
 			return stack;
@@ -298,14 +298,14 @@ void BattleSiegeController::collectRenderableObjects(BattleRenderer & renderer)
 			wallPiece == EWallVisual::UPPER_BATTLEMENT)
 		{
 			renderer.insert( EBattleFieldLayer::STACKS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererPtr canvas){
-				owner->stacksController->showStack(canvas, getTurretStack(wallPiece));
+				owner.stacksController->showStack(canvas, getTurretStack(wallPiece));
 			});
 			renderer.insert( EBattleFieldLayer::BATTLEMENTS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererPtr canvas){
-				showWallPiece(canvas, wallPiece, owner->pos.topLeft());
+				showWallPiece(canvas, wallPiece, owner.pos.topLeft());
 			});
 		}
 		renderer.insert( EBattleFieldLayer::WALLS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererPtr canvas){
-			showWallPiece(canvas, wallPiece, owner->pos.topLeft());
+			showWallPiece(canvas, wallPiece, owner.pos.topLeft());
 		});
 
 
@@ -314,14 +314,14 @@ void BattleSiegeController::collectRenderableObjects(BattleRenderer & renderer)
 
 bool BattleSiegeController::isAttackableByCatapult(BattleHex hex) const
 {
-	if (owner->tacticsMode)
+	if (owner.tacticsMode)
 		return false;
 
-	auto wallPart = owner->curInt->cb->battleHexToWallPart(hex);
-	if (!owner->curInt->cb->isWallPartPotentiallyAttackable(wallPart))
+	auto wallPart = owner.curInt->cb->battleHexToWallPart(hex);
+	if (!owner.curInt->cb->isWallPartPotentiallyAttackable(wallPart))
 		return false;
 
-	auto state = owner->curInt->cb->battleGetWallState(static_cast<int>(wallPart));
+	auto state = owner.curInt->cb->battleGetWallState(static_cast<int>(wallPart));
 	return state != EWallState::DESTROYED && state != EWallState::NONE;
 }
 
@@ -329,10 +329,10 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
 {
 	if (ca.attacker != -1)
 	{
-		const CStack *stack = owner->curInt->cb->battleGetStackByID(ca.attacker);
+		const CStack *stack = owner.curInt->cb->battleGetStackByID(ca.attacker);
 		for (auto attackInfo : ca.attackedParts)
 		{
-			owner->stacksController->addNewAnim(new CCatapultAnimation(owner, stack, attackInfo.destinationTile, nullptr, attackInfo.damageDealt));
+			owner.stacksController->addNewAnim(new CCatapultAnimation(owner, stack, attackInfo.destinationTile, nullptr, attackInfo.damageDealt));
 		}
 	}
 	else
@@ -341,13 +341,13 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
 
 		//no attacker stack, assume spell-related (earthquake) - only hit animation
 		for (auto attackInfo : ca.attackedParts)
-			positions.push_back(owner->stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120));
+			positions.push_back(owner.stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120));
 
 
-		owner->stacksController->addNewAnim(new CPointEffectAnimation(owner, soundBase::WALLHIT, "SGEXPL.DEF", positions));
+		owner.stacksController->addNewAnim(new CPointEffectAnimation(owner, soundBase::WALLHIT, "SGEXPL.DEF", positions));
 	}
 
-	owner->waitForAnims();
+	owner.waitForAnims();
 
 	for (auto attackInfo : ca.attackedParts)
 	{
@@ -356,7 +356,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
 		if (wallId == EWallVisual::GATE)
 			continue;
 
-		auto wallState = EWallState::EWallState(owner->curInt->cb->battleGetWallState(attackInfo.attackedPart));
+		auto wallState = EWallState::EWallState(owner.curInt->cb->battleGetWallState(attackInfo.attackedPart));
 
 		wallPieceImages[wallId] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState));
 	}

+ 2 - 2
client/battle/BattleSiegeController.h

@@ -67,7 +67,7 @@ namespace EWallVisual
 
 class BattleSiegeController
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	/// besieged town
 	const CGTownInstance *town;
@@ -90,7 +90,7 @@ class BattleSiegeController
 	const CStack * getTurretStack(EWallVisual::EWallVisual wallPiece) const;
 
 public:
-	BattleSiegeController(BattleInterface * owner, const CGTownInstance *siegeTown);
+	BattleSiegeController(BattleInterface & owner, const CGTownInstance *siegeTown);
 
 	/// call-ins from server
 	void gateStateChanged(const EGateState state);

+ 34 - 34
client/battle/BattleStacksController.cpp

@@ -60,7 +60,7 @@ static void onAnimationFinished(const CStack *stack, std::weak_ptr<CreatureAnima
 	animation->onAnimationReset += std::bind(&onAnimationFinished, stack, anim);
 }
 
-BattleStacksController::BattleStacksController(BattleInterface * owner):
+BattleStacksController::BattleStacksController(BattleInterface & owner):
 	owner(owner),
 	activeStack(nullptr),
 	mouseHoveredStack(nullptr),
@@ -86,7 +86,7 @@ BattleStacksController::BattleStacksController(BattleInterface * owner):
 	amountNegative->adjustPalette(&shifterNegative);
 	amountEffNeutral->adjustPalette(&shifterNeutral);
 
-	std::vector<const CStack*> stacks = owner->curInt->cb->battleGetAllStacks(true);
+	std::vector<const CStack*> stacks = owner.curInt->cb->battleGetAllStacks(true);
 	for(const CStack * s : stacks)
 	{
 		stackAdded(s);
@@ -118,7 +118,7 @@ BattleHex BattleStacksController::getStackCurrentPosition(const CStack * stack)
 
 void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer)
 {
-	auto stacks = owner->curInt->cb->battleGetAllStacks(false);
+	auto stacks = owner.curInt->cb->battleGetAllStacks(false);
 
 	for (auto stack : stacks)
 	{
@@ -178,14 +178,14 @@ void BattleStacksController::stackAdded(const CStack * stack)
 
 	if(stack->initialPosition < 0) //turret
 	{
-		assert(owner->siegeController);
+		assert(owner.siegeController);
 
-		const CCreature *turretCreature = owner->siegeController->getTurretCreature();
+		const CCreature *turretCreature = owner.siegeController->getTurretCreature();
 
 		stackAnimation[stack->ID] = AnimationControls::getAnimation(turretCreature);
 		stackAnimation[stack->ID]->pos.h = 235;
 
-		coords = owner->siegeController->getTurretCreaturePosition(stack->initialPosition);
+		coords = owner.siegeController->getTurretCreaturePosition(stack->initialPosition);
 	}
 	else
 	{
@@ -209,7 +209,7 @@ void BattleStacksController::setActiveStack(const CStack *stack)
 	if (activeStack) // update UI
 		stackAnimation[activeStack->ID]->setBorderColor(AnimationControls::getGoldBorder());
 
-	owner->controlPanel->blockUI(activeStack == nullptr);
+	owner.controlPanel->blockUI(activeStack == nullptr);
 }
 
 void BattleStacksController::setHoveredStack(const CStack *stack)
@@ -239,9 +239,9 @@ void BattleStacksController::setHoveredStack(const CStack *stack)
 bool BattleStacksController::stackNeedsAmountBox(const CStack * stack)
 {
 	BattleHex currentActionTarget;
-	if(owner->curInt->curAction)
+	if(owner.curInt->curAction)
 	{
-		auto target = owner->curInt->curAction->getTarget(owner->curInt->cb.get());
+		auto target = owner.curInt->curAction->getTarget(owner.curInt->cb.get());
 		if(!target.empty())
 			currentActionTarget = target.at(0).hexValue;
 	}
@@ -249,7 +249,7 @@ bool BattleStacksController::stackNeedsAmountBox(const CStack * stack)
 	if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON) && stack->getCount() == 1) //do not show box for singular war machines, stacked war machines with box shown are supported as extension feature
 		return false;
 
-	if (!owner->battleActionsStarted) // do not perform any further checks since they are related to actions that will only occur after intro music
+	if (!owner.battleActionsStarted) // do not perform any further checks since they are related to actions that will only occur after intro music
 		return true;
 
 	if(!stack->alive())
@@ -265,18 +265,18 @@ bool BattleStacksController::stackNeedsAmountBox(const CStack * stack)
 			return false;
 	}
 
-	if(owner->curInt->curAction)
+	if(owner.curInt->curAction)
 	{
-		if(owner->curInt->curAction->stackNumber == stack->ID) //stack is currently taking action (is not a target of another creature's action etc)
+		if(owner.curInt->curAction->stackNumber == stack->ID) //stack is currently taking action (is not a target of another creature's action etc)
 		{
-			if(owner->curInt->curAction->actionType == EActionType::WALK || owner->curInt->curAction->actionType == EActionType::SHOOT) //hide when stack walks or shoots
+			if(owner.curInt->curAction->actionType == EActionType::WALK || owner.curInt->curAction->actionType == EActionType::SHOOT) //hide when stack walks or shoots
 				return false;
 
-			else if(owner->curInt->curAction->actionType == EActionType::WALK_AND_ATTACK && currentActionTarget != stack->getPosition()) //when attacking, hide until walk phase finished
+			else if(owner.curInt->curAction->actionType == EActionType::WALK_AND_ATTACK && currentActionTarget != stack->getPosition()) //when attacking, hide until walk phase finished
 				return false;
 		}
 
-		if(owner->curInt->curAction->actionType == EActionType::SHOOT && currentActionTarget == stack->getPosition()) //hide if we are ranged attack target
+		if(owner.curInt->curAction->actionType == EActionType::SHOOT && currentActionTarget == stack->getPosition()) //hide if we are ranged attack target
 			return false;
 	}
 	return true;
@@ -312,7 +312,7 @@ void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack *
 	const int reverseSideShift = stack->side == BattleSide::ATTACKER ? -1 : 1;
 	const BattleHex nextPos = stack->getPosition() + sideShift;
 	const bool edge = stack->getPosition() % GameConstants::BFIELD_WIDTH == (stack->side == BattleSide::ATTACKER ? GameConstants::BFIELD_WIDTH - 2 : 1);
-	const bool moveInside = !edge && !owner->fieldController->stackCountOutsideHex(nextPos);
+	const bool moveInside = !edge && !owner.fieldController->stackCountOutsideHex(nextPos);
 
 	int xAdd = (stack->side == BattleSide::ATTACKER ? 220 : 202) +
 			(stack->doubleWide() ? 44 : 0) * sideShift +
@@ -358,23 +358,23 @@ void BattleStacksController::updateBattleAnimations()
 	if (hadAnimations && currentAnimations.empty())
 	{
 		//anims ended
-		owner->controlPanel->blockUI(activeStack == nullptr);
-		owner->animsAreDisplayed.setn(false);
+		owner.controlPanel->blockUI(activeStack == nullptr);
+		owner.animsAreDisplayed.setn(false);
 	}
 }
 
 void BattleStacksController::addNewAnim(CBattleAnimation *anim)
 {
 	currentAnimations.push_back(anim);
-	owner->animsAreDisplayed.setn(true);
+	owner.animsAreDisplayed.setn(true);
 }
 
 void BattleStacksController::stackActivated(const CStack *stack) //TODO: check it all before game state is changed due to abilities
 {
 	stackToActivate = stack;
-	owner->waitForAnims();
+	owner.waitForAnims();
 	if (stackToActivate) //during waiting stack may have gotten activated through show
-		owner->activateStack();
+		owner.activateStack();
 }
 
 void BattleStacksController::stackRemoved(uint32_t stackID)
@@ -384,10 +384,10 @@ void BattleStacksController::stackRemoved(uint32_t stackID)
 		if (getActiveStack()->ID == stackID)
 		{
 			BattleAction *action = new BattleAction();
-			action->side = owner->defendingHeroInstance ? (owner->curInt->playerID == owner->defendingHeroInstance->tempOwner) : false;
+			action->side = owner.defendingHeroInstance ? (owner.curInt->playerID == owner.defendingHeroInstance->tempOwner) : false;
 			action->actionType = EActionType::CANCEL;
 			action->stackNumber = getActiveStack()->ID;
-			owner->givenCommand.setn(action);
+			owner.givenCommand.setn(action);
 			setActiveStack(nullptr);
 		}
 	}
@@ -403,10 +403,10 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 
 		if(attackedInfo.rebirth)
 		{
-			owner->effectsController->displayEffect(EBattleEffect::RESURRECT, soundBase::RESURECT, attackedInfo.defender->getPosition()); //TODO: play reverse death animation
+			owner.effectsController->displayEffect(EBattleEffect::RESURRECT, soundBase::RESURECT, attackedInfo.defender->getPosition()); //TODO: play reverse death animation
 		}
 	}
-	owner->waitForAnims();
+	owner.waitForAnims();
 
 	for (auto & attackedInfo : attackedInfos)
 	{
@@ -420,7 +420,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance)
 {
 	addNewAnim(new CMovementAnimation(owner, stack, destHex, distance));
-	owner->waitForAnims();
+	owner.waitForAnims();
 }
 
 void BattleStacksController::stackAttacking( const CStack *attacker, BattleHex dest, const CStack *attacked, bool shooting )
@@ -454,7 +454,7 @@ void BattleStacksController::endAction(const BattleAction* action)
 {
 	//check if we should reverse stacks
 	//for some strange reason, it's not enough
-	TStacks stacks = owner->curInt->cb->battleGetStacks(CBattleCallback::MINE_AND_ENEMY);
+	TStacks stacks = owner.curInt->cb->battleGetStacks(CBattleCallback::MINE_AND_ENEMY);
 
 	for (const CStack *s : stacks)
 	{
@@ -469,16 +469,16 @@ void BattleStacksController::endAction(const BattleAction* action)
 
 void BattleStacksController::startAction(const BattleAction* action)
 {
-	const CStack *stack = owner->curInt->cb->battleGetStackByID(action->stackNumber);
+	const CStack *stack = owner.curInt->cb->battleGetStackByID(action->stackNumber);
 	setHoveredStack(nullptr);
 
-	auto actionTarget = action->getTarget(owner->curInt->cb.get());
+	auto actionTarget = action->getTarget(owner.curInt->cb.get());
 
 	if(action->actionType == EActionType::WALK
 		|| (action->actionType == EActionType::WALK_AND_ATTACK && actionTarget.at(0).hexValue != stack->getPosition()))
 	{
 		assert(stack);
-		owner->moveStarted = true;
+		owner.moveStarted = true;
 		if (stackAnimation[action->stackNumber]->framesInGroup(CCreatureAnim::MOVE_START))
 			addNewAnim(new CMovementStartAnimation(owner, stack));
 
@@ -495,7 +495,7 @@ void BattleStacksController::activateStack()
 	if ( !stackToActivate)
 		return;
 
-	owner->trySetActivePlayer(stackToActivate->owner);
+	owner.trySetActivePlayer(stackToActivate->owner);
 
 	setActiveStack(stackToActivate);
 	stackToActivate = nullptr;
@@ -513,7 +513,7 @@ void BattleStacksController::activateStack()
 		if(randomSpellcaster)
 			creatureSpellToCast = -1; //spell will be set later on cast
 		else
-			creatureSpellToCast = owner->curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), s, CBattleInfoCallback::RANDOM_AIMED); //faerie dragon can cast only one spell until their next move
+			creatureSpellToCast = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), s, CBattleInfoCallback::RANDOM_AIMED); //faerie dragon can cast only one spell until their next move
 		//TODO: what if creature can cast BOTH random genie spell and aimed spell?
 		//TODO: faerie dragon type spell should be selected by server
 	}
@@ -560,7 +560,7 @@ Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CSta
 {
 	Point ret(-500, -500); //returned value
 	if(stack && stack->initialPosition < 0) //creatures in turrets
-		return owner->siegeController->getTurretCreaturePosition(stack->initialPosition);
+		return owner.siegeController->getTurretCreaturePosition(stack->initialPosition);
 
 	static const Point basePos(-190, -139); // position of creature in topleft corner
 	static const int imageShiftX = 30; // X offset to base pos for facing right stacks, negative for facing left
@@ -591,6 +591,6 @@ Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CSta
 		}
 	}
 	//returning
-	return ret + owner->pos.topLeft();
+	return ret + owner.pos.topLeft();
 
 }

+ 2 - 2
client/battle/BattleStacksController.h

@@ -36,7 +36,7 @@ class IImage;
 /// And any other effect applied to stacks
 class BattleStacksController
 {
-	BattleInterface * owner;
+	BattleInterface & owner;
 
 	std::shared_ptr<IImage> amountNormal;
 	std::shared_ptr<IImage> amountNegative;
@@ -78,7 +78,7 @@ class BattleStacksController
 	std::shared_ptr<IImage> getStackAmountBox(const CStack * stack);
 
 public:
-	BattleStacksController(BattleInterface * owner);
+	BattleStacksController(BattleInterface & owner);
 
 	bool shouldRotate(const CStack * stack, const BattleHex & oldPos, const BattleHex & nextHex) const;
 	bool facingRight(const CStack * stack) const;