Bazaar developer reference

CvTacticalAI::FindClosestUnit(CvPlot *, int, bool, bool, int, bool, bool, bool, CvPlot *)

Defined in
CvTacticalAI.cpp, line 9310
Class
CvTacticalAI
Hook name
CivHooks::CvTacticalAI_FindClosestUnit

Hooks

static bool BeforeCvTacticalAI_FindClosestUnit(CvTacticalAI* self, CvPlot* pTarget, int iNumTurnsAway, bool bMustHaveHalfHP, bool bMustBeRangedUnit, int iRangeRequired, bool bNeedsIgnoreLOS, bool bMustBeMeleeUnit, bool bIgnoreUnits, CvPlot* pRangedAttackTarget, bool& result);static void AfterCvTacticalAI_FindClosestUnit(CvTacticalAI* self, CvPlot* pTarget, int iNumTurnsAway, bool bMustHaveHalfHP, bool bMustBeRangedUnit, int iRangeRequired, bool bNeedsIgnoreLOS, bool bMustBeMeleeUnit, bool bIgnoreUnits, CvPlot* pRangedAttackTarget, bool& result);static bool ReplaceCvTacticalAI_FindClosestUnit(bool (*original)(CvTacticalAI*, CvPlot*, int, bool, bool, int, bool, bool, bool, CvPlot*), CvTacticalAI* self, CvPlot* pTarget, int iNumTurnsAway, bool bMustHaveHalfHP, bool bMustBeRangedUnit, int iRangeRequired, bool bNeedsIgnoreLOS, bool bMustBeMeleeUnit, bool bIgnoreUnits, CvPlot* pRangedAttackTarget);CivRegisterBefore<CivHooks::CvTacticalAI_FindClosestUnit>(host, &BeforeCvTacticalAI_FindClosestUnit);CivRegisterAfter<CivHooks::CvTacticalAI_FindClosestUnit>(host, &AfterCvTacticalAI_FindClosestUnit);CivRegisterReplace<CivHooks::CvTacticalAI_FindClosestUnit>(host, &ReplaceCvTacticalAI_FindClosestUnit);

Code

9309/// Fills m_CurrentMoveUnits with all units within X turns of a target (returns TRUE if 1 or more found)9310bool CvTacticalAI::FindClosestUnit(CvPlot* pTarget, int iNumTurnsAway, bool bMustHaveHalfHP, bool bMustBeRangedUnit, int iRangeRequired, bool bNeedsIgnoreLOS, bool bMustBeMeleeUnit, bool bIgnoreUnits, CvPlot* pRangedAttackTarget)9311{9312	list<int>::iterator it;9313	UnitHandle pLoopUnit;93149315	bool rtnValue = false;9316	m_CurrentMoveUnits.clear();93179318	// Loop through all units available to tactical AI this turn9319	for(it = m_CurrentTurnUnits.begin(); it != m_CurrentTurnUnits.end(); it++)9320	{9321		pLoopUnit = m_pPlayer->getUnit(*it);9322		if(pLoopUnit)9323		{9324			bool bValidUnit = true;93259326			// don't use non-combat units (but consider embarked for now)9327			if(pLoopUnit->getUnitInfo().GetCombat() == 0)9328			{9329				bValidUnit = false;9330			}93319332#if defined(MOD_UNITS_MAX_HP)9333			else if (bMustHaveHalfHP && (pLoopUnit->getDamage() * 2 > pLoopUnit->GetMaxHitPoints()))9334#else9335			else if (bMustHaveHalfHP && (pLoopUnit->getDamage() * 2 > GC.getMAX_HIT_POINTS()))9336#endif9337			{9338				bValidUnit = false;9339			}93409341			else if(bMustBeRangedUnit && ((pTarget->isWater() && pLoopUnit->getDomainType() == DOMAIN_LAND) ||9342			                              (!pTarget->isWater() && !pTarget->isCity() && pLoopUnit->getDomainType() == DOMAIN_SEA)))9343			{9344				bValidUnit = false;9345			}93469347			else if(bMustBeRangedUnit && !pLoopUnit->IsCanAttackRanged())9348			{9349				bValidUnit = false;9350			}93519352			else if(bMustBeRangedUnit && pLoopUnit->GetRange() < iRangeRequired)9353			{9354				bValidUnit = false;9355			}93569357			else if(bMustBeRangedUnit && !pLoopUnit->canEverRangeStrikeAt(pRangedAttackTarget->getX(), pRangedAttackTarget->getY()))9358			{9359				bValidUnit = false;9360			}93619362			else if(bMustBeRangedUnit && pLoopUnit->isOutOfAttacks())9363			{9364				bValidUnit = false;9365			}93669367			else if(pRangedAttackTarget != NULL && bMustBeRangedUnit && !IsExpectedToDamageWithRangedAttack(pLoopUnit, pRangedAttackTarget))9368			{9369				bValidUnit = false;9370			}93719372			else if(bNeedsIgnoreLOS && !pLoopUnit->IsRangeAttackIgnoreLOS())9373			{9374				bValidUnit = false;9375			}93769377			else if(bMustBeMeleeUnit && pLoopUnit->IsCanAttackRanged())9378			{9379				bValidUnit = false;9380			}93819382			int iDistance = plotDistance(pLoopUnit->getX(), pLoopUnit->getY(), pTarget->getX(), pTarget->getY());9383			if(iNumTurnsAway == 0 && iDistance > (m_iRecruitRange / 2) || iNumTurnsAway == 1 && iDistance > m_iRecruitRange)9384			{9385				bValidUnit = false;9386			}93879388			if(bValidUnit)9389			{9390				int iTurns = TurnsToReachTarget(pLoopUnit, pTarget, false /*bReusePaths*/, bIgnoreUnits, (iNumTurnsAway==0));9391				if(iTurns <= iNumTurnsAway)9392				{9393					CvTacticalUnit unit;9394					unit.SetID(pLoopUnit->GetID());9395#if defined(MOD_AI_SMART_V3)9396					// Simple trick to sort also by plot distance if is the same turn.9397					int plDistance = plotDistance(pLoopUnit->getX(), pLoopUnit->getY(), pTarget->getX(), pTarget->getY());9398					int iAttachStrength = MOD_AI_SMART_V3 ? (1000 - (iTurns * 20)) - plDistance : 1000-iTurns;9399					unit.SetAttackStrength(iAttachStrength);9400					unit.SetHealthPercent(10,10);9401					unit.SetMovesToTarget(plDistance);9402#else9403					unit.SetAttackStrength(1000-iTurns);9404					unit.SetHealthPercent(10,10);9405					unit.SetMovesToTarget(plotDistance(pLoopUnit->getX(), pLoopUnit->getY(), pTarget->getX(), pTarget->getY()));9406#endif9407					m_CurrentMoveUnits.push_back(unit);9408					rtnValue = true;9409				}9410			}9411		}9412	}94139414	// Now sort them by turns to reach9415	std::stable_sort(m_CurrentMoveUnits.begin(), m_CurrentMoveUnits.end());94169417	return rtnValue;9418}

Calls

Called by