Code
2993/// Moves units to the hex with the lowest danger2994void CvHomelandAI::ExecuteMovesToSafestPlot()2995{2996 int iDanger;29972998 for(unsigned int iI = 0; iI < m_CurrentMoveUnits.size(); iI++)2999 {3000 WeightedPlotVector aBestPlotList;3001 aBestPlotList.reserve(100);30023003 UnitHandle pUnit = m_pPlayer->getUnit(m_CurrentMoveUnits[iI].GetID());3004 if(pUnit)3005 {3006 CvPlot* pBestPlot = NULL;30073008 int iRange = pUnit->getUnitInfo().GetMoves();30093010 // For each plot within movement range of the fleeing unit3011 for(int iX = -iRange; iX <= iRange; iX++)3012 {3013 for(int iY = -iRange; iY <= iRange; iY++)3014 {3015 CvPlot* pPlot = GC.getMap().plot(pUnit->getX() + iX, pUnit->getY() + iY);3016 if(pPlot == NULL)3017 {3018 continue;3019 }30203021 if (plotDistance(pPlot->getX(), pPlot->getY(), pUnit->getX(), pUnit->getY()) > iRange)3022 {3023 continue;3024 }30253026 // prefer being in a city with the lowest danger value3027 // prefer being in a plot with no danger value3028 // prefer being under a unit with the lowest danger value3029 // prefer being in your own territory with the lowest danger value3030 // prefer the lowest danger value30313032 iDanger = m_pPlayer->GetPlotDanger(*pPlot);3033 bool bIsZeroDanger = (iDanger <= 0);3034 bool bIsInCity = pPlot->isFriendlyCity(*pUnit, false);3035 bool bIsInCover = (pPlot->getNumDefenders(m_pPlayer->GetID()) > 0) && !pUnit->IsCanDefend();3036 bool bIsInTerritory = (pPlot->getTeam() == m_pPlayer->getTeam());30373038#if defined(MOD_AI_SMART_V3)3039 bool bNeedEmbark = ((pUnit->getDomainType() == DOMAIN_LAND) && (!pUnit->plot()->isWater()) && (pPlot->isWater()));3040#endif3041 #define MAX_DANGER_VALUE 1000003042 #define PREFERENCE_LEVEL(x, y) (x * MAX_DANGER_VALUE) + ((MAX_DANGER_VALUE - 1) - y)30433044 CvAssert(iDanger < MAX_DANGER_VALUE);30453046 int iScore;3047#if defined(MOD_AI_SMART_V3)3048 if (MOD_AI_SMART_V3) {3049 // AMS: Lower preference if water and uncovered.3050 if(bNeedEmbark && !bIsInCover)3051 {3052 iScore = PREFERENCE_LEVEL(0, iDanger);3053 }3054 else if(bIsInCity)3055 {3056 iScore = PREFERENCE_LEVEL(6, iDanger);3057 }3058 else if(bIsZeroDanger)3059 {3060 if (bIsInTerritory)3061 iScore = PREFERENCE_LEVEL(5, iDanger);3062 else3063 iScore = PREFERENCE_LEVEL(4, iDanger);3064 }3065 else if(bIsInCover)3066 {3067 iScore = PREFERENCE_LEVEL(3, iDanger);3068 }3069 else if(bIsInTerritory)3070 {3071 iScore = PREFERENCE_LEVEL(2, iDanger);3072 }3073 // if we have no good home, head to the lowest danger value3074 else 3075 {3076 iScore = PREFERENCE_LEVEL(1, iDanger);3077 }3078 }3079 else3080 {3081#endif3082 if(bIsInCity)3083 {3084 iScore = PREFERENCE_LEVEL(5, iDanger);3085 }3086 else if(bIsZeroDanger)3087 {3088 if (bIsInTerritory)3089 iScore = PREFERENCE_LEVEL(4, iDanger);3090 else3091 iScore = PREFERENCE_LEVEL(3, iDanger);3092 }3093 else if(bIsInCover)3094 {3095 iScore = PREFERENCE_LEVEL(2, iDanger);3096 }3097 else if(bIsInTerritory)3098 {3099 iScore = PREFERENCE_LEVEL(1, iDanger);3100 }3101 // if we have no good home, head to the lowest danger value3102 else 3103 {3104 iScore = PREFERENCE_LEVEL(0, iDanger);3105 }3106#if defined(MOD_AI_SMART_V3)3107 }3108#endif31093110 aBestPlotList.push_back(pPlot, iScore);3111 }3112 }31133114 aBestPlotList.SortItems();31153116 // Now loop through the sorted score list and go to the best one we can reach in one turn.3117 // #define EXECUTEMOVESTOSAFESTPLOT_FAILURE_LIMIT3118 #ifdef EXECUTEMOVESTOSAFESTPLOT_FAILURE_LIMIT3119 int iFailureLimit = 10;3120 #endif3121 uint uiListSize;3122 if ((uiListSize = aBestPlotList.size()) > 0)3123 {3124 aBestPlotList.SortItems(); // highest score will be first.3125 for (uint i = 0; i < uiListSize; ++i ) 3126 {3127 CvPlot* pPlot = aBestPlotList.GetElement(i);31283129 if(CanReachInXTurns(pUnit, pPlot, 1))3130 {3131 pBestPlot = pPlot;3132 break;3133 }3134 #ifdef EXECUTEMOVESTOSAFESTPLOT_FAILURE_LIMIT3135 else3136 {3137 if (iFailureLimit-- == 0)3138 break;3139 }3140 #endif3141 }3142 }31433144 if(pBestPlot != NULL)3145 {3146 // Move to the lowest danger value found3147 pUnit->PushMission(CvTypes::getMISSION_MOVE_TO(), pBestPlot->getX(), pBestPlot->getY(), MOVE_UNITS_IGNORE_DANGER);3148 pUnit->finishMoves();3149 UnitProcessed(pUnit->GetID());31503151 if(GC.getLogging() && GC.getAILogging())3152 {3153 CvString strLogString;3154 CvString strTemp;3155 strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();3156 strLogString.Format("Moving %s to safety, X: %d, Y: %d", strTemp.GetCString(), pBestPlot->getX(), pBestPlot->getY());3157 LogHomelandMessage(strLogString);3158 }3159 }3160 }3161 }3162}