Bazaar developer reference

CvTacticalAI::ExecuteMovesToSafestPlot()

Defined in
CvTacticalAI.cpp, line 6833
Class
CvTacticalAI
Hook name
CivHooks::CvTacticalAI_ExecuteMovesToSafestPlot

Hooks

static bool BeforeCvTacticalAI_ExecuteMovesToSafestPlot(CvTacticalAI* self);static void AfterCvTacticalAI_ExecuteMovesToSafestPlot(CvTacticalAI* self);static void ReplaceCvTacticalAI_ExecuteMovesToSafestPlot(void (*original)(CvTacticalAI*), CvTacticalAI* self);CivRegisterBefore<CivHooks::CvTacticalAI_ExecuteMovesToSafestPlot>(host, &BeforeCvTacticalAI_ExecuteMovesToSafestPlot);CivRegisterAfter<CivHooks::CvTacticalAI_ExecuteMovesToSafestPlot>(host, &AfterCvTacticalAI_ExecuteMovesToSafestPlot);CivRegisterReplace<CivHooks::CvTacticalAI_ExecuteMovesToSafestPlot>(host, &ReplaceCvTacticalAI_ExecuteMovesToSafestPlot);

Code

6832/// Moves units to the hex with the lowest danger6833void CvTacticalAI::ExecuteMovesToSafestPlot()6834{6835	int iDanger;68366837#if defined(PATH_PLAN_LAST)6838	// Maybe make these part of the class and just reuse?6839	WeightedPlotVector aCityList;6840	aCityList.reserve(10);6841	WeightedPlotVector aZeroDangerList;6842	aZeroDangerList.reserve(100);6843	WeightedPlotVector aCoverList;6844	aCoverList.reserve(100);6845	WeightedPlotVector aDangerList;6846	aDangerList.reserve(100);6847#endif68486849	TeamTypes ePlayerTeam = m_pPlayer->getTeam();6850	PlayerTypes ePlayerID = m_pPlayer->GetID();68516852	for(unsigned int iI = 0; iI < m_CurrentMoveUnits.size(); iI++)6853	{6854		UnitHandle pUnit = m_pPlayer->getUnit(m_CurrentMoveUnits[iI].GetID());6855		if(pUnit)6856		{6857#if defined(PATH_PLAN_LAST)6858			aCityList.clear();6859			aZeroDangerList.clear();6860			aCoverList.clear();6861			aDangerList.clear();6862#endif6863			CvPlot* pBestPlot = NULL;68646865			int iRange = pUnit->getUnitInfo().GetMoves();6866#if !defined(PATH_PLAN_LAST)6867			int iLowestDanger = MAX_INT;6868			bool bResultHasZeroDangerMove = false;6869			bool bResultInTerritory = false;6870			bool bResultInCity = false;6871			bool bResultInCover = false;6872#endif68736874			CvMap& kMap = GC.getMap();6875			int iUnitX = pUnit->getX();6876			int iUnitY = pUnit->getY();6877			DomainTypes eUnitDomain = pUnit->getDomainType();6878			bool bIsSeaUnit = eUnitDomain == DOMAIN_SEA;68796880			// For each plot within movement range of the fleeing unit6881			for(int iX = -iRange; iX <= iRange; iX++)6882			{6883				for(int iY = -iRange; iY <= iRange; iY++)6884				{6885					CvPlot* pPlot = kMap.plot(iUnitX + iX, iUnitY + iY);6886					if(pPlot == NULL)6887					{6888						continue;6889					}68906891					// Can't be a plot with another player's unit in it or another of our unit of same type6892					if(pPlot->getNumUnits() > 0)6893					{6894						IDInfo* pUnitNode = pPlot->headUnitNode();6895						if(pUnitNode)6896						{6897							CvUnit* pFirstUnit = ::getUnit(*pUnitNode);6898							if(pFirstUnit)6899							{6900								if(pFirstUnit->getOwner() != pUnit->getOwner())6901								{6902									continue;6903								}69046905								else if(pUnit->AreUnitsOfSameType(*pFirstUnit))6906								{6907									continue;6908								}6909							}6910						}6911					}69126913					// Also filter out sea units targeting land plots6914					if (bIsSeaUnit && !pPlot->isWater())6915					{6916						continue;6917					}69186919#if !defined(PATH_PLAN_LAST)6920					if(!CanReachInXTurns(pUnit, pPlot, 1))6921					{6922						continue;6923					}6924#endif6925					//   prefer being in a city with the lowest danger value6926					//   prefer being in a plot with no danger value6927					//   prefer being under a unit with the lowest danger value6928					//   prefer being in your own territory with the lowest danger value6929					//   prefer the lowest danger value69306931					iDanger = m_pPlayer->GetPlotDanger(*pPlot);6932					bool bIsZeroDanger = (iDanger <= 0);6933					bool bIsInCity = pPlot->isFriendlyCity(*pUnit, false);6934					bool bIsInCover = (pPlot->getNumDefenders(ePlayerID) > 0) && !pUnit->IsCanDefend(pPlot); // only move to cover if I'm defenseless here6935					bool bIsInTerritory = (pPlot->getTeam() == ePlayerTeam);6936#if defined(MOD_AI_SMART_V3)					6937					bool bNeedEmbark = ((eUnitDomain == DOMAIN_LAND) && (!pUnit->plot()->isWater()) && (pPlot->isWater()));6938#endif69396940#if defined(PATH_PLAN_LAST)6941#if defined(MOD_AI_SMART_V3)					6942					// AMS: Enormous danger on water plot, embarking as last option.6943					if(MOD_AI_SMART_V3 && bNeedEmbark && !bIsInCover)6944					{6945						int combatMod = pUnit->GetBaseCombatStrength() == 0 ? 100 : pUnit->GetBaseCombatStrength();6946						iDanger = min(combatMod * 900, 99999);6947						aDangerList.push_back(pPlot, iDanger);6948					}6949					else6950#endif6951					if(bIsInCity)6952					{6953						aCityList.push_back(pPlot, iDanger);6954					}6955					else6956					if(bIsZeroDanger)6957					{6958						aZeroDangerList.push_back(pPlot, (bIsInTerritory)?0:1);6959					}6960					else6961					if(bIsInCover)6962					{6963						aCoverList.push_back(pPlot, iDanger);6964					}6965					else6966					{6967						aDangerList.push_back(pPlot, iDanger);6968					}6969#endif69706971#if !defined(PATH_PLAN_LAST)6972					bool bUpdateBestValue = false;69736974					if(bIsInCity)6975					{6976						if(!bResultInCity || iDanger < iLowestDanger)6977						{6978							bUpdateBestValue = true;6979						}6980					}6981					else if(bIsZeroDanger)6982					{6983						if(!bResultInCity)6984						{6985							if(bResultHasZeroDangerMove)6986							{6987								if(bIsInTerritory && !bResultInTerritory)6988								{6989									bUpdateBestValue = true;6990								}6991							}6992							else6993							{6994								bUpdateBestValue = true;6995							}6996						}6997					}6998					else if(bIsInCover)6999					{7000						if(!bResultInCity && !bResultHasZeroDangerMove)7001						{7002							if(!bResultInCover || iDanger < iLowestDanger)7003							{7004								bUpdateBestValue = true;7005							}7006						}7007					}7008					else if(bIsInTerritory)7009					{7010						if(!bResultInCity && !bResultInCover && !bResultHasZeroDangerMove)7011						{7012							if(!bResultInTerritory || iDanger < iLowestDanger)7013							{7014								bUpdateBestValue = true;7015							}7016						}7017					}7018					// if we have no good home, head to the lowest danger value7019					else if(!bResultInCity && !bResultInCover && !bResultInTerritory && !bResultHasZeroDangerMove)7020					{7021						if(iDanger < iLowestDanger)7022						{7023							bUpdateBestValue = true;7024						}7025					}70267027					if(bUpdateBestValue)7028					{7029						pBestPlot = pPlot;7030						iLowestDanger = iDanger;70317032						bResultInTerritory = bIsInTerritory;7033						bResultInCity      = bIsInCity;7034						bResultInCover     = bIsInCover;7035						bResultHasZeroDangerMove = bIsZeroDanger;7036					}7037#endif7038				}7039			}70407041#if defined(PATH_PLAN_LAST)7042			// Now that we've gathered up our lists of destinations, go through them in order and pick the first one we can reach.7043			// This minimizes accessing the pathfinder.7044			if ((pBestPlot = GetReachablePlot(pUnit, aCityList, 1)) == NULL)7045				if ((pBestPlot = GetReachablePlot(pUnit, aZeroDangerList, 1)) == NULL)7046					if ((pBestPlot = GetReachablePlot(pUnit, aCoverList, 1)) == NULL)7047						pBestPlot = GetReachablePlot(pUnit, aDangerList, 1);7048#endif70497050			if(pBestPlot != NULL)7051			{7052				// Move to the lowest danger value found7053				pUnit->PushMission(CvTypes::getMISSION_MOVE_TO(), pBestPlot->getX(), pBestPlot->getY(), MOVE_UNITS_IGNORE_DANGER);7054				pUnit->finishMoves();7055				UnitProcessed(pUnit->GetID(), pUnit->IsCombatUnit());70567057				if(GC.getLogging() && GC.getAILogging())7058				{7059					CvString strLogString;7060					CvString strTemp;7061					strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();7062					strLogString.Format("Moving %s to safety, To X: %d, Y: %d, From X: %d, Y: %d", strTemp.GetCString(), pBestPlot->getX(), pBestPlot->getY(), pUnit->getX(), pUnit->getY());7063					LogTacticalMessage(strLogString);7064				}7065			}7066			else7067			{7068				if(GC.getLogging() && GC.getAILogging())7069				{7070					CvString strLogString;7071					CvString strTemp;7072					strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();7073					strLogString.Format("Failed to find destination moving %s to safety from, X: %d, Y: %d", strTemp.GetCString(), pUnit->getX(), pUnit->getY());7074					LogTacticalMessage(strLogString);7075				}7076			}7077		}7078	}7079}

Calls

Called by