Bazaar developer reference

CvTacticalAI::ExecuteFormationMoves(CvArmyAI *, CvPlot *)

Defined in
CvTacticalAI.cpp, line 5188
Class
CvTacticalAI
Hook name
CivHooks::CvTacticalAI_ExecuteFormationMoves

Hooks

static bool BeforeCvTacticalAI_ExecuteFormationMoves(CvTacticalAI* self, CvArmyAI* pArmy, CvPlot * pClosestCurrentCOMonPath);static void AfterCvTacticalAI_ExecuteFormationMoves(CvTacticalAI* self, CvArmyAI* pArmy, CvPlot * pClosestCurrentCOMonPath);static void ReplaceCvTacticalAI_ExecuteFormationMoves(void (*original)(CvTacticalAI*, CvArmyAI*, CvPlot *), CvTacticalAI* self, CvArmyAI* pArmy, CvPlot * pClosestCurrentCOMonPath);CivRegisterBefore<CivHooks::CvTacticalAI_ExecuteFormationMoves>(host, &BeforeCvTacticalAI_ExecuteFormationMoves);CivRegisterAfter<CivHooks::CvTacticalAI_ExecuteFormationMoves>(host, &AfterCvTacticalAI_ExecuteFormationMoves);CivRegisterReplace<CivHooks::CvTacticalAI_ExecuteFormationMoves>(host, &ReplaceCvTacticalAI_ExecuteFormationMoves);

Code

