Hooks
static bool BeforeCvHomelandAI_GetBestUnitToReachTarget(CvHomelandAI* self, CvPlot* pTarget, int iMaxTurns, bool& result);static void AfterCvHomelandAI_GetBestUnitToReachTarget(CvHomelandAI* self, CvPlot* pTarget, int iMaxTurns, bool& result);static bool ReplaceCvHomelandAI_GetBestUnitToReachTarget(bool (*original)(CvHomelandAI*, CvPlot*, int), CvHomelandAI* self, CvPlot* pTarget, int iMaxTurns);CivRegisterBefore<CivHooks::CvHomelandAI_GetBestUnitToReachTarget>(host, &BeforeCvHomelandAI_GetBestUnitToReachTarget);CivRegisterAfter<CivHooks::CvHomelandAI_GetBestUnitToReachTarget>(host, &AfterCvHomelandAI_GetBestUnitToReachTarget);CivRegisterReplace<CivHooks::CvHomelandAI_GetBestUnitToReachTarget>(host, &ReplaceCvHomelandAI_GetBestUnitToReachTarget);
Code
5732/// Compute the best unit to reach a target in the current normal and high priority move list5733bool CvHomelandAI::GetBestUnitToReachTarget(CvPlot* pTarget, int iMaxTurns)5734{5735 AI_PERF_FORMAT("Homeland-GetBest-perf.csv", ("GetBestUnitToReachTarget, %d, %d, Turn %03d, %s", pTarget->getX(), pTarget->getY(), GC.getGame().getElapsedGameTurns(), m_pPlayer->getCivilizationShortDescription()) );57365737 UnitHandle pLoopUnit;5738 MoveUnitsArray::iterator it;57395740 // Get the raw distance for all units5741 int iTargetX = pTarget->getX();5742 int iTargetY = pTarget->getY();5743 5744 // Normal priority units5745 for(it = m_CurrentMoveUnits.begin(); it != m_CurrentMoveUnits.end(); ++it)5746 {5747 pLoopUnit = m_pPlayer->getUnit(it->GetID());5748 if(pLoopUnit)5749 {5750 // Make sure domain matches5751 if(pLoopUnit->getDomainType() == DOMAIN_SEA && !pTarget->isWater() ||5752 pLoopUnit->getDomainType() == DOMAIN_LAND && pTarget->isWater())5753 {5754 it->SetMovesToTarget(MAX_INT);5755 continue;5756 }57575758 // Make sure we can move into the destination. The path finder will do a similar check near the beginning, but it is best to get this out of the way before then5759 if(!pLoopUnit->canMoveInto(*pTarget, CvUnit::MOVEFLAG_DESTINATION | CvUnit::MOVEFLAG_PRETEND_CORRECT_EMBARK_STATE))5760 {5761 it->SetMovesToTarget(MAX_INT);5762 continue;5763 }57645765 int iPlotDistance = plotDistance(pLoopUnit->getX(), pLoopUnit->getY(), iTargetX, iTargetY);5766 it->SetMovesToTarget(iPlotDistance);5767 }5768 }57695770 // High priority units5771 for(it = m_CurrentMoveHighPriorityUnits.begin(); it != m_CurrentMoveHighPriorityUnits.end(); ++it)5772 {5773 pLoopUnit = m_pPlayer->getUnit(it->GetID());5774 if(pLoopUnit)5775 {5776 // Make sure domain matches5777 if(pLoopUnit->getDomainType() == DOMAIN_SEA && !pTarget->isWater() ||5778 pLoopUnit->getDomainType() == DOMAIN_LAND && pTarget->isWater())5779 {5780 it->SetMovesToTarget(MAX_INT);5781 continue;5782 }57835784 // Make sure we can move into the destination. The path finder will do a similar check near the beginning, but it is best to get this out of the way before then5785 if(!pLoopUnit->canMoveInto(*pTarget, CvUnit::MOVEFLAG_DESTINATION | CvUnit::MOVEFLAG_PRETEND_CORRECT_EMBARK_STATE))5786 {5787 it->SetMovesToTarget(MAX_INT);5788 continue;5789 }57905791 int iPlotDistance = plotDistance(pLoopUnit->getX(), pLoopUnit->getY(), iTargetX, iTargetY);5792 it->SetMovesToTarget(iPlotDistance);5793 }5794 }57955796 // Sort by raw distance5797 std::stable_sort(m_CurrentMoveUnits.begin(), m_CurrentMoveUnits.end());5798 std::stable_sort(m_CurrentMoveHighPriorityUnits.begin(), m_CurrentMoveHighPriorityUnits.end());57995800 // Find the one with the best true moves distance5801 GetClosestUnitByTurnsToTarget(m_CurrentMoveUnits, pTarget, iMaxTurns, &m_CurrentBestMoveUnit, &m_iCurrentBestMoveUnitTurns);5802 GetClosestUnitByTurnsToTarget(m_CurrentMoveHighPriorityUnits, pTarget, iMaxTurns, &m_CurrentBestMoveHighPriorityUnit, &m_iCurrentBestMoveHighPriorityUnitTurns);58035804 return m_CurrentBestMoveHighPriorityUnit != NULL || m_CurrentBestMoveUnit != NULL;5805}