mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Applied suggestions from review
This commit is contained in:
		| @@ -41,7 +41,7 @@ static std::string formatDmgRange(std::pair<ui32, ui32> dmgRange) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| BattleActionsController::BattleActionsController(BattleInterface * owner): | BattleActionsController::BattleActionsController(BattleInterface & owner): | ||||||
| 	owner(owner), | 	owner(owner), | ||||||
| 	creatureCasting(false), | 	creatureCasting(false), | ||||||
| 	spellDestSelectMode(false), | 	spellDestSelectMode(false), | ||||||
| @@ -62,17 +62,17 @@ void BattleActionsController::endCastingSpell() | |||||||
| 		spellDestSelectMode = false; | 		spellDestSelectMode = false; | ||||||
| 		CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); | 		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 | 			possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); //restore actions after they were cleared | ||||||
| 			owner->myTurn = true; | 			owner.myTurn = true; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		if(owner->stacksController->getActiveStack()) | 		if(owner.stacksController->getActiveStack()) | ||||||
| 		{ | 		{ | ||||||
| 			possibleActions = getPossibleActionsForStack(owner->stacksController->getActiveStack()); | 			possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); | ||||||
| 			GH.fakeMouseMove(); | 			GH.fakeMouseMove(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -81,35 +81,35 @@ void BattleActionsController::endCastingSpell() | |||||||
| void BattleActionsController::enterCreatureCastingMode() | void BattleActionsController::enterCreatureCastingMode() | ||||||
| { | { | ||||||
| 	//silently check for possible errors | 	//silently check for possible errors | ||||||
| 	if (!owner->myTurn) | 	if (!owner.myTurn) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (owner->tacticsMode) | 	if (owner.tacticsMode) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	//hero is casting a spell | 	//hero is casting a spell | ||||||
| 	if (spellDestSelectMode) | 	if (spellDestSelectMode) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (!owner->stacksController->getActiveStack()) | 	if (!owner.stacksController->getActiveStack()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (!owner->stacksController->activeStackSpellcaster()) | 	if (!owner.stacksController->activeStackSpellcaster()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	//random spellcaster | 	//random spellcaster | ||||||
| 	if (owner->stacksController->activeStackSpellToCast() == SpellID::NONE) | 	if (owner.stacksController->activeStackSpellToCast() == SpellID::NONE) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (vstd::contains(possibleActions, PossiblePlayerBattleAction::NO_LOCATION)) | 	if (vstd::contains(possibleActions, PossiblePlayerBattleAction::NO_LOCATION)) | ||||||
| 	{ | 	{ | ||||||
| 		const spells::Caster * caster = owner->stacksController->getActiveStack(); | 		const spells::Caster * caster = owner.stacksController->getActiveStack(); | ||||||
| 		const CSpell * spell = owner->stacksController->activeStackSpellToCast().toSpell(); | 		const CSpell * spell = owner.stacksController->activeStackSpellToCast().toSpell(); | ||||||
|  |  | ||||||
| 		spells::Target target; | 		spells::Target target; | ||||||
| 		target.emplace_back(); | 		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); | 		auto m = spell->battleMechanics(&cast); | ||||||
| 		spells::detail::ProblemImpl ignored; | 		spells::detail::ProblemImpl ignored; | ||||||
| @@ -118,16 +118,16 @@ void BattleActionsController::enterCreatureCastingMode() | |||||||
|  |  | ||||||
| 		if (isCastingPossible) | 		if (isCastingPossible) | ||||||
| 		{ | 		{ | ||||||
| 			owner->myTurn = false; | 			owner.myTurn = false; | ||||||
| 			owner->giveCommand(EActionType::MONSTER_SPELL, BattleHex::INVALID, owner->stacksController->activeStackSpellToCast()); | 			owner.giveCommand(EActionType::MONSTER_SPELL, BattleHex::INVALID, owner.stacksController->activeStackSpellToCast()); | ||||||
| 			owner->stacksController->setSelectedStack(nullptr); | 			owner.stacksController->setSelectedStack(nullptr); | ||||||
|  |  | ||||||
| 			CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); | 			CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		possibleActions = getPossibleActionsForStack(owner->stacksController->getActiveStack()); | 		possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); | ||||||
|  |  | ||||||
| 		auto actionFilterPredicate = [](const PossiblePlayerBattleAction x) | 		auto actionFilterPredicate = [](const PossiblePlayerBattleAction x) | ||||||
| 		{ | 		{ | ||||||
| @@ -144,16 +144,16 @@ void BattleActionsController::enterCreatureCastingMode() | |||||||
| std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActionsForStack(const CStack *stack) const | 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 | 	BattleClientInterfaceData data; //hard to get rid of these things so for now they're required data to pass | ||||||
| 	data.creatureSpellToCast = owner->stacksController->activeStackSpellToCast(); | 	data.creatureSpellToCast = owner.stacksController->activeStackSpellToCast(); | ||||||
| 	data.tacticsMode = owner->tacticsMode; | 	data.tacticsMode = owner.tacticsMode; | ||||||
| 	auto allActions = owner->curInt->cb->getClientActionsForStack(stack, data); | 	auto allActions = owner.curInt->cb->getClientActionsForStack(stack, data); | ||||||
|  |  | ||||||
| 	return std::vector<PossiblePlayerBattleAction>(allActions); | 	return std::vector<PossiblePlayerBattleAction>(allActions); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleActionsController::reorderPossibleActionsPriority(const CStack * stack, MouseHoveredHexContext context) | 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 | 	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 = std::make_shared<BattleAction>(); | ||||||
| 	spellToCast->actionType = EActionType::HERO_SPELL; | 	spellToCast->actionType = EActionType::HERO_SPELL; | ||||||
| 	spellToCast->actionSubtype = spellID; //spell number | 	spellToCast->actionSubtype = spellID; //spell number | ||||||
| 	spellToCast->stackNumber = (owner->attackingHeroInstance->tempOwner == owner->curInt->playerID) ? -1 : -2; | 	spellToCast->stackNumber = (owner.attackingHeroInstance->tempOwner == owner.curInt->playerID) ? -1 : -2; | ||||||
| 	spellToCast->side = owner->defendingHeroInstance ? (owner->curInt->playerID == owner->defendingHeroInstance->tempOwner) : false; | 	spellToCast->side = owner.defendingHeroInstance ? (owner.curInt->playerID == owner.defendingHeroInstance->tempOwner) : false; | ||||||
| 	spellDestSelectMode = true; | 	spellDestSelectMode = true; | ||||||
| 	creatureCasting = false; | 	creatureCasting = false; | ||||||
|  |  | ||||||
| 	//choosing possible targets | 	//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 | 	assert(castingHero); // code below assumes non-null hero | ||||||
| 	currentSpell = spellID.toSpell(); | 	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 | 	if (spellSelMode == PossiblePlayerBattleAction::NO_LOCATION) //user does not have to select location | ||||||
| 	{ | 	{ | ||||||
| 		spellToCast->aimToHex(BattleHex::INVALID); | 		spellToCast->aimToHex(BattleHex::INVALID); | ||||||
| 		owner->curInt->cb->battleMakeAction(spellToCast.get()); | 		owner.curInt->cb->battleMakeAction(spellToCast.get()); | ||||||
| 		endCastingSpell(); | 		endCastingSpell(); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @@ -233,7 +233,7 @@ void BattleActionsController::castThisSpell(SpellID spellID) | |||||||
|  |  | ||||||
| void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | 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; | 		return; | ||||||
|  |  | ||||||
| 	// This function handles mouse move over hexes and l-clicking on them. | 	// 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; | 	std::function<void()> realizeAction; | ||||||
|  |  | ||||||
| 	//Get stack on the hex - first try to grab the alive one, if not found -> allow dead stacks. | 	//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) | 	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; | 		return; | ||||||
|  |  | ||||||
| 	bool ourStack = false; | 	bool ourStack = false; | ||||||
| 	if (shere) | 	if (shere) | ||||||
| 		ourStack = shere->owner == owner->curInt->playerID; | 		ourStack = shere->owner == owner.curInt->playerID; | ||||||
|  |  | ||||||
| 	//stack may have changed, update selection border | 	//stack may have changed, update selection border | ||||||
| 	owner->stacksController->setHoveredStack(shere); | 	owner.stacksController->setHoveredStack(shere); | ||||||
|  |  | ||||||
| 	localActions.clear(); | 	localActions.clear(); | ||||||
| 	illegalActions.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; | 	const bool forcedAction = possibleActions.size() == 1; | ||||||
|  |  | ||||||
| 	for (PossiblePlayerBattleAction action : possibleActions) | 	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 (!(shere && shere->alive())) //we can walk on dead stacks | ||||||
| 				{ | 				{ | ||||||
| 					if(canStackMoveHere(owner->stacksController->getActiveStack(), myNumber)) | 					if(canStackMoveHere(owner.stacksController->getActiveStack(), myNumber)) | ||||||
| 						legalAction = true; | 						legalAction = true; | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| @@ -297,12 +297,12 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 			case PossiblePlayerBattleAction::WALK_AND_ATTACK: | 			case PossiblePlayerBattleAction::WALK_AND_ATTACK: | ||||||
| 			case PossiblePlayerBattleAction::ATTACK_AND_RETURN: | 			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 :( | 						owner.fieldController->setBattleCursor(myNumber); // temporary - needed for following function :( | ||||||
| 						BattleHex attackFromHex = owner->fieldController->fromWhichHexAttack(myNumber); | 						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) | 						if (attackFromHex >= 0) //we can be in this line when unreachable creature is L - clicked (as of revision 1308) | ||||||
| 							legalAction = true; | 							legalAction = true; | ||||||
| @@ -311,25 +311,25 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 			} | 			} | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::SHOOT: | 			case PossiblePlayerBattleAction::SHOOT: | ||||||
| 				if(owner->curInt->cb->battleCanShoot(owner->stacksController->getActiveStack(), myNumber)) | 				if(owner.curInt->cb->battleCanShoot(owner.stacksController->getActiveStack(), myNumber)) | ||||||
| 					legalAction = true; | 					legalAction = true; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::ANY_LOCATION: | 			case PossiblePlayerBattleAction::ANY_LOCATION: | ||||||
| 				if (myNumber > -1) //TODO: this should be checked for all actions | 				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; | 						legalAction = true; | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE: | 			case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE: | ||||||
| 				if(shere && isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber)) | 				if(shere && isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber)) | ||||||
| 					legalAction = true; | 					legalAction = true; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL: | 			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) | 					if(spellID > -1) | ||||||
| 					{ | 					{ | ||||||
| 						legalAction = true; | 						legalAction = true; | ||||||
| @@ -338,7 +338,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 			} | 			} | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::OBSTACLE: | 			case PossiblePlayerBattleAction::OBSTACLE: | ||||||
| 				if(isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber)) | 				if(isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber)) | ||||||
| 					legalAction = true; | 					legalAction = true; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::TELEPORT: | 			case PossiblePlayerBattleAction::TELEPORT: | ||||||
| @@ -346,32 +346,32 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 				//todo: move to mechanics | 				//todo: move to mechanics | ||||||
| 				ui8 skill = 0; | 				ui8 skill = 0; | ||||||
| 				if (creatureCasting) | 				if (creatureCasting) | ||||||
| 					skill = owner->stacksController->getActiveStack()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell()); | 					skill = owner.stacksController->getActiveStack()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell()); | ||||||
| 				else | 				else | ||||||
| 					skill = owner->getActiveHero()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell()); | 					skill = owner.getActiveHero()->getEffectLevel(SpellID(SpellID::TELEPORT).toSpell()); | ||||||
| 				//TODO: explicitely save power, skill | 				//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; | 					legalAction = true; | ||||||
| 				else | 				else | ||||||
| 					notLegal = true; | 					notLegal = true; | ||||||
| 			} | 			} | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::SACRIFICE: //choose our living stack to sacrifice | 			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; | 					legalAction = true; | ||||||
| 				else | 				else | ||||||
| 					notLegal = true; | 					notLegal = true; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::FREE_LOCATION: | 			case PossiblePlayerBattleAction::FREE_LOCATION: | ||||||
| 				legalAction = true; | 				legalAction = true; | ||||||
| 				if(!isCastingPossibleHere(owner->stacksController->getActiveStack(), shere, myNumber)) | 				if(!isCastingPossibleHere(owner.stacksController->getActiveStack(), shere, myNumber)) | ||||||
| 				{ | 				{ | ||||||
| 					legalAction = false; | 					legalAction = false; | ||||||
| 					notLegal = true; | 					notLegal = true; | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::CATAPULT: | 			case PossiblePlayerBattleAction::CATAPULT: | ||||||
| 				if (owner->siegeController && owner->siegeController->isAttackableByCatapult(myNumber)) | 				if (owner.siegeController && owner.siegeController->isAttackableByCatapult(myNumber)) | ||||||
| 					legalAction = true; | 					legalAction = true; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::HEAL: | 			case PossiblePlayerBattleAction::HEAL: | ||||||
| @@ -428,35 +428,35 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 		{ | 		{ | ||||||
| 			case PossiblePlayerBattleAction::CHOOSE_TACTICS_STACK: | 			case PossiblePlayerBattleAction::CHOOSE_TACTICS_STACK: | ||||||
| 				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s | 				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[481]) % shere->getName()).str(); //Select %s | ||||||
| 				realizeAction = [=](){ owner->stackActivated(shere); }; | 				realizeAction = [=](){ owner.stackActivated(shere); }; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::MOVE_TACTICS: | 			case PossiblePlayerBattleAction::MOVE_TACTICS: | ||||||
| 			case PossiblePlayerBattleAction::MOVE_STACK: | 			case PossiblePlayerBattleAction::MOVE_STACK: | ||||||
| 				if (owner->stacksController->getActiveStack()->hasBonusOfType(Bonus::FLYING)) | 				if (owner.stacksController->getActiveStack()->hasBonusOfType(Bonus::FLYING)) | ||||||
| 				{ | 				{ | ||||||
| 					cursorFrame = ECursor::COMBAT_FLY; | 					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 | 				else | ||||||
| 				{ | 				{ | ||||||
| 					cursorFrame = ECursor::COMBAT_MOVE; | 					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 = [=]() | 				realizeAction = [=]() | ||||||
| 				{ | 				{ | ||||||
| 					if(owner->stacksController->getActiveStack()->doubleWide()) | 					if(owner.stacksController->getActiveStack()->doubleWide()) | ||||||
| 					{ | 					{ | ||||||
| 						std::vector<BattleHex> acc = owner->curInt->cb->battleGetAvailableHexes(owner->stacksController->getActiveStack()); | 						std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack()); | ||||||
| 						BattleHex shiftedDest = myNumber.cloneInDirection(owner->stacksController->getActiveStack()->destShiftDir(), false); | 						BattleHex shiftedDest = myNumber.cloneInDirection(owner.stacksController->getActiveStack()->destShiftDir(), false); | ||||||
| 						if(vstd::contains(acc, myNumber)) | 						if(vstd::contains(acc, myNumber)) | ||||||
| 							owner->giveCommand(EActionType::WALK, myNumber); | 							owner.giveCommand(EActionType::WALK, myNumber); | ||||||
| 						else if(vstd::contains(acc, shiftedDest)) | 						else if(vstd::contains(acc, shiftedDest)) | ||||||
| 							owner->giveCommand(EActionType::WALK, shiftedDest); | 							owner.giveCommand(EActionType::WALK, shiftedDest); | ||||||
| 					} | 					} | ||||||
| 					else | 					else | ||||||
| 					{ | 					{ | ||||||
| 						owner->giveCommand(EActionType::WALK, myNumber); | 						owner.giveCommand(EActionType::WALK, myNumber); | ||||||
| 					} | 					} | ||||||
| 				}; | 				}; | ||||||
| 				break; | 				break; | ||||||
| @@ -464,55 +464,55 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 			case PossiblePlayerBattleAction::WALK_AND_ATTACK: | 			case PossiblePlayerBattleAction::WALK_AND_ATTACK: | ||||||
| 			case PossiblePlayerBattleAction::ATTACK_AND_RETURN: //TODO: allow to disable return | 			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? | 					setCursor = false; //don't overwrite settings from the call above //TODO: what does it mean? | ||||||
|  |  | ||||||
| 					bool returnAfterAttack = currentAction == PossiblePlayerBattleAction::ATTACK_AND_RETURN; | 					bool returnAfterAttack = currentAction == PossiblePlayerBattleAction::ATTACK_AND_RETURN; | ||||||
|  |  | ||||||
| 					realizeAction = [=]() | 					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) | 						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)); | 							auto command = new BattleAction(BattleAction::makeMeleeAttack(owner.stacksController->getActiveStack(), myNumber, attackFromHex, returnAfterAttack)); | ||||||
| 							owner->sendCommand(command, owner->stacksController->getActiveStack()); | 							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 | 					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) | 					newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[36]) % shere->getName() % estDmgText).str(); //Attack %s (%s damage) | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::SHOOT: | 			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; | 					cursorFrame = ECursor::COMBAT_SHOOT_PENALTY; | ||||||
| 				else | 				else | ||||||
| 					cursorFrame = ECursor::COMBAT_SHOOT; | 					cursorFrame = ECursor::COMBAT_SHOOT; | ||||||
|  |  | ||||||
| 				realizeAction = [=](){owner->giveCommand(EActionType::SHOOT, myNumber);}; | 				realizeAction = [=](){owner.giveCommand(EActionType::SHOOT, myNumber);}; | ||||||
| 				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 | 				std::string estDmgText = formatDmgRange(std::make_pair((ui32)damage.first, (ui32)damage.second)); //calculating estimated dmg | ||||||
| 				//printing - Shoot %s (%d shots left, %s damage) | 				//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; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE: | 			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 | 				newConsoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[27]) % currentSpell->name % shere->getName()); //Cast %s on %s | ||||||
| 				switch (currentSpell->id) | 				switch (currentSpell->id) | ||||||
| 				{ | 				{ | ||||||
| 					case SpellID::SACRIFICE: | 					case SpellID::SACRIFICE: | ||||||
| 					case SpellID::TELEPORT: | 					case SpellID::TELEPORT: | ||||||
| 						owner->stacksController->setSelectedStack(shere); //remember first target | 						owner.stacksController->setSelectedStack(shere); //remember first target | ||||||
| 						secondaryTarget = true; | 						secondaryTarget = true; | ||||||
| 						break; | 						break; | ||||||
| 				} | 				} | ||||||
| 				isCastingPossible = true; | 				isCastingPossible = true; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::ANY_LOCATION: | 			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 | 				newConsoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[26]) % currentSpell->name); //Cast %s | ||||||
| 				isCastingPossible = true; | 				isCastingPossible = true; | ||||||
| 				break; | 				break; | ||||||
| @@ -544,18 +544,18 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 			case PossiblePlayerBattleAction::HEAL: | 			case PossiblePlayerBattleAction::HEAL: | ||||||
| 				cursorFrame = ECursor::COMBAT_HEAL; | 				cursorFrame = ECursor::COMBAT_HEAL; | ||||||
| 				newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s | 				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; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::RISE_DEMONS: | 			case PossiblePlayerBattleAction::RISE_DEMONS: | ||||||
| 				cursorType = ECursor::SPELLBOOK; | 				cursorType = ECursor::SPELLBOOK; | ||||||
| 				realizeAction = [=]() | 				realizeAction = [=]() | ||||||
| 				{ | 				{ | ||||||
| 					owner->giveCommand(EActionType::DAEMON_SUMMONING, myNumber); | 					owner.giveCommand(EActionType::DAEMON_SUMMONING, myNumber); | ||||||
| 				}; | 				}; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::CATAPULT: | 			case PossiblePlayerBattleAction::CATAPULT: | ||||||
| 				cursorFrame = ECursor::COMBAT_SHOOT_CATAPULT; | 				cursorFrame = ECursor::COMBAT_SHOOT_CATAPULT; | ||||||
| 				realizeAction = [=](){ owner->giveCommand(EActionType::CATAPULT, myNumber); }; | 				realizeAction = [=](){ owner.giveCommand(EActionType::CATAPULT, myNumber); }; | ||||||
| 				break; | 				break; | ||||||
| 			case PossiblePlayerBattleAction::CREATURE_INFO: | 			case PossiblePlayerBattleAction::CREATURE_INFO: | ||||||
| 			{ | 			{ | ||||||
| @@ -634,11 +634,11 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 				{ | 				{ | ||||||
| 					if (currentSpell) | 					if (currentSpell) | ||||||
| 					{ | 					{ | ||||||
| 						owner->giveCommand(EActionType::MONSTER_SPELL, myNumber, owner->stacksController->activeStackSpellToCast()); | 						owner.giveCommand(EActionType::MONSTER_SPELL, myNumber, owner.stacksController->activeStackSpellToCast()); | ||||||
| 					} | 					} | ||||||
| 					else //unknown random spell | 					else //unknown random spell | ||||||
| 					{ | 					{ | ||||||
| 						owner->giveCommand(EActionType::MONSTER_SPELL, myNumber); | 						owner.giveCommand(EActionType::MONSTER_SPELL, myNumber); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| @@ -653,10 +653,10 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 						spellToCast->aimToHex(myNumber); | 						spellToCast->aimToHex(myNumber); | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 					owner->curInt->cb->battleMakeAction(spellToCast.get()); | 					owner.curInt->cb->battleMakeAction(spellToCast.get()); | ||||||
| 					endCastingSpell(); | 					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); | 				CCS->curh->changeGraphic(cursorType, cursorFrame); | ||||||
|  |  | ||||||
| 			if (!currentConsoleMsg.empty()) | 			if (!currentConsoleMsg.empty()) | ||||||
| 				owner->controlPanel->console->clearIfMatching(currentConsoleMsg); | 				owner.controlPanel->console->clearIfMatching(currentConsoleMsg); | ||||||
| 			if (!newConsoleMsg.empty()) | 			if (!newConsoleMsg.empty()) | ||||||
| 				owner->controlPanel->console->write(newConsoleMsg); | 				owner.controlPanel->console->write(newConsoleMsg); | ||||||
|  |  | ||||||
| 			currentConsoleMsg = newConsoleMsg; | 			currentConsoleMsg = newConsoleMsg; | ||||||
| 		} | 		} | ||||||
| @@ -679,12 +679,12 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) | |||||||
| 			//opening creature window shouldn't affect myTurn... | 			//opening creature window shouldn't affect myTurn... | ||||||
| 			if ((currentAction != PossiblePlayerBattleAction::CREATURE_INFO) && !secondaryTarget) | 			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(); | 			realizeAction(); | ||||||
| 			if (!secondaryTarget) //do not replace teleport or sacrifice cursor | 			if (!secondaryTarget) //do not replace teleport or sacrifice cursor | ||||||
| 				CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); | 				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) | 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; | 	bool isCastingPossible = true; | ||||||
|  |  | ||||||
| 	int spellID = -1; | 	int spellID = -1; | ||||||
| 	if (creatureCasting) | 	if (creatureCasting) | ||||||
| 	{ | 	{ | ||||||
| 		if (owner->stacksController->activeStackSpellToCast() != SpellID::NONE && (shere != sactive)) //can't cast on itself | 		if (owner.stacksController->activeStackSpellToCast() != SpellID::NONE && (shere != sactive)) //can't cast on itself | ||||||
| 			spellID = owner->stacksController->activeStackSpellToCast(); //TODO: merge with SpellTocast? | 			spellID = owner.stacksController->activeStackSpellToCast(); //TODO: merge with SpellTocast? | ||||||
| 	} | 	} | ||||||
| 	else //hero casting | 	else //hero casting | ||||||
| 	{ | 	{ | ||||||
| @@ -714,7 +714,7 @@ bool BattleActionsController::isCastingPossibleHere(const CStack *sactive, const | |||||||
|  |  | ||||||
| 	if (currentSpell) | 	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) | 		if (caster == nullptr) | ||||||
| 		{ | 		{ | ||||||
| 			isCastingPossible = false;//just in case | 			isCastingPossible = false;//just in case | ||||||
| @@ -726,7 +726,7 @@ bool BattleActionsController::isCastingPossibleHere(const CStack *sactive, const | |||||||
| 			spells::Target target; | 			spells::Target target; | ||||||
| 			target.emplace_back(myNumber); | 			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); | 			auto m = currentSpell->battleMechanics(&cast); | ||||||
| 			spells::detail::ProblemImpl problem; //todo: display problem in status bar | 			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 | 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); | 	BattleHex shiftedDest = myNumber.cloneInDirection(stackToMove->destShiftDir(), false); | ||||||
|  |  | ||||||
| 	if (vstd::contains(acc, myNumber)) | 	if (vstd::contains(acc, myNumber)) | ||||||
| @@ -757,7 +757,7 @@ bool BattleActionsController::canStackMoveHere(const CStack * stackToMove, Battl | |||||||
|  |  | ||||||
| void BattleActionsController::activateStack() | void BattleActionsController::activateStack() | ||||||
| { | { | ||||||
| 	const CStack * s = owner->stacksController->getActiveStack(); | 	const CStack * s = owner.stacksController->getActiveStack(); | ||||||
| 	if(s) | 	if(s) | ||||||
| 		possibleActions = getPossibleActionsForStack(s); | 		possibleActions = getPossibleActionsForStack(s); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ enum class MouseHoveredHexContext | |||||||
| /// As well as all relevant feedback for these actions in user interface | /// As well as all relevant feedback for these actions in user interface | ||||||
| class BattleActionsController | class BattleActionsController | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	/// all actions possible to call at the moment by player | 	/// all actions possible to call at the moment by player | ||||||
| 	std::vector<PossiblePlayerBattleAction> possibleActions; | 	std::vector<PossiblePlayerBattleAction> possibleActions; | ||||||
| @@ -70,7 +70,7 @@ class BattleActionsController | |||||||
| 	void reorderPossibleActionsPriority(const CStack * stack, MouseHoveredHexContext context); | 	void reorderPossibleActionsPriority(const CStack * stack, MouseHoveredHexContext context); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleActionsController(BattleInterface * owner); | 	BattleActionsController(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	/// initialize list of potential actions for new active stack | 	/// initialize list of potential actions for new active stack | ||||||
| 	void activateStack(); | 	void activateStack(); | ||||||
|   | |||||||
| @@ -34,9 +34,9 @@ | |||||||
| #include "../../lib/CTownHandler.h" | #include "../../lib/CTownHandler.h" | ||||||
| #include "../../lib/mapObjects/CGTownInstance.h" | #include "../../lib/mapObjects/CGTownInstance.h" | ||||||
|  |  | ||||||
| CBattleAnimation::CBattleAnimation(BattleInterface * _owner) | CBattleAnimation::CBattleAnimation(BattleInterface & owner) | ||||||
| 	: owner(_owner), | 	: owner(owner), | ||||||
| 	  ID(_owner->stacksController->animIDhelper++), | 	  ID(owner.stacksController->animIDhelper++), | ||||||
| 	  initialized(false) | 	  initialized(false) | ||||||
| { | { | ||||||
| 	logAnim->trace("Animation #%d created", ID); | 	logAnim->trace("Animation #%d created", ID); | ||||||
| @@ -72,22 +72,22 @@ CBattleAnimation::~CBattleAnimation() | |||||||
|  |  | ||||||
| std::vector<CBattleAnimation *> & CBattleAnimation::pendingAnimations() | std::vector<CBattleAnimation *> & CBattleAnimation::pendingAnimations() | ||||||
| { | { | ||||||
| 	return owner->stacksController->currentAnimations; | 	return owner.stacksController->currentAnimations; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::shared_ptr<CreatureAnimation> CBattleAnimation::stackAnimation(const CStack * stack) const | 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) | 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) | void CBattleAnimation::setStackFacingRight(const CStack * stack, bool facingRight) | ||||||
| { | { | ||||||
| 	owner->stacksController->stackFacingRight[stack->ID] = facingRight; | 	owner.stacksController->stackFacingRight[stack->ID] = facingRight; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CBattleAnimation::checkInitialConditions() | bool CBattleAnimation::checkInitialConditions() | ||||||
| @@ -116,7 +116,7 @@ bool CBattleAnimation::checkInitialConditions() | |||||||
| 	return ID == lowestMoveID; | 	return ID == lowestMoveID; | ||||||
| } | } | ||||||
|  |  | ||||||
| CBattleStackAnimation::CBattleStackAnimation(BattleInterface * owner, const CStack * stack) | CBattleStackAnimation::CBattleStackAnimation(BattleInterface & owner, const CStack * stack) | ||||||
| 	: CBattleAnimation(owner), | 	: CBattleAnimation(owner), | ||||||
| 	  myAnim(stackAnimation(stack)), | 	  myAnim(stackAnimation(stack)), | ||||||
| 	  stack(stack) | 	  stack(stack) | ||||||
| @@ -172,13 +172,13 @@ bool CAttackAnimation::checkInitialConditions() | |||||||
| const CCreature * CAttackAnimation::getCreature() const | const CCreature * CAttackAnimation::getCreature() const | ||||||
| { | { | ||||||
| 	if (attackingStack->getCreature()->idNumber == CreatureID::ARROW_TOWERS) | 	if (attackingStack->getCreature()->idNumber == CreatureID::ARROW_TOWERS) | ||||||
| 		return owner->siegeController->getTurretCreature(); | 		return owner.siegeController->getTurretCreature(); | ||||||
| 	else | 	else | ||||||
| 		return attackingStack->getCreature(); | 		return attackingStack->getCreature(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CAttackAnimation::CAttackAnimation(BattleInterface *_owner, const CStack *attacker, BattleHex _dest, const CStack *defender) | CAttackAnimation::CAttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender) | ||||||
| 	: CBattleStackAnimation(_owner, attacker), | 	: CBattleStackAnimation(owner, attacker), | ||||||
| 	  shooting(false), | 	  shooting(false), | ||||||
| 	  group(CCreatureAnim::SHOOT_FRONT), | 	  group(CCreatureAnim::SHOOT_FRONT), | ||||||
| 	  soundPlayed(false), | 	  soundPlayed(false), | ||||||
| @@ -190,8 +190,8 @@ CAttackAnimation::CAttackAnimation(BattleInterface *_owner, const CStack *attack | |||||||
| 	attackingStackPosBeforeReturn = attackingStack->getPosition(); | 	attackingStackPosBeforeReturn = attackingStack->getPosition(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface * _owner) | CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface & owner) | ||||||
| 	: CBattleStackAnimation(_owner, _attackedInfo.defender), | 	: CBattleStackAnimation(owner, _attackedInfo.defender), | ||||||
| 	  attacker(_attackedInfo.attacker), | 	  attacker(_attackedInfo.attacker), | ||||||
| 	  rangedAttack(_attackedInfo.indirectAttack), | 	  rangedAttack(_attackedInfo.indirectAttack), | ||||||
| 	  killed(_attackedInfo.killed), | 	  killed(_attackedInfo.killed), | ||||||
| @@ -235,14 +235,14 @@ bool CDefenceAnimation::init() | |||||||
|  |  | ||||||
|  |  | ||||||
| 	//reverse unit if necessary | 	//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; | 		return false; | ||||||
| 	} | 	} | ||||||
| 	//unit reversed | 	//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; | 		return false; | ||||||
| 	} | 	} | ||||||
| @@ -327,8 +327,8 @@ CDefenceAnimation::~CDefenceAnimation() | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| CDummyAnimation::CDummyAnimation(BattleInterface * _owner, int howManyFrames) | CDummyAnimation::CDummyAnimation(BattleInterface & owner, int howManyFrames) | ||||||
| 	: CBattleAnimation(_owner), | 	: CBattleAnimation(owner), | ||||||
| 	  counter(0), | 	  counter(0), | ||||||
| 	  howMany(howManyFrames) | 	  howMany(howManyFrames) | ||||||
| { | { | ||||||
| @@ -358,11 +358,11 @@ bool CMeleeAttackAnimation::init() | |||||||
| 		return false; | 		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) | 	if(toReverse) | ||||||
| 	{ | 	{ | ||||||
| 		owner->stacksController->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true)); | 		owner.stacksController->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true)); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -438,14 +438,14 @@ bool CMeleeAttackAnimation::init() | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| CMeleeAttackAnimation::CMeleeAttackAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked) | CMeleeAttackAnimation::CMeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked) | ||||||
| 	: CAttackAnimation(_owner, attacker, _dest, _attacked) | 	: CAttackAnimation(owner, attacker, _dest, _attacked) | ||||||
| { | { | ||||||
| 	logAnim->debug("Created melee attack anim for %s", attacker->getName()); | 	logAnim->debug("Created melee attack anim for %s", attacker->getName()); | ||||||
| } | } | ||||||
|  |  | ||||||
| CStackMoveAnimation::CStackMoveAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex _currentHex): | CStackMoveAnimation::CStackMoveAnimation(BattleInterface & owner, const CStack * _stack, BattleHex _currentHex): | ||||||
| 	CBattleStackAnimation(_owner, _stack), | 	CBattleStackAnimation(owner, _stack), | ||||||
| 	currentHex(_currentHex) | 	currentHex(_currentHex) | ||||||
| { | { | ||||||
|  |  | ||||||
| @@ -471,13 +471,13 @@ bool CMovementAnimation::init() | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	//reverse unit if necessary | 	//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 | 		// it seems that H3 does NOT plays full rotation animation here in most situations | ||||||
| 		// Logical since it takes quite a lot of time | 		// Logical since it takes quite a lot of time | ||||||
| 		if (curentMoveIndex == 0) // full rotation only for moving towards first tile. | 		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; | 			return false; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @@ -491,13 +491,13 @@ bool CMovementAnimation::init() | |||||||
| 		myAnim->setType(CCreatureAnim::MOVING); | 		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 begPosition = owner.stacksController->getStackPositionAtHex(oldPos, stack); | ||||||
| 	Point endPosition = owner->stacksController->getStackPositionAtHex(currentHex, stack); | 	Point endPosition = owner.stacksController->getStackPositionAtHex(currentHex, stack); | ||||||
|  |  | ||||||
| 	timeToMove = AnimationControls::getMovementDuration(stack->getCreature()); | 	timeToMove = AnimationControls::getMovementDuration(stack->getCreature()); | ||||||
|  |  | ||||||
| @@ -530,7 +530,7 @@ void CMovementAnimation::nextFrame() | |||||||
| 	if(progress >= 1.0) | 	if(progress >= 1.0) | ||||||
| 	{ | 	{ | ||||||
| 		// Sets the position of the creature animation sprites | 		// 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; | 		myAnim->pos = coords; | ||||||
|  |  | ||||||
| 		// true if creature haven't reached the final destination hex | 		// true if creature haven't reached the final destination hex | ||||||
| @@ -553,18 +553,18 @@ CMovementAnimation::~CMovementAnimation() | |||||||
| { | { | ||||||
| 	assert(stack); | 	assert(stack); | ||||||
|  |  | ||||||
| 	myAnim->pos = owner->stacksController->getStackPositionAtHex(currentHex, stack); | 	myAnim->pos = owner.stacksController->getStackPositionAtHex(currentHex, stack); | ||||||
| 	owner->stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, currentHex)); | 	owner.stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, currentHex)); | ||||||
|  |  | ||||||
| 	if(owner->moveSoundHander != -1) | 	if(owner.moveSoundHander != -1) | ||||||
| 	{ | 	{ | ||||||
| 		CCS->soundh->stopSound(owner->moveSoundHander); | 		CCS->soundh->stopSound(owner.moveSoundHander); | ||||||
| 		owner->moveSoundHander = -1; | 		owner.moveSoundHander = -1; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| CMovementAnimation::CMovementAnimation(BattleInterface *_owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance) | CMovementAnimation::CMovementAnimation(BattleInterface & owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance) | ||||||
| 	: CStackMoveAnimation(_owner, _stack, _destTiles.front()), | 	: CStackMoveAnimation(owner, _stack, _destTiles.front()), | ||||||
| 	  destTiles(_destTiles), | 	  destTiles(_destTiles), | ||||||
| 	  curentMoveIndex(0), | 	  curentMoveIndex(0), | ||||||
| 	  oldPos(stack->getPosition()), | 	  oldPos(stack->getPosition()), | ||||||
| @@ -576,8 +576,8 @@ CMovementAnimation::CMovementAnimation(BattleInterface *_owner, const CStack *_s | |||||||
| 	logAnim->debug("Created movement anim for %s", stack->getName()); | 	logAnim->debug("Created movement anim for %s", stack->getName()); | ||||||
| } | } | ||||||
|  |  | ||||||
| CMovementEndAnimation::CMovementEndAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex destTile) | CMovementEndAnimation::CMovementEndAnimation(BattleInterface & owner, const CStack * _stack, BattleHex destTile) | ||||||
| : CStackMoveAnimation(_owner, _stack, destTile) | : CStackMoveAnimation(owner, _stack, destTile) | ||||||
| { | { | ||||||
| 	logAnim->debug("Created movement end anim for %s", stack->getName()); | 	logAnim->debug("Created movement end anim for %s", stack->getName()); | ||||||
| } | } | ||||||
| @@ -611,8 +611,8 @@ CMovementEndAnimation::~CMovementEndAnimation() | |||||||
| 	CCS->curh->show(); | 	CCS->curh->show(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CMovementStartAnimation::CMovementStartAnimation(BattleInterface * _owner, const CStack * _stack) | CMovementStartAnimation::CMovementStartAnimation(BattleInterface & owner, const CStack * _stack) | ||||||
| 	: CStackMoveAnimation(_owner, _stack, _stack->getPosition()) | 	: CStackMoveAnimation(owner, _stack, _stack->getPosition()) | ||||||
| { | { | ||||||
| 	logAnim->debug("Created movement start anim for %s", stack->getName()); | 	logAnim->debug("Created movement start anim for %s", stack->getName()); | ||||||
| } | } | ||||||
| @@ -636,8 +636,8 @@ bool CMovementStartAnimation::init() | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| CReverseAnimation::CReverseAnimation(BattleInterface * _owner, const CStack * stack, BattleHex dest, bool _priority) | CReverseAnimation::CReverseAnimation(BattleInterface & owner, const CStack * stack, BattleHex dest, bool _priority) | ||||||
| 	: CStackMoveAnimation(_owner, stack, dest), | 	: CStackMoveAnimation(owner, stack, dest), | ||||||
| 	  priority(_priority) | 	  priority(_priority) | ||||||
| { | { | ||||||
| 	logAnim->debug("Created reverse anim for %s", stack->getName()); | 	logAnim->debug("Created reverse anim for %s", stack->getName()); | ||||||
| @@ -676,7 +676,7 @@ void CBattleStackAnimation::rotateStack(BattleHex hex) | |||||||
| { | { | ||||||
| 	setStackFacingRight(stack, !stackFacingRight(stack)); | 	setStackFacingRight(stack, !stackFacingRight(stack)); | ||||||
|  |  | ||||||
| 	stackAnimation(stack)->pos = owner->stacksController->getStackPositionAtHex(hex, stack); | 	stackAnimation(stack)->pos = owner.stacksController->getStackPositionAtHex(hex, stack); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CReverseAnimation::setupSecondPart() | void CReverseAnimation::setupSecondPart() | ||||||
| @@ -698,8 +698,8 @@ void CReverseAnimation::setupSecondPart() | |||||||
| 		delete this; | 		delete this; | ||||||
| } | } | ||||||
|  |  | ||||||
| CRangedAttackAnimation::CRangedAttackAnimation(BattleInterface * owner_, const CStack * attacker, BattleHex dest_, const CStack * defender) | CRangedAttackAnimation::CRangedAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest_, const CStack * defender) | ||||||
| 	: CAttackAnimation(owner_, attacker, dest_, defender), | 	: CAttackAnimation(owner, attacker, dest_, defender), | ||||||
| 	  projectileEmitted(false) | 	  projectileEmitted(false) | ||||||
| { | { | ||||||
| 	logAnim->info("Ranged attack animation created"); | 	logAnim->info("Ranged attack animation created"); | ||||||
| @@ -722,9 +722,9 @@ bool CRangedAttackAnimation::init() | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	//reverse unit if necessary | 	//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; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -738,7 +738,7 @@ bool CRangedAttackAnimation::init() | |||||||
| void CRangedAttackAnimation::setAnimationGroup() | void CRangedAttackAnimation::setAnimationGroup() | ||||||
| { | { | ||||||
| 	Point shooterPos = stackAnimation(attackingStack)->pos.topLeft(); | 	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) | 	//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; | 	static const double straightAngle = 0.2; | ||||||
| @@ -757,7 +757,7 @@ void CRangedAttackAnimation::setAnimationGroup() | |||||||
| void CRangedAttackAnimation::initializeProjectile() | void CRangedAttackAnimation::initializeProjectile() | ||||||
| { | { | ||||||
| 	const CCreature *shooterInfo = getCreature(); | 	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); | 	Point shotOrigin = stackAnimation(attackingStack)->pos.topLeft() + Point(222, 265); | ||||||
| 	int multiplier = stackFacingRight(attackingStack) ? 1 : -1; | 	int multiplier = stackFacingRight(attackingStack) ? 1 : -1; | ||||||
|  |  | ||||||
| @@ -787,7 +787,7 @@ void CRangedAttackAnimation::initializeProjectile() | |||||||
| void CRangedAttackAnimation::emitProjectile() | void CRangedAttackAnimation::emitProjectile() | ||||||
| { | { | ||||||
| 	logAnim->info("Ranged attack projectile emitted"); | 	logAnim->info("Ranged attack projectile emitted"); | ||||||
| 	owner->projectilesController->emitStackProjectile(attackingStack); | 	owner.projectilesController->emitStackProjectile(attackingStack); | ||||||
| 	projectileEmitted = true; | 	projectileEmitted = true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -807,7 +807,7 @@ void CRangedAttackAnimation::nextFrame() | |||||||
| 	// animation should be paused if there is an active projectile | 	// animation should be paused if there is an active projectile | ||||||
| 	if (projectileEmitted) | 	if (projectileEmitted) | ||||||
| 	{ | 	{ | ||||||
| 		if (owner->projectilesController->hasActiveProjectile(attackingStack)) | 		if (owner.projectilesController->hasActiveProjectile(attackingStack)) | ||||||
| 			stackAnimation(attackingStack)->pause(); | 			stackAnimation(attackingStack)->pause(); | ||||||
| 		else | 		else | ||||||
| 			stackAnimation(attackingStack)->play(); | 			stackAnimation(attackingStack)->play(); | ||||||
| @@ -836,7 +836,7 @@ CRangedAttackAnimation::~CRangedAttackAnimation() | |||||||
| { | { | ||||||
| 	logAnim->info("Ranged attack animation is over"); | 	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? | 	//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); | 	assert(projectileEmitted); | ||||||
|  |  | ||||||
| 	// FIXME: is this possible? Animation is over but we're yet to fire projectile? | 	// 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) | CShootingAnimation::CShootingAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked) | ||||||
| 	: CRangedAttackAnimation(_owner, attacker, _dest, _attacked) | 	: CRangedAttackAnimation(owner, attacker, _dest, _attacked) | ||||||
| { | { | ||||||
| 	logAnim->debug("Created shooting anim for %s", stack->getName()); | 	logAnim->debug("Created shooting anim for %s", stack->getName()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CShootingAnimation::createProjectile(const Point & from, const Point & dest) const | 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 | uint32_t CShootingAnimation::getAttackClimaxFrame() const | ||||||
| @@ -879,8 +879,8 @@ CCreatureAnim::EAnimType CShootingAnimation::getDownwardsGroup() const | |||||||
| 	return CCreatureAnim::SHOOT_DOWN; | 	return CCreatureAnim::SHOOT_DOWN; | ||||||
| } | } | ||||||
|  |  | ||||||
| CCatapultAnimation::CCatapultAnimation(BattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, int _catapultDmg) | CCatapultAnimation::CCatapultAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, int _catapultDmg) | ||||||
| 	: CShootingAnimation(_owner, attacker, _dest, _attacked), | 	: CShootingAnimation(owner, attacker, _dest, _attacked), | ||||||
| 	catapultDamage(_catapultDmg), | 	catapultDamage(_catapultDmg), | ||||||
| 	explosionEmitted(false) | 	explosionEmitted(false) | ||||||
| { | { | ||||||
| @@ -897,26 +897,26 @@ void CCatapultAnimation::nextFrame() | |||||||
| 	if ( !projectileEmitted) | 	if ( !projectileEmitted) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (owner->projectilesController->hasActiveProjectile(attackingStack)) | 	if (owner.projectilesController->hasActiveProjectile(attackingStack)) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	explosionEmitted = true; | 	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) | 	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 | 	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 | 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) | CCastAnimation::CCastAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell) | ||||||
| 	: CRangedAttackAnimation(owner_, attacker, dest_, defender), | 	: CRangedAttackAnimation(owner, attacker, dest_, defender), | ||||||
| 	  spell(spell) | 	  spell(spell) | ||||||
| { | { | ||||||
| 	assert(dest.isValid());// FIXME: when? | 	assert(dest.isValid());// FIXME: when? | ||||||
| @@ -970,7 +970,7 @@ CCreatureAnim::EAnimType CCastAnimation::getDownwardsGroup() const | |||||||
| void CCastAnimation::createProjectile(const Point & from, const Point & dest) const | void CCastAnimation::createProjectile(const Point & from, const Point & dest) const | ||||||
| { | { | ||||||
| 	if (!spell->animationInfo.projectile.empty()) | 	if (!spell->animationInfo.projectile.empty()) | ||||||
| 		owner->projectilesController->createSpellProjectile(attackingStack, from, dest, spell); | 		owner.projectilesController->createSpellProjectile(attackingStack, from, dest, spell); | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t CCastAnimation::getAttackClimaxFrame() const | uint32_t CCastAnimation::getAttackClimaxFrame() const | ||||||
| @@ -983,8 +983,8 @@ uint32_t CCastAnimation::getAttackClimaxFrame() const | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, int effects): | CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, int effects): | ||||||
| 	CBattleAnimation(_owner), | 	CBattleAnimation(owner), | ||||||
| 	animation(std::make_shared<CAnimation>(animationName)), | 	animation(std::make_shared<CAnimation>(animationName)), | ||||||
| 	sound(sound), | 	sound(sound), | ||||||
| 	effectFlags(effects), | 	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::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, std::vector<BattleHex> hex, int effects): | ||||||
| 	CPointEffectAnimation(_owner, sound, animationName, effects) | 	CPointEffectAnimation(owner, sound, animationName, effects) | ||||||
| { | { | ||||||
| 	battlehexes = hex; | 	battlehexes = hex; | ||||||
| } | } | ||||||
|  |  | ||||||
| CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, BattleHex hex, int effects): | CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, BattleHex hex, int effects): | ||||||
| 	CPointEffectAnimation(_owner, sound, animationName, effects) | 	CPointEffectAnimation(owner, sound, animationName, effects) | ||||||
| { | { | ||||||
| 	assert(hex.isValid()); | 	assert(hex.isValid()); | ||||||
| 	battlehexes.push_back(hex); | 	battlehexes.push_back(hex); | ||||||
| } | } | ||||||
|  |  | ||||||
| CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos, int effects): | CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, std::vector<Point> pos, int effects): | ||||||
| 	CPointEffectAnimation(_owner, sound, animationName, effects) | 	CPointEffectAnimation(owner, sound, animationName, effects) | ||||||
| { | { | ||||||
| 	positions = pos; | 	positions = pos; | ||||||
| } | } | ||||||
|  |  | ||||||
| CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos, int effects): | CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, Point pos, int effects): | ||||||
| 	CPointEffectAnimation(_owner, sound, animationName, effects) | 	CPointEffectAnimation(owner, sound, animationName, effects) | ||||||
| { | { | ||||||
| 	positions.push_back(pos); | 	positions.push_back(pos); | ||||||
| } | } | ||||||
|  |  | ||||||
| CPointEffectAnimation::CPointEffectAnimation(BattleInterface * _owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex,   int effects): | CPointEffectAnimation::CPointEffectAnimation(BattleInterface & owner, soundBase::soundID sound, std::string animationName, Point pos, BattleHex hex,   int effects): | ||||||
| 	CPointEffectAnimation(_owner, sound, animationName, effects) | 	CPointEffectAnimation(owner, sound, animationName, effects) | ||||||
| { | { | ||||||
| 	assert(hex.isValid()); | 	assert(hex.isValid()); | ||||||
| 	battlehexes.push_back(hex); | 	battlehexes.push_back(hex); | ||||||
| @@ -1043,9 +1043,9 @@ bool CPointEffectAnimation::init() | |||||||
|  |  | ||||||
| 	if (screenFill()) | 	if (screenFill()) | ||||||
| 	{ | 	{ | ||||||
| 		for(int i=0; i * first->width() < owner->pos.w ; ++i) | 		for(int i=0; i * first->width() < owner.pos.w ; ++i) | ||||||
| 			for(int j=0; j * first->height() < owner->pos.h ; ++j) | 			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())); | 				positions.push_back(Point( owner.pos.x + i * first->width(), owner.pos.y + j * first->height())); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	BattleEffect be; | 	BattleEffect be; | ||||||
| @@ -1070,8 +1070,8 @@ bool CPointEffectAnimation::init() | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			const CStack * destStack = owner->getCurrentPlayerInterface()->cb->battleGetStackByPos(battlehexes[i], false); | 			const CStack * destStack = owner.getCurrentPlayerInterface()->cb->battleGetStackByPos(battlehexes[i], false); | ||||||
| 			Rect tilePos = owner->fieldController->hexPositionAbsolute(battlehexes[i]); | 			Rect tilePos = owner.fieldController->hexPositionAbsolute(battlehexes[i]); | ||||||
|  |  | ||||||
| 			be.x = tilePos.x + tilePos.w/2 - first->width()/2; | 			be.x = tilePos.x + tilePos.w/2 - first->width()/2; | ||||||
|  |  | ||||||
| @@ -1083,7 +1083,7 @@ bool CPointEffectAnimation::init() | |||||||
| 			else | 			else | ||||||
| 				be.y = tilePos.y - first->height()/2; | 				be.y = tilePos.y - first->height()/2; | ||||||
| 		} | 		} | ||||||
| 		owner->effectsController->battleEffects.push_back(be); | 		owner.effectsController->battleEffects.push_back(be); | ||||||
| 	} | 	} | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| @@ -1156,7 +1156,7 @@ void CPointEffectAnimation::playEffect() | |||||||
| 	if ( effectFinished ) | 	if ( effectFinished ) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	for(auto & elem : owner->effectsController->battleEffects) | 	for(auto & elem : owner.effectsController->battleEffects) | ||||||
| 	{ | 	{ | ||||||
| 		if(elem.effectID == ID) | 		if(elem.effectID == ID) | ||||||
| 		{ | 		{ | ||||||
| @@ -1174,7 +1174,7 @@ void CPointEffectAnimation::playEffect() | |||||||
|  |  | ||||||
| void CPointEffectAnimation::clearEffect() | void CPointEffectAnimation::clearEffect() | ||||||
| { | { | ||||||
| 	auto & effects = owner->effectsController->battleEffects; | 	auto & effects = owner.effectsController->battleEffects; | ||||||
|  |  | ||||||
| 	for ( auto it = effects.begin(); it != effects.end(); ) | 	for ( auto it = effects.begin(); it != effects.end(); ) | ||||||
| 	{ | 	{ | ||||||
| @@ -1191,8 +1191,8 @@ CPointEffectAnimation::~CPointEffectAnimation() | |||||||
| 	assert(soundFinished); | 	assert(soundFinished); | ||||||
| } | } | ||||||
|  |  | ||||||
| CWaitingAnimation::CWaitingAnimation(BattleInterface * owner_): | CWaitingAnimation::CWaitingAnimation(BattleInterface & owner): | ||||||
| 	CBattleAnimation(owner_) | 	CBattleAnimation(owner) | ||||||
| {} | {} | ||||||
|  |  | ||||||
| void CWaitingAnimation::nextFrame() | void CWaitingAnimation::nextFrame() | ||||||
| @@ -1201,8 +1201,8 @@ void CWaitingAnimation::nextFrame() | |||||||
| 	delete this; | 	delete this; | ||||||
| } | } | ||||||
|  |  | ||||||
| CWaitingProjectileAnimation::CWaitingProjectileAnimation(BattleInterface * owner_, const CStack * shooter): | CWaitingProjectileAnimation::CWaitingProjectileAnimation(BattleInterface & owner, const CStack * shooter): | ||||||
| 	CWaitingAnimation(owner_), | 	CWaitingAnimation(owner), | ||||||
| 	shooter(shooter) | 	shooter(shooter) | ||||||
| {} | {} | ||||||
|  |  | ||||||
| @@ -1219,7 +1219,7 @@ bool CWaitingProjectileAnimation::init() | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if(owner->projectilesController->hasActiveProjectile(shooter)) | 	if(owner.projectilesController->hasActiveProjectile(shooter)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ class CBattleAnimation | |||||||
| { | { | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
| 	bool initialized; | 	bool initialized; | ||||||
|  |  | ||||||
| 	std::vector<CBattleAnimation *> & pendingAnimations(); | 	std::vector<CBattleAnimation *> & pendingAnimations(); | ||||||
| @@ -49,7 +49,7 @@ public: | |||||||
| 	virtual void nextFrame() {} //call every new frame | 	virtual void nextFrame() {} //call every new frame | ||||||
| 	virtual ~CBattleAnimation(); | 	virtual ~CBattleAnimation(); | ||||||
|  |  | ||||||
| 	CBattleAnimation(BattleInterface * _owner); | 	CBattleAnimation(BattleInterface & owner); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Sub-class which is responsible for managing the battle stack animation. | /// 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 | 	std::shared_ptr<CreatureAnimation> myAnim; //animation for our stack, managed by CBattleInterface | ||||||
| 	const CStack * stack; //id of stack whose animation it is | 	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 shiftColor(const ColorShifter * shifter); | ||||||
| 	void rotateStack(BattleHex hex); | 	void rotateStack(BattleHex hex); | ||||||
| @@ -83,7 +83,7 @@ public: | |||||||
| 	void nextFrame() override; | 	void nextFrame() override; | ||||||
| 	bool checkInitialConditions(); | 	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(); | 	~CAttackAnimation(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -104,7 +104,7 @@ public: | |||||||
| 	bool init() override; | 	bool init() override; | ||||||
| 	void nextFrame() override; | 	void nextFrame() override; | ||||||
|  |  | ||||||
| 	CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface * _owner); | 	CDefenceAnimation(StackAttackedInfo _attackedInfo, BattleInterface & owner); | ||||||
| 	~CDefenceAnimation(); | 	~CDefenceAnimation(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -117,7 +117,7 @@ public: | |||||||
| 	bool init() override; | 	bool init() override; | ||||||
| 	void nextFrame() override; | 	void nextFrame() override; | ||||||
|  |  | ||||||
| 	CDummyAnimation(BattleInterface * _owner, int howManyFrames); | 	CDummyAnimation(BattleInterface & owner, int howManyFrames); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Hand-to-hand attack | /// Hand-to-hand attack | ||||||
| @@ -126,7 +126,7 @@ class CMeleeAttackAnimation : public CAttackAnimation | |||||||
| public: | public: | ||||||
| 	bool init() override; | 	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 | /// Base class for all animations that play during stack movement | ||||||
| @@ -136,7 +136,7 @@ public: | |||||||
| 	BattleHex currentHex; | 	BattleHex currentHex; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
| 	CStackMoveAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex _currentHex); | 	CStackMoveAnimation(BattleInterface & owner, const CStack * _stack, BattleHex _currentHex); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Move animation of a creature | /// Move animation of a creature | ||||||
| @@ -158,7 +158,7 @@ public: | |||||||
| 	bool init() override; | 	bool init() override; | ||||||
| 	void nextFrame() 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(); | 	~CMovementAnimation(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -168,7 +168,7 @@ class CMovementEndAnimation : public CStackMoveAnimation | |||||||
| public: | public: | ||||||
| 	bool init() override; | 	bool init() override; | ||||||
|  |  | ||||||
| 	CMovementEndAnimation(BattleInterface * _owner, const CStack * _stack, BattleHex destTile); | 	CMovementEndAnimation(BattleInterface & owner, const CStack * _stack, BattleHex destTile); | ||||||
| 	~CMovementEndAnimation(); | 	~CMovementEndAnimation(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -178,7 +178,7 @@ class CMovementStartAnimation : public CStackMoveAnimation | |||||||
| public: | public: | ||||||
| 	bool init() override; | 	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) | /// Class responsible for animation of stack chaning direction (left <-> right) | ||||||
| @@ -190,7 +190,7 @@ public: | |||||||
|  |  | ||||||
| 	void setupSecondPart(); | 	void setupSecondPart(); | ||||||
|  |  | ||||||
| 	CReverseAnimation(BattleInterface * _owner, const CStack * stack, BattleHex dest, bool _priority); | 	CReverseAnimation(BattleInterface & owner, const CStack * stack, BattleHex dest, bool _priority); | ||||||
| 	~CReverseAnimation(); | 	~CReverseAnimation(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -213,7 +213,7 @@ protected: | |||||||
| 	virtual uint32_t getAttackClimaxFrame() const = 0; | 	virtual uint32_t getAttackClimaxFrame() const = 0; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	CRangedAttackAnimation(BattleInterface * owner_, const CStack * attacker, BattleHex dest, const CStack * defender); | 	CRangedAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest, const CStack * defender); | ||||||
| 	~CRangedAttackAnimation(); | 	~CRangedAttackAnimation(); | ||||||
|  |  | ||||||
| 	bool init() override; | 	bool init() override; | ||||||
| @@ -231,7 +231,7 @@ class CShootingAnimation : public CRangedAttackAnimation | |||||||
| 	uint32_t getAttackClimaxFrame() const override; | 	uint32_t getAttackClimaxFrame() const override; | ||||||
|  |  | ||||||
| public: | 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; | 	int catapultDamage; | ||||||
|  |  | ||||||
| public: | 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 createProjectile(const Point & from, const Point & dest) const override; | ||||||
| 	void nextFrame() override; | 	void nextFrame() override; | ||||||
| @@ -262,7 +262,7 @@ class CCastAnimation : public CRangedAttackAnimation | |||||||
| 	uint32_t getAttackClimaxFrame() const override; | 	uint32_t getAttackClimaxFrame() const override; | ||||||
|  |  | ||||||
| public: | 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 | struct CPointEffectParameters | ||||||
| @@ -313,17 +313,17 @@ public: | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	/// Create animation with screen-wide effect | 	/// 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 | 	/// 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, 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, std::vector<Point> pos    , int effects = 0); | ||||||
|  |  | ||||||
| 	/// Create animation positioned at certain hex(es) | 	/// 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, 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, 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(); | 	 ~CPointEffectAnimation(); | ||||||
|  |  | ||||||
| 	bool init() override; | 	bool init() override; | ||||||
| @@ -334,7 +334,7 @@ public: | |||||||
| class CWaitingAnimation : public CBattleAnimation | class CWaitingAnimation : public CBattleAnimation | ||||||
| { | { | ||||||
| protected: | protected: | ||||||
| 	CWaitingAnimation(BattleInterface * owner_); | 	CWaitingAnimation(BattleInterface & owner); | ||||||
| public: | public: | ||||||
| 	void nextFrame() override; | 	void nextFrame() override; | ||||||
| }; | }; | ||||||
| @@ -344,7 +344,7 @@ class CWaitingProjectileAnimation : public CWaitingAnimation | |||||||
| { | { | ||||||
| 	const CStack * shooter; | 	const CStack * shooter; | ||||||
| public: | public: | ||||||
| 	CWaitingProjectileAnimation(BattleInterface * owner_, const CStack * shooter); | 	CWaitingProjectileAnimation(BattleInterface & owner, const CStack * shooter); | ||||||
|  |  | ||||||
| 	bool init() override; | 	bool init() override; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ | |||||||
| #include "../../lib/CStack.h" | #include "../../lib/CStack.h" | ||||||
| #include "../../lib/CConfigHandler.h" | #include "../../lib/CConfigHandler.h" | ||||||
|  |  | ||||||
| BattleControlPanel::BattleControlPanel(BattleInterface * owner, const Point & position): | BattleControlPanel::BattleControlPanel(BattleInterface & owner, const Point & position): | ||||||
| 	owner(owner) | 	owner(owner) | ||||||
| { | { | ||||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; | 	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)); | 	console = std::make_shared<BattleConsole>(Rect(211, 4, 406,38)); | ||||||
| 	GH.statusbar = console; | 	GH.statusbar = console; | ||||||
|  |  | ||||||
| 	if ( owner->tacticsMode ) | 	if ( owner.tacticsMode ) | ||||||
| 		tacticPhaseStarted(); | 		tacticPhaseStarted(); | ||||||
| 	else | 	else | ||||||
| 		tacticPhaseEnded(); | 		tacticPhaseEnded(); | ||||||
| @@ -81,7 +81,7 @@ void BattleControlPanel::tacticPhaseStarted() | |||||||
| 	btactNext = std::make_shared<CButton>(Point(213, 4), "icm011.def", std::make_pair("", ""), [&]() { bTacticNextStack();}, SDLK_SPACE); | 	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); | 	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 = std::make_shared<CPicture>("COPLACBR.BMP", 0, 0); | ||||||
| 	menu->colorize(owner->curInt->playerID); | 	menu->colorize(owner.curInt->playerID); | ||||||
| 	menu->recActions &= ~(SHOWALL | UPDATE); | 	menu->recActions &= ~(SHOWALL | UPDATE); | ||||||
| } | } | ||||||
| void BattleControlPanel::tacticPhaseEnded() | void BattleControlPanel::tacticPhaseEnded() | ||||||
| @@ -92,13 +92,13 @@ void BattleControlPanel::tacticPhaseEnded() | |||||||
| 	btactEnd.reset(); | 	btactEnd.reset(); | ||||||
|  |  | ||||||
| 	menu = std::make_shared<CPicture>("CBAR.BMP", 0, 0); | 	menu = std::make_shared<CPicture>("CBAR.BMP", 0, 0); | ||||||
| 	menu->colorize(owner->curInt->playerID); | 	menu->colorize(owner.curInt->playerID); | ||||||
| 	menu->recActions &= ~(SHOWALL | UPDATE); | 	menu->recActions &= ~(SHOWALL | UPDATE); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::bOptionsf() | void BattleControlPanel::bOptionsf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	CCS->curh->changeGraphic(ECursor::ADVENTURE,0); | 	CCS->curh->changeGraphic(ECursor::ADVENTURE,0); | ||||||
| @@ -108,13 +108,13 @@ void BattleControlPanel::bOptionsf() | |||||||
|  |  | ||||||
| void BattleControlPanel::bSurrenderf() | void BattleControlPanel::bSurrenderf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	int cost = owner->curInt->cb->battleGetSurrenderCost(); | 	int cost = owner.curInt->cb->battleGetSurrenderCost(); | ||||||
| 	if(cost >= 0) | 	if(cost >= 0) | ||||||
| 	{ | 	{ | ||||||
| 		std::string enemyHeroName = owner->curInt->cb->battleGetEnemyHero().name; | 		std::string enemyHeroName = owner.curInt->cb->battleGetEnemyHero().name; | ||||||
| 		if(enemyHeroName.empty()) | 		if(enemyHeroName.empty()) | ||||||
| 		{ | 		{ | ||||||
| 			logGlobal->warn("Surrender performed without enemy hero, should not happen!"); | 			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." | 		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() | void BattleControlPanel::bFleef() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if ( owner->curInt->cb->battleCanFlee() ) | 	if ( owner.curInt->cb->battleCanFlee() ) | ||||||
| 	{ | 	{ | ||||||
| 		CFunctionList<void()> ony = std::bind(&BattleControlPanel::reallyFlee,this); | 		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 | 	else | ||||||
| 	{ | 	{ | ||||||
| 		std::vector<std::shared_ptr<CComponent>> comps; | 		std::vector<std::shared_ptr<CComponent>> comps; | ||||||
| 		std::string heroName; | 		std::string heroName; | ||||||
| 		//calculating fleeing hero's name | 		//calculating fleeing hero's name | ||||||
| 		if (owner->attackingHeroInstance) | 		if (owner.attackingHeroInstance) | ||||||
| 			if (owner->attackingHeroInstance->tempOwner == owner->curInt->cb->getMyColor()) | 			if (owner.attackingHeroInstance->tempOwner == owner.curInt->cb->getMyColor()) | ||||||
| 				heroName = owner->attackingHeroInstance->name; | 				heroName = owner.attackingHeroInstance->name; | ||||||
| 		if (owner->defendingHeroInstance) | 		if (owner.defendingHeroInstance) | ||||||
| 			if (owner->defendingHeroInstance->tempOwner == owner->curInt->cb->getMyColor()) | 			if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getMyColor()) | ||||||
| 				heroName = owner->defendingHeroInstance->name; | 				heroName = owner.defendingHeroInstance->name; | ||||||
| 		//calculating text | 		//calculating text | ||||||
| 		auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat! | 		auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat! | ||||||
|  |  | ||||||
| 		//printing message | 		//printing message | ||||||
| 		owner->curInt->showInfoDialog(boost::to_string(txt), comps); | 		owner.curInt->showInfoDialog(boost::to_string(txt), comps); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::reallyFlee() | void BattleControlPanel::reallyFlee() | ||||||
| { | { | ||||||
| 	owner->giveCommand(EActionType::RETREAT); | 	owner.giveCommand(EActionType::RETREAT); | ||||||
| 	CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); | 	CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::reallySurrender() | 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 | 	else | ||||||
| 	{ | 	{ | ||||||
| 		owner->giveCommand(EActionType::SURRENDER); | 		owner.giveCommand(EActionType::SURRENDER); | ||||||
| 		CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); | 		CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::bAutofightf() | void BattleControlPanel::bAutofightf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	//Stop auto-fight mode | 	//Stop auto-fight mode | ||||||
| 	if(owner->curInt->isAutoFightOn) | 	if(owner.curInt->isAutoFightOn) | ||||||
| 	{ | 	{ | ||||||
| 		assert(owner->curInt->autofightingAI); | 		assert(owner.curInt->autofightingAI); | ||||||
| 		owner->curInt->isAutoFightOn = false; | 		owner.curInt->isAutoFightOn = false; | ||||||
| 		logGlobal->trace("Stopping the autofight..."); | 		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); | 		blockUI(true); | ||||||
|  |  | ||||||
| 		auto ai = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String()); | 		auto ai = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String()); | ||||||
| 		ai->init(owner->curInt->env, owner->curInt->cb); | 		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()); | 		ai->battleStart(owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.curInt->cb->battleGetMySide()); | ||||||
| 		owner->curInt->autofightingAI = ai; | 		owner.curInt->autofightingAI = ai; | ||||||
| 		owner->curInt->cb->registerBattleInterface(ai); | 		owner.curInt->cb->registerBattleInterface(ai); | ||||||
|  |  | ||||||
| 		owner->requestAutofightingAIToTakeAction(); | 		owner.requestAutofightingAIToTakeAction(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::bSpellf() | void BattleControlPanel::bSpellf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (!owner->myTurn) | 	if (!owner.myTurn) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	auto myHero = owner->currentHero(); | 	auto myHero = owner.currentHero(); | ||||||
| 	if(!myHero) | 	if(!myHero) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	CCS->curh->changeGraphic(ECursor::ADVENTURE,0); | 	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) | 	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) | 	else if (spellCastProblem == ESpellCastProblem::MAGIC_IS_BLOCKED) | ||||||
| 	{ | 	{ | ||||||
| 		//TODO: move to spell mechanics, add more information to spell cast problem | 		//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 | 		//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) | 		if (!blockingBonus) | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
| @@ -234,7 +234,7 @@ void BattleControlPanel::bSpellf() | |||||||
| 			const auto artID = ArtifactID(blockingBonus->sid); | 			const auto artID = ArtifactID(blockingBonus->sid); | ||||||
| 			//If we have artifact, put name of our hero. Otherwise assume it's the enemy. | 			//If we have artifact, put name of our hero. Otherwise assume it's the enemy. | ||||||
| 			//TODO check who *really* is source of bonus | 			//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. | 			//%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]) | 			LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683]) | ||||||
| @@ -245,25 +245,25 @@ void BattleControlPanel::bSpellf() | |||||||
|  |  | ||||||
| void BattleControlPanel::bWaitf() | void BattleControlPanel::bWaitf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (owner->stacksController->getActiveStack() != nullptr) | 	if (owner.stacksController->getActiveStack() != nullptr) | ||||||
| 		owner->giveCommand(EActionType::WAIT); | 		owner.giveCommand(EActionType::WAIT); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::bDefencef() | void BattleControlPanel::bDefencef() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (owner->stacksController->getActiveStack() != nullptr) | 	if (owner.stacksController->getActiveStack() != nullptr) | ||||||
| 		owner->giveCommand(EActionType::DEFEND); | 		owner.giveCommand(EActionType::DEFEND); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::bConsoleUpf() | void BattleControlPanel::bConsoleUpf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	console->scrollUp(); | 	console->scrollUp(); | ||||||
| @@ -271,7 +271,7 @@ void BattleControlPanel::bConsoleUpf() | |||||||
|  |  | ||||||
| void BattleControlPanel::bConsoleDownf() | void BattleControlPanel::bConsoleDownf() | ||||||
| { | { | ||||||
| 	if (owner->actionsController->spellcastingModeActive()) | 	if (owner.actionsController->spellcastingModeActive()) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	console->scrollDown(); | 	console->scrollDown(); | ||||||
| @@ -279,38 +279,38 @@ void BattleControlPanel::bConsoleDownf() | |||||||
|  |  | ||||||
| void BattleControlPanel::bTacticNextStack() | void BattleControlPanel::bTacticNextStack() | ||||||
| { | { | ||||||
| 	owner->tacticNextStack(nullptr); | 	owner.tacticNextStack(nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::bTacticPhaseEnd() | void BattleControlPanel::bTacticPhaseEnd() | ||||||
| { | { | ||||||
| 	owner->tacticPhaseEnd(); | 	owner.tacticPhaseEnd(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleControlPanel::blockUI(bool on) | void BattleControlPanel::blockUI(bool on) | ||||||
| { | { | ||||||
| 	bool canCastSpells = false; | 	bool canCastSpells = false; | ||||||
| 	auto hero = owner->curInt->cb->battleGetMyHero(); | 	auto hero = owner.curInt->cb->battleGetMyHero(); | ||||||
|  |  | ||||||
| 	if(hero) | 	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 | 		//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; | 		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); | 	bOptions->block(on); | ||||||
| 	bFlee->block(on || !owner->curInt->cb->battleCanFlee()); | 	bFlee->block(on || !owner.curInt->cb->battleCanFlee()); | ||||||
| 	bSurrender->block(on || owner->curInt->cb->battleGetSurrenderCost() < 0); | 	bSurrender->block(on || owner.curInt->cb->battleGetSurrenderCost() < 0); | ||||||
|  |  | ||||||
| 	// block only if during enemy turn and auto-fight is off | 	// block only if during enemy turn and auto-fight is off | ||||||
| 	// otherwise - crash on accessing non-exisiting active stack | 	// 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); | 		btactNext->block(on); | ||||||
| 		btactEnd->block(on); | 		btactEnd->block(on); | ||||||
| @@ -322,7 +322,7 @@ void BattleControlPanel::blockUI(bool on) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	bSpell->block(on || owner->tacticsMode || !canCastSpells); | 	bSpell->block(on || owner.tacticsMode || !canCastSpells); | ||||||
| 	bWait->block(on || owner->tacticsMode || !canWait); | 	bWait->block(on || owner.tacticsMode || !canWait); | ||||||
| 	bDefence->block(on || owner->tacticsMode); | 	bDefence->block(on || owner.tacticsMode); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ class BattleConsole; | |||||||
| /// GUI object that handles functionality of panel at the bottom of combat screen | /// GUI object that handles functionality of panel at the bottom of combat screen | ||||||
| class BattleControlPanel : public CIntObject | class BattleControlPanel : public CIntObject | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	std::shared_ptr<CPicture> menu; | 	std::shared_ptr<CPicture> menu; | ||||||
|  |  | ||||||
| @@ -71,6 +71,6 @@ public: | |||||||
| 	/// Toggle UI to displaying battle log in place of tactics UI | 	/// Toggle UI to displaying battle log in place of tactics UI | ||||||
| 	void tacticPhaseEnded(); | 	void tacticPhaseEnded(); | ||||||
|  |  | ||||||
| 	BattleControlPanel(BattleInterface * owner, const Point & position); | 	BattleControlPanel(BattleInterface & owner, const Point & position); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
| #include "../../lib/IGameEventsReceiver.h" | #include "../../lib/IGameEventsReceiver.h" | ||||||
| #include "../../lib/CGeneralTextHandler.h" | #include "../../lib/CGeneralTextHandler.h" | ||||||
|  |  | ||||||
| BattleEffectsController::BattleEffectsController(BattleInterface * owner): | BattleEffectsController::BattleEffectsController(BattleInterface & owner): | ||||||
| 	owner(owner) | 	owner(owner) | ||||||
| {} | {} | ||||||
|  |  | ||||||
| @@ -44,14 +44,14 @@ void BattleEffectsController::displayEffect(EBattleEffect::EBattleEffect effect, | |||||||
| { | { | ||||||
| 	std::string customAnim = graphics->battleACToDef[effect][0]; | 	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) | void BattleEffectsController::displayCustomEffects(const std::vector<CustomEffectInfo> & customEffects) | ||||||
| { | { | ||||||
| 	for(const CustomEffectInfo & one : 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(s); | ||||||
| 		assert(one.effect != 0); | 		assert(one.effect != 0); | ||||||
| @@ -62,7 +62,7 @@ void BattleEffectsController::displayCustomEffects(const std::vector<CustomEffec | |||||||
|  |  | ||||||
| void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bte) | 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) | 	if(!stack) | ||||||
| 	{ | 	{ | ||||||
| 		logGlobal->error("Invalid stack ID %d", bte.stackID); | 		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]; | 			std::string hlp = CGI->generaltexth->allTexts[33]; | ||||||
| 			boost::algorithm::replace_first(hlp,"%s",(stack->getName())); | 			boost::algorithm::replace_first(hlp,"%s",(stack->getName())); | ||||||
| 			displayEffect(EBattleEffect::GOOD_MORALE, soundBase::GOODMRLE, stack->getPosition()); | 			displayEffect(EBattleEffect::GOOD_MORALE, soundBase::GOODMRLE, stack->getPosition()); | ||||||
| 			owner->controlPanel->console->addText(hlp); | 			owner.controlPanel->console->addText(hlp); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		default: | 		default: | ||||||
| @@ -100,21 +100,21 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt | |||||||
|  |  | ||||||
| void BattleEffectsController::startAction(const BattleAction* action) | 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) | 	switch(action->actionType) | ||||||
| 	{ | 	{ | ||||||
| 	case EActionType::WAIT: | 	case EActionType::WAIT: | ||||||
| 		owner->controlPanel->console->addText(stack->formatGeneralMessage(136)); | 		owner.controlPanel->console->addText(stack->formatGeneralMessage(136)); | ||||||
| 		break; | 		break; | ||||||
| 	case EActionType::BAD_MORALE: | 	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()); | 		displayEffect(EBattleEffect::BAD_MORALE, soundBase::BADMRLE, stack->getPosition()); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	//displaying special abilities | 	//displaying special abilities | ||||||
| 	auto actionTarget = action->getTarget(owner->curInt->cb.get()); | 	auto actionTarget = action->getTarget(owner.curInt->cb.get()); | ||||||
| 	switch(action->actionType) | 	switch(action->actionType) | ||||||
| 	{ | 	{ | ||||||
| 		case EActionType::STACK_HEAL: | 		case EActionType::STACK_HEAL: | ||||||
|   | |||||||
| @@ -59,13 +59,13 @@ struct BattleEffect | |||||||
| /// Controls rendering of effects in battle, e.g. from spells, abilities and various other actions like morale | /// Controls rendering of effects in battle, e.g. from spells, abilities and various other actions like morale | ||||||
| class BattleEffectsController | class BattleEffectsController | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	/// list of current effects that are being displayed on screen (spells & creature abilities) | 	/// list of current effects that are being displayed on screen (spells & creature abilities) | ||||||
| 	std::vector<BattleEffect> battleEffects; | 	std::vector<BattleEffect> battleEffects; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleEffectsController(BattleInterface * owner); | 	BattleEffectsController(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	void startAction(const BattleAction* action); | 	void startAction(const BattleAction* action); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,21 +33,21 @@ | |||||||
| #include "../../lib/CStack.h" | #include "../../lib/CStack.h" | ||||||
| #include "../../lib/spells/ISpellMechanics.h" | #include "../../lib/spells/ISpellMechanics.h" | ||||||
|  |  | ||||||
| BattleFieldController::BattleFieldController(BattleInterface * owner): | BattleFieldController::BattleFieldController(BattleInterface & owner): | ||||||
| 	owner(owner), | 	owner(owner), | ||||||
| 	attackingHex(BattleHex::INVALID) | 	attackingHex(BattleHex::INVALID) | ||||||
| { | { | ||||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; | 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; | ||||||
| 	pos.w = owner->pos.w; | 	pos.w = owner.pos.w; | ||||||
| 	pos.h = owner->pos.h; | 	pos.h = owner.pos.h; | ||||||
|  |  | ||||||
| 	//preparing cells and hexes | 	//preparing cells and hexes | ||||||
| 	cellBorder = IImage::createFromFile("CCELLGRD.BMP"); | 	cellBorder = IImage::createFromFile("CCELLGRD.BMP"); | ||||||
| 	cellShade = IImage::createFromFile("CCELLSHD.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) | 		if(bfieldType == BattleField::NONE) | ||||||
| 			logGlobal->error("Invalid battlefield returned for current battle"); | 			logGlobal->error("Invalid battlefield returned for current battle"); | ||||||
| @@ -56,7 +56,7 @@ BattleFieldController::BattleFieldController(BattleInterface * owner): | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		std::string backgroundName = owner->siegeController->getBattleBackgroundName(); | 		std::string backgroundName = owner.siegeController->getBattleBackgroundName(); | ||||||
| 		background = IImage::createFromFile(backgroundName); | 		background = IImage::createFromFile(backgroundName); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -80,11 +80,11 @@ BattleFieldController::BattleFieldController(BattleInterface * owner): | |||||||
| 		auto hex = std::make_shared<ClickableHex>(); | 		auto hex = std::make_shared<ClickableHex>(); | ||||||
| 		hex->myNumber = h; | 		hex->myNumber = h; | ||||||
| 		hex->pos = hexPositionAbsolute(h); | 		hex->pos = hexPositionAbsolute(h); | ||||||
| 		hex->myInterface = owner; | 		hex->myInterface = &owner; | ||||||
| 		bfield.push_back(hex); | 		bfield.push_back(hex); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	auto accessibility = owner->curInt->cb->getAccesibility(); | 	auto accessibility = owner.curInt->cb->getAccesibility(); | ||||||
| 	for(int i = 0; i < accessibility.size(); i++) | 	for(int i = 0; i < accessibility.size(); i++) | ||||||
| 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE); | 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE); | ||||||
| } | } | ||||||
| @@ -97,12 +97,12 @@ void BattleFieldController::renderBattlefield(Canvas & canvas) | |||||||
|  |  | ||||||
| 	renderer.execute(canvas); | 	renderer.execute(canvas); | ||||||
|  |  | ||||||
| 	owner->projectilesController->showProjectiles(canvas); | 	owner.projectilesController->showProjectiles(canvas); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleFieldController::showBackground(Canvas & 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); | 		showBackgroundImageWithHexes(canvas); | ||||||
| 	else | 	else | ||||||
| 		showBackgroundImage(canvas); | 		showBackgroundImage(canvas); | ||||||
| @@ -113,38 +113,38 @@ void BattleFieldController::showBackground(Canvas & canvas) | |||||||
|  |  | ||||||
| void BattleFieldController::showBackgroundImage(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()); | 	owner.obstacleController->showAbsoluteObstacles(canvas, pos.topLeft()); | ||||||
| 	if ( owner->siegeController ) | 	if ( owner.siegeController ) | ||||||
| 		owner->siegeController->showAbsoluteObstacles(canvas, pos.topLeft()); | 		owner.siegeController->showAbsoluteObstacles(canvas, pos.topLeft()); | ||||||
|  |  | ||||||
| 	if (settings["battle"]["cellBorders"].Bool()) | 	if (settings["battle"]["cellBorders"].Bool()) | ||||||
| 		canvas.draw(*cellBorders, owner->pos.topLeft()); | 		canvas.draw(*cellBorders, owner.pos.topLeft()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleFieldController::showBackgroundImageWithHexes(Canvas & canvas) | void BattleFieldController::showBackgroundImageWithHexes(Canvas & canvas) | ||||||
| { | { | ||||||
| 	canvas.draw(*backgroundWithHexes.get(), owner->pos.topLeft()); | 	canvas.draw(*backgroundWithHexes.get(), owner.pos.topLeft()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleFieldController::redrawBackgroundWithHexes() | void BattleFieldController::redrawBackgroundWithHexes() | ||||||
| { | { | ||||||
| 	const CStack *activeStack = owner->stacksController->getActiveStack(); | 	const CStack *activeStack = owner.stacksController->getActiveStack(); | ||||||
| 	std::vector<BattleHex> attackableHexes; | 	std::vector<BattleHex> attackableHexes; | ||||||
| 	if (activeStack) | 	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++) | 	for(int i = 0; i < accessibility.size(); i++) | ||||||
| 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE); | 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE); | ||||||
|  |  | ||||||
| 	//prepare background graphic with hexes and shaded hexes | 	//prepare background graphic with hexes and shaded hexes | ||||||
| 	backgroundWithHexes->draw(background, Point(0,0)); | 	backgroundWithHexes->draw(background, Point(0,0)); | ||||||
| 	owner->obstacleController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0)); | 	owner.obstacleController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0)); | ||||||
| 	if ( owner->siegeController ) | 	if ( owner.siegeController ) | ||||||
| 		owner->siegeController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0)); | 		owner.siegeController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0)); | ||||||
|  |  | ||||||
| 	if (settings["battle"]["stackRange"].Bool()) | 	if (settings["battle"]["stackRange"].Bool()) | ||||||
| 	{ | 	{ | ||||||
| @@ -173,7 +173,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange() | |||||||
| { | { | ||||||
| 	std::set<BattleHex> result; | 	std::set<BattleHex> result; | ||||||
|  |  | ||||||
| 	if ( !owner->stacksController->getActiveStack()) | 	if ( !owner.stacksController->getActiveStack()) | ||||||
| 		return result; | 		return result; | ||||||
|  |  | ||||||
| 	if ( !settings["battle"]["stackRange"].Bool()) | 	if ( !settings["battle"]["stackRange"].Bool()) | ||||||
| @@ -181,15 +181,15 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange() | |||||||
|  |  | ||||||
| 	auto hoveredHex = getHoveredHex(); | 	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) | 	for(BattleHex hex : set) | ||||||
| 		result.insert(hex); | 		result.insert(hex); | ||||||
|  |  | ||||||
| 	// display the movement shadow of the stack at b (i.e. stack under mouse) | 	// display the movement shadow of the stack at b (i.e. stack under mouse) | ||||||
| 	const CStack * const shere = owner->curInt->cb->battleGetStackByPos(hoveredHex, false); | 	const CStack * const shere = owner.curInt->cb->battleGetStackByPos(hoveredHex, false); | ||||||
| 	if(shere && shere != owner->stacksController->getActiveStack() && shere->alive()) | 	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) | 		for(BattleHex hex : v) | ||||||
| 			result.insert(hex); | 			result.insert(hex); | ||||||
| 	} | 	} | ||||||
| @@ -209,22 +209,22 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange() | |||||||
|  |  | ||||||
| 	spells::Mode mode = spells::Mode::HERO; | 	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(); | 		spell = owner.actionsController->selectedSpell().toSpell(); | ||||||
| 		caster = owner->getActiveHero(); | 		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(); | 		spell = SpellID(owner.stacksController->activeStackSpellToCast()).toSpell(); | ||||||
| 		caster = owner->stacksController->getActiveStack(); | 		caster = owner.stacksController->getActiveStack(); | ||||||
| 		mode = spells::Mode::CREATURE_ACTIVE; | 		mode = spells::Mode::CREATURE_ACTIVE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if(caster && spell) //when casting spell | 	if(caster && spell) //when casting spell | ||||||
| 	{ | 	{ | ||||||
| 		// printing shaded hex(es) | 		// 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); | 		auto shaded = spell->battleMechanics(&event)->rangeInHexes(hoveredHex); | ||||||
|  |  | ||||||
| 		for(BattleHex shadedHex : shaded) | 		for(BattleHex shadedHex : shaded) | ||||||
| @@ -233,7 +233,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange() | |||||||
| 				result.insert(shadedHex); | 				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) | 		if(hoveredHex.getX() != 0 && hoveredHex.getX() != GameConstants::BFIELD_WIDTH - 1) | ||||||
| 			result.insert(hoveredHex); | 			result.insert(hoveredHex); | ||||||
| @@ -280,7 +280,7 @@ Rect BattleFieldController::hexPositionLocal(BattleHex hex) const | |||||||
|  |  | ||||||
| Rect BattleFieldController::hexPositionAbsolute(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) | bool BattleFieldController::isPixelInHex(Point const & position) | ||||||
| @@ -317,7 +317,7 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) | |||||||
| 	sectorCursor.push_back(12); | 	sectorCursor.push_back(12); | ||||||
| 	sectorCursor.push_back(7); | 	sectorCursor.push_back(7); | ||||||
|  |  | ||||||
| 	const bool doubleWide = owner->stacksController->getActiveStack()->doubleWide(); | 	const bool doubleWide = owner.stacksController->getActiveStack()->doubleWide(); | ||||||
| 	bool aboveAttackable = true, belowAttackable = true; | 	bool aboveAttackable = true, belowAttackable = true; | ||||||
|  |  | ||||||
| 	// Exclude directions which cannot be attacked from. | 	// Exclude directions which cannot be attacked from. | ||||||
| @@ -478,12 +478,12 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) | |||||||
| 	{ | 	{ | ||||||
| 	case 12: //from bottom right | 	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 ) + | 			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)) | 			if(vstd::contains(occupyableHexes, destHex)) | ||||||
| 				return 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)) | 				if (vstd::contains(occupyableHexes, destHex+1)) | ||||||
| 					return 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 ); | 			destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH-1 : GameConstants::BFIELD_WIDTH ); | ||||||
| 			if (vstd::contains(occupyableHexes, destHex)) | 			if (vstd::contains(occupyableHexes, destHex)) | ||||||
| 				return 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)) | 				if(vstd::contains(occupyableHexes, destHex+1)) | ||||||
| 					return destHex+1; | 					return destHex+1; | ||||||
| @@ -514,9 +514,9 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) | |||||||
| 		} | 		} | ||||||
| 	case 8: //from left | 	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)) | 				if (vstd::contains(acc, myNumber)) | ||||||
| 					return myNumber - 1; | 					return myNumber - 1; | ||||||
| 				else | 				else | ||||||
| @@ -533,7 +533,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) | |||||||
| 			destHex = myNumber - ((myNumber/GameConstants::BFIELD_WIDTH) % 2 ? GameConstants::BFIELD_WIDTH + 1 : GameConstants::BFIELD_WIDTH); | 			destHex = myNumber - ((myNumber/GameConstants::BFIELD_WIDTH) % 2 ? GameConstants::BFIELD_WIDTH + 1 : GameConstants::BFIELD_WIDTH); | ||||||
| 			if(vstd::contains(occupyableHexes, destHex)) | 			if(vstd::contains(occupyableHexes, destHex)) | ||||||
| 				return 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)) | 				if(vstd::contains(occupyableHexes, destHex+1)) | ||||||
| 					return destHex+1; | 					return destHex+1; | ||||||
| @@ -547,12 +547,12 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) | |||||||
| 		} | 		} | ||||||
| 	case 10: //from top right | 	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 ) + | 			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)) | 			if(vstd::contains(occupyableHexes, destHex)) | ||||||
| 				return 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)) | 				if(vstd::contains(occupyableHexes, destHex+1)) | ||||||
| 					return destHex+1; | 					return destHex+1; | ||||||
| @@ -566,9 +566,9 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) | |||||||
| 		} | 		} | ||||||
| 	case 11: //from right | 	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)) | 				if(vstd::contains(acc, myNumber)) | ||||||
| 					return myNumber + 1; | 					return myNumber + 1; | ||||||
| 				else | 				else | ||||||
| @@ -585,7 +585,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) | |||||||
| 			destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH+1 ); | 			destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH+1 ); | ||||||
| 			if(vstd::contains(occupyableHexes, destHex)) | 			if(vstd::contains(occupyableHexes, destHex)) | ||||||
| 				return 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)) | 				if(vstd::contains(occupyableHexes, destHex+1)) | ||||||
| 					return 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 ); | 			destHex = myNumber - ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH-1 ); | ||||||
| 			if (vstd::contains(occupyableHexes, destHex)) | 			if (vstd::contains(occupyableHexes, destHex)) | ||||||
| 				return 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)) | 				if(vstd::contains(occupyableHexes, destHex+1)) | ||||||
| 					return destHex+1; | 					return destHex+1; | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ class BattleInterface; | |||||||
| /// Handles battlefield grid as well as rendering of background layer of battle interface | /// Handles battlefield grid as well as rendering of background layer of battle interface | ||||||
| class BattleFieldController : public CIntObject | class BattleFieldController : public CIntObject | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	std::shared_ptr<IImage> background; | 	std::shared_ptr<IImage> background; | ||||||
| 	std::shared_ptr<IImage> cellBorder; | 	std::shared_ptr<IImage> cellBorder; | ||||||
| @@ -63,7 +63,7 @@ class BattleFieldController : public CIntObject | |||||||
| 	void showHighlightedHexes(Canvas & canvas); | 	void showHighlightedHexes(Canvas & canvas); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleFieldController(BattleInterface * owner); | 	BattleFieldController(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	void redrawBackgroundWithHexes(); | 	void redrawBackgroundWithHexes(); | ||||||
| 	void renderBattlefield(Canvas & canvas); | 	void renderBattlefield(Canvas & canvas); | ||||||
|   | |||||||
| @@ -55,8 +55,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet * | |||||||
| { | { | ||||||
| 	OBJ_CONSTRUCTION; | 	OBJ_CONSTRUCTION; | ||||||
|  |  | ||||||
| 	projectilesController.reset(new BattleProjectileController(this)); |  | ||||||
|  |  | ||||||
| 	if(spectatorInt) | 	if(spectatorInt) | ||||||
| 	{ | 	{ | ||||||
| 		curInt = spectatorInt; | 		curInt = spectatorInt; | ||||||
| @@ -90,7 +88,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet * | |||||||
| 	else | 	else | ||||||
| 		embedQueue = screen->h < 700 || queueSize == "small"; | 		embedQueue = screen->h < 700 || queueSize == "small"; | ||||||
|  |  | ||||||
| 	queue = std::make_shared<StackQueue>(embedQueue, this); | 	queue = std::make_shared<StackQueue>(embedQueue, *this); | ||||||
| 	if(!embedQueue) | 	if(!embedQueue) | ||||||
| 	{ | 	{ | ||||||
| 		if (settings["battle"]["showQueue"].Bool()) | 		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)); | 		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; | 	CPlayerInterface::battleInt = this; | ||||||
|  |  | ||||||
| @@ -110,13 +104,16 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet * | |||||||
| 	this->army1 = army1; | 	this->army1 = army1; | ||||||
| 	this->army2 = army2; | 	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 | 	controlPanel = std::make_shared<BattleControlPanel>(*this, Point(0, 556)); | ||||||
| 	fieldController.reset( new BattleFieldController(this)); | 	projectilesController.reset(new BattleProjectileController(*this)); | ||||||
| 	stacksController.reset( new BattleStacksController(this)); | 	fieldController.reset( new BattleFieldController(*this)); | ||||||
| 	actionsController.reset( new BattleActionsController(this)); | 	stacksController.reset( new BattleStacksController(*this)); | ||||||
| 	effectsController.reset(new BattleEffectsController(this)); | 	actionsController.reset( new BattleActionsController(*this)); | ||||||
|  | 	effectsController.reset(new BattleEffectsController(*this)); | ||||||
|  |  | ||||||
| 	//loading hero animations | 	//loading hero animations | ||||||
| 	if(hero1) // attacking hero | 	if(hero1) // attacking hero | ||||||
| @@ -134,7 +131,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet * | |||||||
| 				battleImage = hero1->type->heroClass->imageBattleMale; | 				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); | 		auto img = attackingHero->animation->getImage(0, 0, true); | ||||||
| 		if(img) | 		if(img) | ||||||
| @@ -158,14 +155,14 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet * | |||||||
| 				battleImage = hero2->type->heroClass->imageBattleMale; | 				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); | 		auto img = defendingHero->animation->getImage(0, 0, true); | ||||||
| 		if(img) | 		if(img) | ||||||
| 			defendingHero->pos = genRect(img->height(), img->width(), pos.x + 693, pos.y - 19); | 			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) | 	if(tacticsMode) | ||||||
| 		tacticNextStack(nullptr); | 		tacticNextStack(nullptr); | ||||||
| @@ -502,7 +499,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) | |||||||
| 		{ | 		{ | ||||||
| 			displaySpellCast(spellID, casterStack->getPosition()); | 			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 | 		else | ||||||
| 		if (sc->tile.isValid() && !spell->animationInfo.projectile.empty()) | 		if (sc->tile.isValid() && !spell->animationInfo.projectile.empty()) | ||||||
| @@ -518,7 +515,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) | |||||||
| 			projectilesController->emitStackProjectile( nullptr ); | 			projectilesController->emitStackProjectile( nullptr ); | ||||||
|  |  | ||||||
| 			// wait fo projectile to end | 			// 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 leftHero = Point(15, 30) + pos; | ||||||
| 		Point rightHero = Point(755, 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_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_B.DEF" : "SP07_A.DEF", rightHero)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -589,7 +586,7 @@ void BattleInterface::displaySpellAnimationQueue(const CSpell::TAnimationQueue & | |||||||
| 	for(const CSpell::TAnimation & animation : q) | 	for(const CSpell::TAnimation & animation : q) | ||||||
| 	{ | 	{ | ||||||
| 		if(animation.pause > 0) | 		if(animation.pause > 0) | ||||||
| 			stacksController->addNewAnim(new CDummyAnimation(this, animation.pause)); | 			stacksController->addNewAnim(new CDummyAnimation(*this, animation.pause)); | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			int flags = 0; | 			int flags = 0; | ||||||
| @@ -604,9 +601,9 @@ void BattleInterface::displaySpellAnimationQueue(const CSpell::TAnimationQueue & | |||||||
| 				flags |= CPointEffectAnimation::SCREEN_FILL; | 				flags |= CPointEffectAnimation::SCREEN_FILL; | ||||||
|  |  | ||||||
| 			if (!destinationTile.isValid()) | 			if (!destinationTile.isValid()) | ||||||
| 				stacksController->addNewAnim(new CPointEffectAnimation(this, soundBase::invalid, animation.resourceName, flags)); | 				stacksController->addNewAnim(new CPointEffectAnimation(*this, soundBase::invalid, animation.resourceName, flags)); | ||||||
| 			else | 			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 | const CGHeroInstance *BattleInterface::currentHero() const | ||||||
| { | { | ||||||
| 	if (attackingHeroInstance->tempOwner == curInt->playerID) | 	if (attackingHeroInstance && attackingHeroInstance->tempOwner == curInt->playerID) | ||||||
| 		return attackingHeroInstance; | 		return attackingHeroInstance; | ||||||
| 	else |  | ||||||
|  | 	if (defendingHeroInstance && defendingHeroInstance->tempOwner == curInt->playerID) | ||||||
| 		return defendingHeroInstance; | 		return defendingHeroInstance; | ||||||
|  |  | ||||||
|  | 	return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| InfoAboutHero BattleInterface::enemyHero() const | InfoAboutHero BattleInterface::enemyHero() const | ||||||
|   | |||||||
| @@ -262,10 +262,10 @@ void BattleHero::switchToNextPhase() | |||||||
| 	currentFrame = firstFrame; | 	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), |     flip(flipG), | ||||||
|     myHero(hero), |     myHero(hero), | ||||||
|     myOwner(owner), | 	myOwner(&owner), | ||||||
|     phase(1), |     phase(1), | ||||||
|     nextPhase(0), |     nextPhase(0), | ||||||
|     flagAnim(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))); | 	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") | 	CWindowObject(PLAYER_COLORED, "comopbck.bmp") | ||||||
| { | { | ||||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | 	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()); | 	viewGrid->setSelected(settings["battle"]["cellBorders"].Bool()); | ||||||
| 	toggles.push_back(viewGrid); | 	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()); | 	movementShadow->setSelected(settings["battle"]["stackRange"].Bool()); | ||||||
| 	toggles.push_back(movementShadow); | 	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()); | 	mouseShadow->setSelected(settings["battle"]["mouseShadow"].Bool()); | ||||||
| 	toggles.push_back(mouseShadow); | 	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; | 	std::shared_ptr<CToggleButton> toggle; | ||||||
| 	toggle = std::make_shared<CToggleButton>(Point( 28, 225), "sysopb9.def", CGI->generaltexth->zelp[422]); | 	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]); | 	toggle = std::make_shared<CToggleButton>(Point(156, 225), "sysob11.def", CGI->generaltexth->zelp[424]); | ||||||
| 	animSpeeds->addToggle(100, toggle); | 	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 = std::make_shared<CButton>(Point(246, 359), "codefaul.def", CGI->generaltexth->zelp[393], [&](){ bDefaultf(); }); | ||||||
| 	setToDefault->setImageOrder(1, 0, 2, 3); | 	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), | 	: embedded(Embedded), | ||||||
| 	owner(_owner) | 	owner(owner) | ||||||
| { | { | ||||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||||
| 	if(embedded) | 	if(embedded) | ||||||
| @@ -689,7 +689,7 @@ void StackQueue::update() | |||||||
| { | { | ||||||
| 	std::vector<battle::Units> queueData; | 	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; | 	size_t boxIndex = 0; | ||||||
|  |  | ||||||
| @@ -705,7 +705,7 @@ void StackQueue::update() | |||||||
|  |  | ||||||
| int32_t StackQueue::getSiegeShooterIconID() | int32_t StackQueue::getSiegeShooterIconID() | ||||||
| { | { | ||||||
| 	return owner->siegeController->getSiegedTown()->town->faction->index; | 	return owner.siegeController->getSiegedTown()->town->faction->index; | ||||||
| } | } | ||||||
|  |  | ||||||
| StackQueue::StackBox::StackBox(StackQueue * owner): | StackQueue::StackBox::StackBox(StackQueue * owner): | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ public: | |||||||
| 	void hover(bool on) override; | 	void hover(bool on) override; | ||||||
| 	void clickLeft(tribool down, bool previousState) override; //call-in | 	void clickLeft(tribool down, bool previousState) override; //call-in | ||||||
| 	void clickRight(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 | class HeroInfoWindow : public CWindowObject | ||||||
| @@ -119,7 +119,7 @@ private: | |||||||
| 	std::vector<std::shared_ptr<CLabel>> labels; | 	std::vector<std::shared_ptr<CLabel>> labels; | ||||||
| 	std::vector<std::shared_ptr<CToggleButton>> toggles; | 	std::vector<std::shared_ptr<CToggleButton>> toggles; | ||||||
| public: | public: | ||||||
| 	BattleOptionsWindow(BattleInterface * owner); | 	BattleOptionsWindow(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	void bDefaultf(); //default button callback | 	void bDefaultf(); //default button callback | ||||||
| 	void bExitf(); //exit 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 | 	bool setAlterText; //if true, this hex has set alternative text in console and will clean it | ||||||
| public: | public: | ||||||
| 	ui32 myNumber; //number of hex in commonly used format | 	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) | 	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 | 	BattleInterface * myInterface; //interface that owns me | ||||||
|  |  | ||||||
| @@ -183,7 +181,7 @@ class StackQueue : public CIntObject | |||||||
| 	static const int QUEUE_SIZE = 10; | 	static const int QUEUE_SIZE = 10; | ||||||
| 	std::shared_ptr<CFilledTexture> background; | 	std::shared_ptr<CFilledTexture> background; | ||||||
| 	std::vector<std::shared_ptr<StackBox>> stackBoxes; | 	std::vector<std::shared_ptr<StackBox>> stackBoxes; | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	std::shared_ptr<CAnimation> icons; | 	std::shared_ptr<CAnimation> icons; | ||||||
| 	std::shared_ptr<CAnimation> stateIcons; | 	std::shared_ptr<CAnimation> stateIcons; | ||||||
| @@ -192,6 +190,6 @@ class StackQueue : public CIntObject | |||||||
| public: | public: | ||||||
| 	const bool embedded; | 	const bool embedded; | ||||||
|  |  | ||||||
| 	StackQueue(bool Embedded, BattleInterface * _owner); | 	StackQueue(bool Embedded, BattleInterface & owner); | ||||||
| 	void update(); | 	void update(); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -24,10 +24,10 @@ | |||||||
| #include "../../lib/battle/CObstacleInstance.h" | #include "../../lib/battle/CObstacleInstance.h" | ||||||
| #include "../../lib/ObstacleHandler.h" | #include "../../lib/ObstacleHandler.h" | ||||||
|  |  | ||||||
| BattleObstacleController::BattleObstacleController(BattleInterface * owner): | BattleObstacleController::BattleObstacleController(BattleInterface & owner): | ||||||
| 	owner(owner) | 	owner(owner) | ||||||
| { | { | ||||||
| 	auto obst = owner->curInt->cb->battleGetAllObstacles(); | 	auto obst = owner.curInt->cb->battleGetAllObstacles(); | ||||||
| 	for(auto & elem : obst) | 	for(auto & elem : obst) | ||||||
| 	{ | 	{ | ||||||
| 		if ( elem->obstacleType == CObstacleInstance::MOAT ) | 		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 | 		//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 | 		// -> if we know how to blit obstacle, let's blit the effect in the same place | ||||||
| 		Point whereTo = getObstaclePosition(first, *oi); | 		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 | 		//so when multiple obstacles are added, they show up one after another | ||||||
| 		owner->waitForAnims(); | 		owner.waitForAnims(); | ||||||
|  |  | ||||||
| 		obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin()); | 		obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin()); | ||||||
| 		loadObstacleImage(*spellObstacle); | 		loadObstacleImage(*spellObstacle); | ||||||
| @@ -117,7 +117,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr< | |||||||
| void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas, const Point & offset) | void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas, const Point & offset) | ||||||
| { | { | ||||||
| 	//Blit absolute obstacles | 	//Blit absolute obstacles | ||||||
| 	for(auto & oi : owner->curInt->cb->battleGetAllObstacles()) | 	for(auto & oi : owner.curInt->cb->battleGetAllObstacles()) | ||||||
| 	{ | 	{ | ||||||
| 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||||
| 		{ | 		{ | ||||||
| @@ -130,7 +130,7 @@ void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas, const Poin | |||||||
|  |  | ||||||
| void BattleObstacleController::collectRenderableObjects(BattleRenderer & renderer) | 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) | 		if (obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||||
| 			continue; | 			continue; | ||||||
| @@ -151,7 +151,7 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere | |||||||
|  |  | ||||||
| std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstacleInstance & oi) | 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; | 	std::shared_ptr<CAnimation> animation; | ||||||
|  |  | ||||||
| 	if (obstacleAnimations.count(oi.uniqueID) == 0) | 	if (obstacleAnimations.count(oi.uniqueID) == 0) | ||||||
| @@ -183,7 +183,7 @@ Point BattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> imag | |||||||
| { | { | ||||||
| 	int offset = obstacle.getAnimationYOffset(image->height()); | 	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; | 	r.y += 42 - image->height() + offset; | ||||||
|  |  | ||||||
| 	return r.topLeft(); | 	return r.topLeft(); | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ struct Point; | |||||||
| /// (with exception of moat, which is apparently handled by siege controller) | /// (with exception of moat, which is apparently handled by siege controller) | ||||||
| class BattleObstacleController | class BattleObstacleController | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	/// cached animations of all obstacles in current battle | 	/// cached animations of all obstacles in current battle | ||||||
| 	std::map<std::string, std::shared_ptr<CAnimation>> animationsCache; | 	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); | 	Point getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleObstacleController(BattleInterface * owner); | 	BattleObstacleController(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	/// call-in from network pack, add newly placed obstacles with any required animations | 	/// call-in from network pack, add newly placed obstacles with any required animations | ||||||
| 	void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & oi); | 	void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & oi); | ||||||
|   | |||||||
| @@ -146,16 +146,16 @@ void ProjectileRay::show(Canvas & canvas) | |||||||
| 	++step; | 	++step; | ||||||
| } | } | ||||||
|  |  | ||||||
| BattleProjectileController::BattleProjectileController(BattleInterface * owner): | BattleProjectileController::BattleProjectileController(BattleInterface & owner): | ||||||
| 	owner(owner) | 	owner(owner) | ||||||
| {} | {} | ||||||
|  |  | ||||||
| const CCreature * BattleProjectileController::getShooter(const CStack * stack) | const CCreature & BattleProjectileController::getShooter(const CStack * stack) const | ||||||
| { | { | ||||||
| 	const CCreature * creature = stack->getCreature(); | 	const CCreature * creature = stack->getCreature(); | ||||||
|  |  | ||||||
| 	if(creature->idNumber == CreatureID::ARROW_TOWERS) | 	if(creature->idNumber == CreatureID::ARROW_TOWERS) | ||||||
| 		creature = owner->siegeController->getTurretCreature(); | 		creature = owner.siegeController->getTurretCreature(); | ||||||
|  |  | ||||||
| 	if(creature->animation.missleFrameAngles.empty()) | 	if(creature->animation.missleFrameAngles.empty()) | ||||||
| 	{ | 	{ | ||||||
| @@ -163,17 +163,17 @@ const CCreature * BattleProjectileController::getShooter(const CStack * stack) | |||||||
| 		creature = CGI->creh->objects[CreatureID::ARCHER]; | 		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) | void BattleProjectileController::initStackProjectile(const CStack * stack) | ||||||
| @@ -181,8 +181,8 @@ void BattleProjectileController::initStackProjectile(const CStack * stack) | |||||||
| 	if (!stackUsesMissileProjectile(stack)) | 	if (!stackUsesMissileProjectile(stack)) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	const CCreature * creature = getShooter(stack); | 	const CCreature & creature = getShooter(stack); | ||||||
| 	projectilesCache[creature->animation.projectileImageName] = createProjectileImage(creature->animation.projectileImageName); | 	projectilesCache[creature.animation.projectileImageName] = createProjectileImage(creature.animation.projectileImageName); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::shared_ptr<CAnimation> BattleProjectileController::createProjectileImage(const std::string & path ) | 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) | std::shared_ptr<CAnimation> BattleProjectileController::getProjectileImage(const CStack * stack) | ||||||
| { | { | ||||||
| 	const CCreature * creature = getShooter(stack); | 	const CCreature & creature = getShooter(stack); | ||||||
| 	std::string imageName = creature->animation.projectileImageName; | 	std::string imageName = creature.animation.projectileImageName; | ||||||
|  |  | ||||||
| 	if (!projectilesCache.count(imageName)) | 	if (!projectilesCache.count(imageName)) | ||||||
| 		initStackProjectile(stack); | 		initStackProjectile(stack); | ||||||
| @@ -266,9 +266,9 @@ int BattleProjectileController::computeProjectileFlightTime( Point from, Point d | |||||||
|  |  | ||||||
| int BattleProjectileController::computeProjectileFrameID( Point from, Point dest, const CStack * stack) | 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); | 	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 | 	// 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) | 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; | 	std::shared_ptr<ProjectileBase> projectile; | ||||||
| 	if (stackUsesRayProjectile(shooter) && stackUsesMissileProjectile(shooter)) | 	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)) | 	if (stackUsesRayProjectile(shooter)) | ||||||
| @@ -327,7 +327,7 @@ void BattleProjectileController::createProjectile(const CStack * shooter, Point | |||||||
| 		auto rayProjectile = new ProjectileRay(); | 		auto rayProjectile = new ProjectileRay(); | ||||||
| 		projectile.reset(rayProjectile); | 		projectile.reset(rayProjectile); | ||||||
|  |  | ||||||
| 		rayProjectile->rayConfig = shooterInfo->animation.projectileRay; | 		rayProjectile->rayConfig = shooterInfo.animation.projectileRay; | ||||||
| 	} | 	} | ||||||
| 	else if (stackUsesMissileProjectile(shooter)) | 	else if (stackUsesMissileProjectile(shooter)) | ||||||
| 	{ | 	{ | ||||||
| @@ -335,7 +335,7 @@ void BattleProjectileController::createProjectile(const CStack * shooter, Point | |||||||
| 		projectile.reset(missileProjectile); | 		projectile.reset(missileProjectile); | ||||||
|  |  | ||||||
| 		missileProjectile->animation = getProjectileImage(shooter); | 		missileProjectile->animation = getProjectileImage(shooter); | ||||||
| 		missileProjectile->reverse  = !owner->stacksController->facingRight(shooter); | 		missileProjectile->reverse  = !owner.stacksController->facingRight(shooter); | ||||||
| 		missileProjectile->frameNum = computeProjectileFrameID(from, dest, shooter); | 		missileProjectile->frameNum = computeProjectileFrameID(from, dest, shooter); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -77,7 +77,7 @@ struct ProjectileRay : ProjectileBase | |||||||
| /// ... even though in H3 only 1 projectile can be on screen at any point of time | /// ... even though in H3 only 1 projectile can be on screen at any point of time | ||||||
| class BattleProjectileController | class BattleProjectileController | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	/// all projectiles loaded during current battle | 	/// all projectiles loaded during current battle | ||||||
| 	std::map<std::string, std::shared_ptr<CAnimation>> projectilesCache; | 	std::map<std::string, std::shared_ptr<CAnimation>> projectilesCache; | ||||||
| @@ -89,18 +89,18 @@ class BattleProjectileController | |||||||
| 	std::shared_ptr<CAnimation> createProjectileImage(const std::string & path ); | 	std::shared_ptr<CAnimation> createProjectileImage(const std::string & path ); | ||||||
| 	void initStackProjectile(const CStack * stack); | 	void initStackProjectile(const CStack * stack); | ||||||
|  |  | ||||||
| 	bool stackUsesRayProjectile(const CStack * stack); | 	bool stackUsesRayProjectile(const CStack * stack) const; | ||||||
| 	bool stackUsesMissileProjectile(const CStack * stack); | 	bool stackUsesMissileProjectile(const CStack * stack) const; | ||||||
|  |  | ||||||
| 	void showProjectile(Canvas & canvas, std::shared_ptr<ProjectileBase> projectile); | 	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 computeProjectileFrameID( Point from, Point dest, const CStack * stack); | ||||||
| 	int computeProjectileFlightTime( Point from, Point dest, double speed); | 	int computeProjectileFlightTime( Point from, Point dest, double speed); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleProjectileController(BattleInterface * owner); | 	BattleProjectileController(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	/// renders all currently active projectiles | 	/// renders all currently active projectiles | ||||||
| 	void showProjectiles(Canvas & canvas); | 	void showProjectiles(Canvas & canvas); | ||||||
|   | |||||||
| @@ -18,12 +18,12 @@ | |||||||
|  |  | ||||||
| void BattleRenderer::collectObjects() | void BattleRenderer::collectObjects() | ||||||
| { | { | ||||||
| 	owner->collectRenderableObjects(*this); | 	owner.collectRenderableObjects(*this); | ||||||
| 	owner->effectsController->collectRenderableObjects(*this); | 	owner.effectsController->collectRenderableObjects(*this); | ||||||
| 	owner->obstacleController->collectRenderableObjects(*this); | 	owner.obstacleController->collectRenderableObjects(*this); | ||||||
| 	owner->stacksController->collectRenderableObjects(*this); | 	owner.stacksController->collectRenderableObjects(*this); | ||||||
| 	if (owner->siegeController) | 	if (owner.siegeController) | ||||||
| 		owner->siegeController->collectRenderableObjects(*this); | 		owner.siegeController->collectRenderableObjects(*this); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleRenderer::sortObjects() | void BattleRenderer::sortObjects() | ||||||
| @@ -36,13 +36,7 @@ void BattleRenderer::sortObjects() | |||||||
| 		if ( object.tile == BattleHex::HEX_BEFORE_ALL ) | 		if ( object.tile == BattleHex::HEX_BEFORE_ALL ) | ||||||
| 			return -1; | 			return -1; | ||||||
|  |  | ||||||
| 		if ( object.tile == BattleHex::HEX_AFTER_ALL ) | 		assert( object.tile == BattleHex::HEX_AFTER_ALL || object.tile == BattleHex::INVALID); | ||||||
| 			return GameConstants::BFIELD_HEIGHT; |  | ||||||
|  |  | ||||||
| 		if ( object.tile == BattleHex::INVALID ) |  | ||||||
| 			return GameConstants::BFIELD_HEIGHT; |  | ||||||
|  |  | ||||||
| 		assert(0); |  | ||||||
| 		return GameConstants::BFIELD_HEIGHT; | 		return GameConstants::BFIELD_HEIGHT; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -59,14 +53,14 @@ void BattleRenderer::renderObjects(BattleRenderer::RendererPtr targetCanvas) | |||||||
| 		object.functor(targetCanvas); | 		object.functor(targetCanvas); | ||||||
| } | } | ||||||
|  |  | ||||||
| BattleRenderer::BattleRenderer(BattleInterface * owner): | BattleRenderer::BattleRenderer(BattleInterface & owner): | ||||||
| 	owner(owner) | 	owner(owner) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleRenderer::insert(EBattleFieldLayer layer, BattleHex tile, BattleRenderer::RenderFunctor functor) | 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) | void BattleRenderer::execute(BattleRenderer::RendererPtr targetCanvas) | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ public: | |||||||
| 	using RenderFunctor = std::function<void(RendererPtr)>; | 	using RenderFunctor = std::function<void(RendererPtr)>; | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	struct RenderableInstance | 	struct RenderableInstance | ||||||
| 	{ | 	{ | ||||||
| @@ -47,7 +47,7 @@ private: | |||||||
| 	void sortObjects(); | 	void sortObjects(); | ||||||
| 	void renderObjects(RendererPtr targetCanvas); | 	void renderObjects(RendererPtr targetCanvas); | ||||||
| public: | public: | ||||||
| 	BattleRenderer(BattleInterface * owner); | 	BattleRenderer(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	void insert(EBattleFieldLayer layer, BattleHex tile, RenderFunctor functor); | 	void insert(EBattleFieldLayer layer, BattleHex tile, RenderFunctor functor); | ||||||
| 	void execute(RendererPtr targetCanvas); | 	void execute(RendererPtr targetCanvas); | ||||||
|   | |||||||
| @@ -124,15 +124,15 @@ std::string BattleSiegeController::getBattleBackgroundName() const | |||||||
| bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what) const | bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what) const | ||||||
| { | { | ||||||
| 	//FIXME: use this instead of buildings test? | 	//FIXME: use this instead of buildings test? | ||||||
| 	//ui8 siegeLevel = owner->curInt->cb->battleGetSiegeLevel(); | 	//ui8 siegeLevel = owner.curInt->cb->battleGetSiegeLevel(); | ||||||
|  |  | ||||||
| 	switch (what) | 	switch (what) | ||||||
| 	{ | 	{ | ||||||
| 	case EWallVisual::MOAT:              return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER; | 	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::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::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::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::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER)) != EWallState::DESTROYED; | ||||||
| 	default:                             return true; | 	default:                             return true; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -163,11 +163,11 @@ BattleHex BattleSiegeController::getWallPiecePosition(EWallVisual::EWallVisual w | |||||||
| 	return wallsPositions[what]; | 	return wallsPositions[what]; | ||||||
| } | } | ||||||
|  |  | ||||||
| BattleSiegeController::BattleSiegeController(BattleInterface * owner, const CGTownInstance *siegeTown): | BattleSiegeController::BattleSiegeController(BattleInterface & owner, const CGTownInstance *siegeTown): | ||||||
| 	owner(owner), | 	owner(owner), | ||||||
| 	town(siegeTown) | 	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) | 	for (int g = 0; g < wallPieceImages.size(); ++g) | ||||||
| 	{ | 	{ | ||||||
| @@ -205,7 +205,7 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con | |||||||
|  |  | ||||||
| 	if (posID != 0) | 	if (posID != 0) | ||||||
| 	{ | 	{ | ||||||
| 		Point result = owner->pos.topLeft(); | 		Point result = owner.pos.topLeft(); | ||||||
| 		result.x += town->town->clientInfo.siegePositions[posID].x; | 		result.x += town->town->clientInfo.siegePositions[posID].x; | ||||||
| 		result.y += town->town->clientInfo.siegePositions[posID].y; | 		result.y += town->town->clientInfo.siegePositions[posID].y; | ||||||
| 		return result; | 		return result; | ||||||
| @@ -217,7 +217,7 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con | |||||||
|  |  | ||||||
| void BattleSiegeController::gateStateChanged(const EGateState state) | void BattleSiegeController::gateStateChanged(const EGateState state) | ||||||
| { | { | ||||||
| 	auto oldState = owner->curInt->cb->battleGetGateState(); | 	auto oldState = owner.curInt->cb->battleGetGateState(); | ||||||
| 	bool playSound = false; | 	bool playSound = false; | ||||||
| 	auto stateId = EWallState::NONE; | 	auto stateId = EWallState::NONE; | ||||||
| 	switch(state) | 	switch(state) | ||||||
| @@ -272,7 +272,7 @@ BattleHex BattleSiegeController::getTurretBattleHex(EWallVisual::EWallVisual wal | |||||||
|  |  | ||||||
| const CStack * BattleSiegeController::getTurretStack(EWallVisual::EWallVisual wallPiece) const | 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)) | 		if ( stack->initialPosition == getTurretBattleHex(wallPiece)) | ||||||
| 			return stack; | 			return stack; | ||||||
| @@ -298,14 +298,14 @@ void BattleSiegeController::collectRenderableObjects(BattleRenderer & renderer) | |||||||
| 			wallPiece == EWallVisual::UPPER_BATTLEMENT) | 			wallPiece == EWallVisual::UPPER_BATTLEMENT) | ||||||
| 		{ | 		{ | ||||||
| 			renderer.insert( EBattleFieldLayer::STACKS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererPtr canvas){ | 			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){ | 			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){ | 		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 | bool BattleSiegeController::isAttackableByCatapult(BattleHex hex) const | ||||||
| { | { | ||||||
| 	if (owner->tacticsMode) | 	if (owner.tacticsMode) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	auto wallPart = owner->curInt->cb->battleHexToWallPart(hex); | 	auto wallPart = owner.curInt->cb->battleHexToWallPart(hex); | ||||||
| 	if (!owner->curInt->cb->isWallPartPotentiallyAttackable(wallPart)) | 	if (!owner.curInt->cb->isWallPartPotentiallyAttackable(wallPart)) | ||||||
| 		return false; | 		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; | 	return state != EWallState::DESTROYED && state != EWallState::NONE; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -329,10 +329,10 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca) | |||||||
| { | { | ||||||
| 	if (ca.attacker != -1) | 	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) | 		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 | 	else | ||||||
| @@ -341,13 +341,13 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca) | |||||||
|  |  | ||||||
| 		//no attacker stack, assume spell-related (earthquake) - only hit animation | 		//no attacker stack, assume spell-related (earthquake) - only hit animation | ||||||
| 		for (auto attackInfo : ca.attackedParts) | 		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) | 	for (auto attackInfo : ca.attackedParts) | ||||||
| 	{ | 	{ | ||||||
| @@ -356,7 +356,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca) | |||||||
| 		if (wallId == EWallVisual::GATE) | 		if (wallId == EWallVisual::GATE) | ||||||
| 			continue; | 			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)); | 		wallPieceImages[wallId] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState)); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ namespace EWallVisual | |||||||
|  |  | ||||||
| class BattleSiegeController | class BattleSiegeController | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	/// besieged town | 	/// besieged town | ||||||
| 	const CGTownInstance *town; | 	const CGTownInstance *town; | ||||||
| @@ -90,7 +90,7 @@ class BattleSiegeController | |||||||
| 	const CStack * getTurretStack(EWallVisual::EWallVisual wallPiece) const; | 	const CStack * getTurretStack(EWallVisual::EWallVisual wallPiece) const; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleSiegeController(BattleInterface * owner, const CGTownInstance *siegeTown); | 	BattleSiegeController(BattleInterface & owner, const CGTownInstance *siegeTown); | ||||||
|  |  | ||||||
| 	/// call-ins from server | 	/// call-ins from server | ||||||
| 	void gateStateChanged(const EGateState state); | 	void gateStateChanged(const EGateState state); | ||||||
|   | |||||||
| @@ -60,7 +60,7 @@ static void onAnimationFinished(const CStack *stack, std::weak_ptr<CreatureAnima | |||||||
| 	animation->onAnimationReset += std::bind(&onAnimationFinished, stack, anim); | 	animation->onAnimationReset += std::bind(&onAnimationFinished, stack, anim); | ||||||
| } | } | ||||||
|  |  | ||||||
| BattleStacksController::BattleStacksController(BattleInterface * owner): | BattleStacksController::BattleStacksController(BattleInterface & owner): | ||||||
| 	owner(owner), | 	owner(owner), | ||||||
| 	activeStack(nullptr), | 	activeStack(nullptr), | ||||||
| 	mouseHoveredStack(nullptr), | 	mouseHoveredStack(nullptr), | ||||||
| @@ -86,7 +86,7 @@ BattleStacksController::BattleStacksController(BattleInterface * owner): | |||||||
| 	amountNegative->adjustPalette(&shifterNegative); | 	amountNegative->adjustPalette(&shifterNegative); | ||||||
| 	amountEffNeutral->adjustPalette(&shifterNeutral); | 	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) | 	for(const CStack * s : stacks) | ||||||
| 	{ | 	{ | ||||||
| 		stackAdded(s); | 		stackAdded(s); | ||||||
| @@ -118,7 +118,7 @@ BattleHex BattleStacksController::getStackCurrentPosition(const CStack * stack) | |||||||
|  |  | ||||||
| void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer) | void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer) | ||||||
| { | { | ||||||
| 	auto stacks = owner->curInt->cb->battleGetAllStacks(false); | 	auto stacks = owner.curInt->cb->battleGetAllStacks(false); | ||||||
|  |  | ||||||
| 	for (auto stack : stacks) | 	for (auto stack : stacks) | ||||||
| 	{ | 	{ | ||||||
| @@ -178,14 +178,14 @@ void BattleStacksController::stackAdded(const CStack * stack) | |||||||
|  |  | ||||||
| 	if(stack->initialPosition < 0) //turret | 	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] = AnimationControls::getAnimation(turretCreature); | ||||||
| 		stackAnimation[stack->ID]->pos.h = 235; | 		stackAnimation[stack->ID]->pos.h = 235; | ||||||
|  |  | ||||||
| 		coords = owner->siegeController->getTurretCreaturePosition(stack->initialPosition); | 		coords = owner.siegeController->getTurretCreaturePosition(stack->initialPosition); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @@ -209,7 +209,7 @@ void BattleStacksController::setActiveStack(const CStack *stack) | |||||||
| 	if (activeStack) // update UI | 	if (activeStack) // update UI | ||||||
| 		stackAnimation[activeStack->ID]->setBorderColor(AnimationControls::getGoldBorder()); | 		stackAnimation[activeStack->ID]->setBorderColor(AnimationControls::getGoldBorder()); | ||||||
|  |  | ||||||
| 	owner->controlPanel->blockUI(activeStack == nullptr); | 	owner.controlPanel->blockUI(activeStack == nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleStacksController::setHoveredStack(const CStack *stack) | void BattleStacksController::setHoveredStack(const CStack *stack) | ||||||
| @@ -239,9 +239,9 @@ void BattleStacksController::setHoveredStack(const CStack *stack) | |||||||
| bool BattleStacksController::stackNeedsAmountBox(const CStack * stack) | bool BattleStacksController::stackNeedsAmountBox(const CStack * stack) | ||||||
| { | { | ||||||
| 	BattleHex currentActionTarget; | 	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()) | 		if(!target.empty()) | ||||||
| 			currentActionTarget = target.at(0).hexValue; | 			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 | 	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; | 		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; | 		return true; | ||||||
|  |  | ||||||
| 	if(!stack->alive()) | 	if(!stack->alive()) | ||||||
| @@ -265,18 +265,18 @@ bool BattleStacksController::stackNeedsAmountBox(const CStack * stack) | |||||||
| 			return false; | 			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; | 				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; | 				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 false; | ||||||
| 	} | 	} | ||||||
| 	return true; | 	return true; | ||||||
| @@ -312,7 +312,7 @@ void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack * | |||||||
| 	const int reverseSideShift = stack->side == BattleSide::ATTACKER ? -1 : 1; | 	const int reverseSideShift = stack->side == BattleSide::ATTACKER ? -1 : 1; | ||||||
| 	const BattleHex nextPos = stack->getPosition() + sideShift; | 	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 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) + | 	int xAdd = (stack->side == BattleSide::ATTACKER ? 220 : 202) + | ||||||
| 			(stack->doubleWide() ? 44 : 0) * sideShift + | 			(stack->doubleWide() ? 44 : 0) * sideShift + | ||||||
| @@ -358,23 +358,23 @@ void BattleStacksController::updateBattleAnimations() | |||||||
| 	if (hadAnimations && currentAnimations.empty()) | 	if (hadAnimations && currentAnimations.empty()) | ||||||
| 	{ | 	{ | ||||||
| 		//anims ended | 		//anims ended | ||||||
| 		owner->controlPanel->blockUI(activeStack == nullptr); | 		owner.controlPanel->blockUI(activeStack == nullptr); | ||||||
| 		owner->animsAreDisplayed.setn(false); | 		owner.animsAreDisplayed.setn(false); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleStacksController::addNewAnim(CBattleAnimation *anim) | void BattleStacksController::addNewAnim(CBattleAnimation *anim) | ||||||
| { | { | ||||||
| 	currentAnimations.push_back(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 | void BattleStacksController::stackActivated(const CStack *stack) //TODO: check it all before game state is changed due to abilities | ||||||
| { | { | ||||||
| 	stackToActivate = stack; | 	stackToActivate = stack; | ||||||
| 	owner->waitForAnims(); | 	owner.waitForAnims(); | ||||||
| 	if (stackToActivate) //during waiting stack may have gotten activated through show | 	if (stackToActivate) //during waiting stack may have gotten activated through show | ||||||
| 		owner->activateStack(); | 		owner.activateStack(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BattleStacksController::stackRemoved(uint32_t stackID) | void BattleStacksController::stackRemoved(uint32_t stackID) | ||||||
| @@ -384,10 +384,10 @@ void BattleStacksController::stackRemoved(uint32_t stackID) | |||||||
| 		if (getActiveStack()->ID == stackID) | 		if (getActiveStack()->ID == stackID) | ||||||
| 		{ | 		{ | ||||||
| 			BattleAction *action = new BattleAction(); | 			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->actionType = EActionType::CANCEL; | ||||||
| 			action->stackNumber = getActiveStack()->ID; | 			action->stackNumber = getActiveStack()->ID; | ||||||
| 			owner->givenCommand.setn(action); | 			owner.givenCommand.setn(action); | ||||||
| 			setActiveStack(nullptr); | 			setActiveStack(nullptr); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -403,10 +403,10 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at | |||||||
|  |  | ||||||
| 		if(attackedInfo.rebirth) | 		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) | 	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) | void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance) | ||||||
| { | { | ||||||
| 	addNewAnim(new CMovementAnimation(owner, stack, destHex, 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 ) | 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 | 	//check if we should reverse stacks | ||||||
| 	//for some strange reason, it's not enough | 	//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) | 	for (const CStack *s : stacks) | ||||||
| 	{ | 	{ | ||||||
| @@ -469,16 +469,16 @@ void BattleStacksController::endAction(const BattleAction* action) | |||||||
|  |  | ||||||
| void BattleStacksController::startAction(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); | 	setHoveredStack(nullptr); | ||||||
|  |  | ||||||
| 	auto actionTarget = action->getTarget(owner->curInt->cb.get()); | 	auto actionTarget = action->getTarget(owner.curInt->cb.get()); | ||||||
|  |  | ||||||
| 	if(action->actionType == EActionType::WALK | 	if(action->actionType == EActionType::WALK | ||||||
| 		|| (action->actionType == EActionType::WALK_AND_ATTACK && actionTarget.at(0).hexValue != stack->getPosition())) | 		|| (action->actionType == EActionType::WALK_AND_ATTACK && actionTarget.at(0).hexValue != stack->getPosition())) | ||||||
| 	{ | 	{ | ||||||
| 		assert(stack); | 		assert(stack); | ||||||
| 		owner->moveStarted = true; | 		owner.moveStarted = true; | ||||||
| 		if (stackAnimation[action->stackNumber]->framesInGroup(CCreatureAnim::MOVE_START)) | 		if (stackAnimation[action->stackNumber]->framesInGroup(CCreatureAnim::MOVE_START)) | ||||||
| 			addNewAnim(new CMovementStartAnimation(owner, stack)); | 			addNewAnim(new CMovementStartAnimation(owner, stack)); | ||||||
|  |  | ||||||
| @@ -495,7 +495,7 @@ void BattleStacksController::activateStack() | |||||||
| 	if ( !stackToActivate) | 	if ( !stackToActivate) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	owner->trySetActivePlayer(stackToActivate->owner); | 	owner.trySetActivePlayer(stackToActivate->owner); | ||||||
|  |  | ||||||
| 	setActiveStack(stackToActivate); | 	setActiveStack(stackToActivate); | ||||||
| 	stackToActivate = nullptr; | 	stackToActivate = nullptr; | ||||||
| @@ -513,7 +513,7 @@ void BattleStacksController::activateStack() | |||||||
| 		if(randomSpellcaster) | 		if(randomSpellcaster) | ||||||
| 			creatureSpellToCast = -1; //spell will be set later on cast | 			creatureSpellToCast = -1; //spell will be set later on cast | ||||||
| 		else | 		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: what if creature can cast BOTH random genie spell and aimed spell? | ||||||
| 		//TODO: faerie dragon type spell should be selected by server | 		//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 | 	Point ret(-500, -500); //returned value | ||||||
| 	if(stack && stack->initialPosition < 0) //creatures in turrets | 	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 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 | 	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 | 	//returning | ||||||
| 	return ret + owner->pos.topLeft(); | 	return ret + owner.pos.topLeft(); | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ class IImage; | |||||||
| /// And any other effect applied to stacks | /// And any other effect applied to stacks | ||||||
| class BattleStacksController | class BattleStacksController | ||||||
| { | { | ||||||
| 	BattleInterface * owner; | 	BattleInterface & owner; | ||||||
|  |  | ||||||
| 	std::shared_ptr<IImage> amountNormal; | 	std::shared_ptr<IImage> amountNormal; | ||||||
| 	std::shared_ptr<IImage> amountNegative; | 	std::shared_ptr<IImage> amountNegative; | ||||||
| @@ -78,7 +78,7 @@ class BattleStacksController | |||||||
| 	std::shared_ptr<IImage> getStackAmountBox(const CStack * stack); | 	std::shared_ptr<IImage> getStackAmountBox(const CStack * stack); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	BattleStacksController(BattleInterface * owner); | 	BattleStacksController(BattleInterface & owner); | ||||||
|  |  | ||||||
| 	bool shouldRotate(const CStack * stack, const BattleHex & oldPos, const BattleHex & nextHex) const; | 	bool shouldRotate(const CStack * stack, const BattleHex & oldPos, const BattleHex & nextHex) const; | ||||||
| 	bool facingRight(const CStack * stack) const; | 	bool facingRight(const CStack * stack) const; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user