Hooks
static bool BeforeTurnsToReachTarget(UnitHandle pUnit, CvPlot* pTarget, bool bReusePaths, bool bIgnoreUnits, bool bIgnoreStacking, int& result);static void AfterTurnsToReachTarget(UnitHandle pUnit, CvPlot* pTarget, bool bReusePaths, bool bIgnoreUnits, bool bIgnoreStacking, int& result);static int ReplaceTurnsToReachTarget(int (*original)(UnitHandle, CvPlot*, bool, bool, bool), UnitHandle pUnit, CvPlot* pTarget, bool bReusePaths, bool bIgnoreUnits, bool bIgnoreStacking);CivRegisterBefore<CivHooks::TurnsToReachTarget>(host, &BeforeTurnsToReachTarget);CivRegisterAfter<CivHooks::TurnsToReachTarget>(host, &AfterTurnsToReachTarget);CivRegisterReplace<CivHooks::TurnsToReachTarget>(host, &ReplaceTurnsToReachTarget);
Code
3826/// How many turns will it take a unit to get to a target plot (returns MAX_INT if can't reach at all; returns 0 if makes it in 1 turn and has movement left)3827// Should call it with bIgnoreStacking true if want foolproof way to see if can make it in 0 turns (since that way doesn't open3828// open the 2nd layer of the pathfinder)3829int TurnsToReachTarget(UnitHandle pUnit, CvPlot* pTarget, bool bReusePaths, bool bIgnoreUnits, bool bIgnoreStacking)3830{3831 int rtnValue = MAX_INT;3832 CvAStarNode* pNode = NULL;38333834 if(pTarget == pUnit->plot())3835 {3836 return 0;3837 }38383839 if(pUnit)3840 {3841#ifdef PATH_FINDER_LOGGING3842 CvString strBaseString;3843 cvStopWatch kTimer(strBaseString, "Pathfinder.csv");3844#endif38453846 if(bIgnoreUnits)3847 {3848 GC.getIgnoreUnitsPathFinder().SetData(pUnit.pointer());3849 if (GC.getIgnoreUnitsPathFinder().GeneratePath(pUnit->getX(), pUnit->getY(), pTarget->getX(), pTarget->getY(), 0, bReusePaths))3850 {3851 pNode = GC.getIgnoreUnitsPathFinder().GetLastNode();3852 }3853 }3854 else3855 {3856 int iFlags = MOVE_UNITS_IGNORE_DANGER;3857 if(bIgnoreStacking)3858 {3859 iFlags |= MOVE_IGNORE_STACKING;3860 }38613862 CvAssertMsg(pTarget != NULL, "Passed in a NULL destination to GeneratePath");3863 if(pTarget == NULL)3864 {3865 return false;3866 }38673868 bool bSuccess;38693870 GC.GetTacticalAnalysisMapFinder().SetData(pUnit.pointer());3871 bSuccess = GC.GetTacticalAnalysisMapFinder().GeneratePath(pUnit->getX(), pUnit->getY(), pTarget->getX(), pTarget->getY(), iFlags, bReusePaths);3872 if(bSuccess)3873 {3874 pNode = GC.GetTacticalAnalysisMapFinder().GetLastNode();3875 }3876 }38773878 if(pNode)3879 {3880 rtnValue = pNode->m_iData2;3881 if(rtnValue == 1)3882 {3883 if(pNode->m_iData1 > 0)3884 {3885 rtnValue = 0;3886 }3887 }3888 }38893890#ifdef PATH_FINDER_LOGGING3891 // NOTE: because I'm creating the string after the cvStopWatch, the time it takes to create the string will be in the timer.3892 strBaseString.Format("TurnsToReachTarget, Turn %03d, Player: %d, Unit: %d, From X: %d, Y: %d, To X: %d, Y: %d, reuse=%d, ignoreUnits=%d, ignoreStacking=%d, turns=%d", GC.getGame().getElapsedGameTurns(), (int)pUnit->getOwner(), pUnit->GetID(), pUnit->getX(), pUnit->getY(), pTarget->getX(), pTarget->getY(), bReusePaths?1:0, bIgnoreUnits?1:0, bIgnoreStacking?1:0, rtnValue);3893 kTimer.SetText(strBaseString);3894#endif3895 }38963897 return rtnValue;3898}