Hooks
static bool BeforeCvHomelandAI_GetClosestUnitByTurnsToTarget(CvHomelandAI* self, FStaticVector<CvHomelandUnit, 64, true, 297> & kMoveUnits, CvPlot * pTarget, int iMaxTurns, CvUnit ** ppClosestUnit, int * piClosestTurns, bool& result);static void AfterCvHomelandAI_GetClosestUnitByTurnsToTarget(CvHomelandAI* self, FStaticVector<CvHomelandUnit, 64, true, 297> & kMoveUnits, CvPlot * pTarget, int iMaxTurns, CvUnit ** ppClosestUnit, int * piClosestTurns, bool& result);static bool ReplaceCvHomelandAI_GetClosestUnitByTurnsToTarget(bool (*original)(CvHomelandAI*, FStaticVector<CvHomelandUnit, 64, true, 297> &, CvPlot *, int, CvUnit **, int *), CvHomelandAI* self, FStaticVector<CvHomelandUnit, 64, true, 297> & kMoveUnits, CvPlot * pTarget, int iMaxTurns, CvUnit ** ppClosestUnit, int * piClosestTurns);CivRegisterBefore<CivHooks::CvHomelandAI_GetClosestUnitByTurnsToTarget>(host, &BeforeCvHomelandAI_GetClosestUnitByTurnsToTarget);CivRegisterAfter<CivHooks::CvHomelandAI_GetClosestUnitByTurnsToTarget>(host, &AfterCvHomelandAI_GetClosestUnitByTurnsToTarget);CivRegisterReplace<CivHooks::CvHomelandAI_GetClosestUnitByTurnsToTarget>(host, &ReplaceCvHomelandAI_GetClosestUnitByTurnsToTarget);
Code
5669/// Get the closest 5670bool CvHomelandAI::GetClosestUnitByTurnsToTarget(CvHomelandAI::MoveUnitsArray &kMoveUnits, CvPlot* pTarget, int iMaxTurns, CvUnit** ppClosestUnit, int* piClosestTurns)5671{5672 CvUnit* pBestUnit = NULL;5673 int iMinTurns = MAX_INT;5674 MoveUnitsArray::iterator it;56755676 int iFailedPaths = 0;5677 // If we see this many failed pathing attempts, we assume no unit can get to the target5678 const int MAX_FAILED_PATHS = 2;5679 // If the last failed pathing attempt was this far (raw distance) from the target, we assume no one can reach the target, even if we have not reached MAX_FAILED_PATHS5680 const int EARLY_OUT_FAILED_PATH_DISTANCE = 12;56815682 // Now go through and figure out the actual number of turns, and as a result, even if it can get there at all.5683 // We will try and do as few as possible by stopping if we find a unit that can make it in one turn.5684 for(it = kMoveUnits.begin(); it != kMoveUnits.end(); ++it)5685 {5686 UnitHandle pLoopUnit = m_pPlayer->getUnit(it->GetID());5687 if (pLoopUnit)5688 {5689 int iDistance = it->GetMovesToTarget(); // Raw distance5690 if (iDistance == MAX_INT)5691 continue;5692 int iMoves = TurnsToReachTarget(pLoopUnit.pointer(), pTarget);5693 it->SetMovesToTarget(iMoves);5694 // Did we make it at all?5695 if (iMoves != MAX_INT)5696 {5697 // Reasonably close?5698 if (iDistance == 0 || (iMoves <= iDistance && iMoves <= iMaxTurns && iMoves < iMinTurns))5699 {5700 pBestUnit = pLoopUnit.pointer();5701 iMinTurns = iMoves;5702 break;5703 }57045705 if (iMoves < iMinTurns)5706 {5707 pBestUnit = pLoopUnit.pointer();5708 iMinTurns = iMoves;5709 }57105711 // Were we far away? If so, this is probably the best we are going to do5712 if (iDistance >= GC.getAI_HOMELAND_ESTIMATE_TURNS_DISTANCE())5713 break;5714 }5715 else5716 {5717 ++iFailedPaths;5718 if (iFailedPaths >= MAX_FAILED_PATHS)5719 break;5720 if (iDistance >= EARLY_OUT_FAILED_PATH_DISTANCE)5721 break;5722 }5723 }5724 }57255726 *ppClosestUnit = pBestUnit;5727 *piClosestTurns = iMinTurns;5728 return pBestUnit != NULL;5729}