Bazaar developer reference

CvHomelandAI::ExecuteMovesToSafestPlot()

Defined in
CvHomelandAI.cpp, line 2994
Class
CvHomelandAI
Hook name
CivHooks::CvHomelandAI_ExecuteMovesToSafestPlot

Hooks

static bool BeforeCvHomelandAI_ExecuteMovesToSafestPlot(CvHomelandAI* self);static void AfterCvHomelandAI_ExecuteMovesToSafestPlot(CvHomelandAI* self);static void ReplaceCvHomelandAI_ExecuteMovesToSafestPlot(void (*original)(CvHomelandAI*), CvHomelandAI* self);CivRegisterBefore<CivHooks::CvHomelandAI_ExecuteMovesToSafestPlot>(host, &BeforeCvHomelandAI_ExecuteMovesToSafestPlot);CivRegisterAfter<CivHooks::CvHomelandAI_ExecuteMovesToSafestPlot>(host, &AfterCvHomelandAI_ExecuteMovesToSafestPlot);CivRegisterReplace<CivHooks::CvHomelandAI_ExecuteMovesToSafestPlot>(host, &ReplaceCvHomelandAI_ExecuteMovesToSafestPlot);

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}

Calls

Called by