5187/// Complete moves for all units requested through calls to MoveWithFormation()5188void CvTacticalAI::ExecuteFormationMoves(CvArmyAI* pArmy, CvPlot *pClosestCurrentCOMonPath)5189{5190	CvPlot* pTarget;5191	UnitHandle pUnit;5192	AITacticalTargetType eTargetType;5193	CvPlot* pLoopPlot;5194	FStaticVector<CvOperationUnit, SAFE_ESTIMATE_NUM_MULTIUNITFORMATION_ENTRIES, true, c_eCiv5GameplayDLL, 0>::iterator it;51955196	if(m_OperationUnits.size() == 0)5197	{5198		return;5199	}52005201	pTarget = pArmy->Plot();52025203	int iMeleeUnits = 0;5204	int iRangedUnits = 0;5205	for(it = m_OperationUnits.begin(); it != m_OperationUnits.end(); it++)5206	{5207		CvUnit *pOpUnit = m_pPlayer->getUnit(it->GetUnitID());5208		if (pOpUnit->IsCanAttackRanged())5209		{5210			iRangedUnits++;5211		}5212		else5213		{5214			iMeleeUnits++;5215		}5216	}52175218	// See if we have enough places to put everyone5219	if(!ScoreFormationPlots(pArmy, pTarget, pClosestCurrentCOMonPath, iMeleeUnits + iRangedUnits))5220	{5221		if(GC.getLogging() && GC.getAILogging())5222		{5223			CvString strLogString;5224			strLogString.Format("Operation aborting. Army ID: %d. Not enough spaces to deploy along formation's path", pArmy->GetID());5225			LogTacticalMessage(strLogString);5226		}5227		m_pPlayer->getAIOperation(pArmy->GetOperationID())->SetToAbort(AI_ABORT_NO_ROOM_DEPLOY);5228	}52295230	// Compute the moves to get the best deployment5231	else5232	{5233		std::stable_sort(m_TempTargets.begin(), m_TempTargets.end());52345235		// First loop for melee units who should be out front5236		int iMeleeUnitsToPlace = iMeleeUnits;5237		bool bDone = false;5238		for(unsigned int iI = 0; iI < m_TempTargets.size() && !bDone; iI++)5239		{5240			eTargetType = m_TempTargets[iI].GetTargetType();52415242			pLoopPlot = GC.getMap().plot(m_TempTargets[iI].GetTargetX(), m_TempTargets[iI].GetTargetY());52435244			// Don't use if there's already someone here5245			if (!pLoopPlot->getBestDefender(NO_PLAYER))5246			{5247				if(FindClosestOperationUnit(pLoopPlot, false /*bSafeForRanged*/, false /*bMustBeRangedUnit*/))5248				{5249					UnitHandle pInnerUnit = m_pPlayer->getUnit(m_CurrentMoveUnits[0].GetID());5250					bool bMoveWasSafe;5251					MoveToUsingSafeEmbark(pInnerUnit, pLoopPlot, bMoveWasSafe);5252					pInnerUnit->finishMoves();5253					if(GC.getLogging() && GC.getAILogging())5254					{5255						CvString strMsg;5256						strMsg.Format("Deploying melee unit, %s, To X: %d, To Y: %d, At X: %d, At Y: %d", pInnerUnit->getName().GetCString(), pLoopPlot->getX(), pLoopPlot->getY(), pInnerUnit->getX(), pInnerUnit->getY());5257						LogTacticalMessage(strMsg);5258					}5259					iMeleeUnitsToPlace--;5260				}5261			}5262			if (iMeleeUnitsToPlace == 0)5263			{5264				bDone = true;5265			}5266		}52675268		// Log if someone in army didn't get a move assigned5269		if (iMeleeUnitsToPlace > 0)5270		{5271			if(GC.getLogging() && GC.getAILogging())5272			{5273				CvString strMsg;5274				strMsg.Format("No army deployment move for %d melee units", iMeleeUnitsToPlace);5275				LogTacticalMessage(strMsg);5276			}5277		}52785279		// Second loop for ranged units5280		int iRangedUnitsToPlace = iRangedUnits;5281		bDone = false;5282		for(unsigned int iI = 0; iI < m_TempTargets.size() && !bDone; iI++)5283		{5284			eTargetType = m_TempTargets[iI].GetTargetType();52855286			pLoopPlot = GC.getMap().plot(m_TempTargets[iI].GetTargetX(), m_TempTargets[iI].GetTargetY());5287			if (eTargetType == AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT)5288			{5289				// Don't use if there's already someone here5290				if (!pLoopPlot->getBestDefender(NO_PLAYER))5291				{5292					if(FindClosestOperationUnit(pLoopPlot, true /*bSafeForRanged*/, true /*bMustBeRangedUnit*/))5293					{5294						UnitHandle pInnerUnit = m_pPlayer->getUnit(m_CurrentMoveUnits[0].GetID());5295						bool bMoveWasSafe;5296						MoveToUsingSafeEmbark(pInnerUnit, pLoopPlot, bMoveWasSafe);5297						pInnerUnit->finishMoves();5298						if(GC.getLogging() && GC.getAILogging())5299						{5300							CvString strMsg;5301							strMsg.Format("Deploying ranged unit, %s, To X: %d, To Y: %d, At X: %d, At Y: %d", pInnerUnit->getName().GetCString(), pLoopPlot->getX(), pLoopPlot->getY(), pInnerUnit->getX(), pInnerUnit->getY());5302							LogTacticalMessage(strMsg);5303						}5304						iRangedUnitsToPlace--;5305					}5306				}5307			}5308			if (iRangedUnitsToPlace == 0)5309			{5310				bDone = true;5311			}5312		}53135314		// Third loop for ranged units we couldn't put in an ideal spot5315		for(unsigned int iI = 0; iI < m_TempTargets.size() && !bDone; iI++)5316		{5317			eTargetType = m_TempTargets[iI].GetTargetType();53185319			pLoopPlot = GC.getMap().plot(m_TempTargets[iI].GetTargetX(), m_TempTargets[iI].GetTargetY());53205321			// Don't use if there's already someone here5322			if (!pLoopPlot->getBestDefender(NO_PLAYER))5323			{5324				if(FindClosestOperationUnit(pLoopPlot, true /*bSafeForRanged*/, true /*bMustBeRangedUnit*/))5325				{5326					UnitHandle pInnerUnit = m_pPlayer->getUnit(m_CurrentMoveUnits[0].GetID());5327					bool bMoveWasSafe;5328					MoveToUsingSafeEmbark(pInnerUnit, pLoopPlot, bMoveWasSafe);5329					pInnerUnit->finishMoves();5330					if(GC.getLogging() && GC.getAILogging())5331					{5332						CvString strMsg;5333						strMsg.Format("Deploying ranged unit (Pass 2), %s, To X: %d, To Y: %d, At X: %d, At Y: %d", pInnerUnit->getName().GetCString(), pLoopPlot->getX(), pLoopPlot->getY(), pInnerUnit->getX(), pInnerUnit->getY());5334						LogTacticalMessage(strMsg);5335					}5336					iRangedUnitsToPlace--;5337				}5338			}5339			if (iRangedUnitsToPlace == 0)5340			{5341				bDone = true;5342			}5343		}53445345		// Log if someone in army didn't get a move assigned5346		if (iRangedUnitsToPlace > 0)5347		{5348			if(GC.getLogging() && GC.getAILogging())5349			{5350				CvString strMsg;5351				strMsg.Format("No army deployment move for %d ranged units", iRangedUnitsToPlace);5352				LogTacticalMessage(strMsg);5353			}5354		}5355	}5356}

Calls

Called by