Bazaar developer reference

CvHomelandAI::MoveCivilianToSafety(CvUnit *, bool, bool)

Defined in
CvHomelandAI.cpp, line 4946
Class
CvHomelandAI
Hook name
CivHooks::CvHomelandAI_MoveCivilianToSafety

Hooks

static bool BeforeCvHomelandAI_MoveCivilianToSafety(CvHomelandAI* self, CvUnit* pUnit, bool bIgnoreUnits, bool bSecondary, bool& result);static void AfterCvHomelandAI_MoveCivilianToSafety(CvHomelandAI* self, CvUnit* pUnit, bool bIgnoreUnits, bool bSecondary, bool& result);static bool ReplaceCvHomelandAI_MoveCivilianToSafety(bool (*original)(CvHomelandAI*, CvUnit*, bool, bool), CvHomelandAI* self, CvUnit* pUnit, bool bIgnoreUnits, bool bSecondary);CivRegisterBefore<CivHooks::CvHomelandAI_MoveCivilianToSafety>(host, &BeforeCvHomelandAI_MoveCivilianToSafety);CivRegisterAfter<CivHooks::CvHomelandAI_MoveCivilianToSafety>(host, &AfterCvHomelandAI_MoveCivilianToSafety);CivRegisterReplace<CivHooks::CvHomelandAI_MoveCivilianToSafety>(host, &ReplaceCvHomelandAI_MoveCivilianToSafety);

Code

4944/// Fleeing to safety for civilian units4945#if defined(MOD_AI_SECONDARY_WORKERS)4946bool CvHomelandAI::MoveCivilianToSafety(CvUnit* pUnit, bool bIgnoreUnits, bool bSecondary)4947#else4948bool CvHomelandAI::MoveCivilianToSafety(CvUnit* pUnit, bool bIgnoreUnits)4949#endif4950{4951	int iSearchRange = pUnit->SearchRange(1);49524953	// Collecting all the possibilities first.4954	WeightedPlotVector aBestPlotList;4955	aBestPlotList.reserve( ((iSearchRange * 2) + 1) * 2 );49564957	for(int iDX = -(iSearchRange); iDX <= iSearchRange; iDX++)4958	{4959		for(int iDY = -(iSearchRange); iDY <= iSearchRange; iDY++)4960		{4961			CvPlot* pLoopPlot = plotXYWithRangeCheck(pUnit->getX(), pUnit->getY(), iDX, iDY, iSearchRange);4962			if(!pLoopPlot)4963			{4964				continue;4965			}49664967#if defined(MOD_AI_SECONDARY_WORKERS)4968			if(!pUnit->PlotValid(pLoopPlot, CvUnit::MOVEFLAG_PRETEND_CORRECT_EMBARK_STATE))4969#else4970			if(!pUnit->PlotValid(pLoopPlot))4971#endif4972			{4973				continue;4974			}49754976			if(pLoopPlot->isVisibleEnemyUnit(pUnit))4977			{4978				continue;4979			}49804981			int iValue = 0;4982			if(pLoopPlot->getOwner() != NO_PLAYER && GET_PLAYER(pLoopPlot->getOwner()).getTeam() == m_pPlayer->getTeam())4983			{4984				// if this is within our territory, provide a minor benefit4985				iValue += 1;4986			}49874988#if defined(MOD_AI_SECONDARY_WORKERS)4989			if (bSecondary && pUnit->getDomainType() == DOMAIN_LAND && pLoopPlot->isWater()) {4990				// being embarked is NOT safe!4991				iValue -= 100;4992			}4993#endif49944995			CvCity* pCity = pLoopPlot->getPlotCity();4996			if(pCity && pCity->getTeam() == pUnit->getTeam())4997			{4998				iValue += pCity->getStrengthValue() * (GC.getMAX_CITY_DEFENSE_DAMAGE() - pCity->getDamage());4999			}5000			else if(!bIgnoreUnits)5001			{5002				IDInfo* pUnitNode = pLoopPlot->headUnitNode();5003				while(pUnitNode != NULL)5004				{5005					CvUnit* pLoopUnit = ::getUnit(*pUnitNode);5006					pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);50075008					if(pLoopUnit && pLoopUnit->getOwner() == pUnit->getOwner())5009					{5010						if(pLoopUnit->IsCanDefend())5011						{5012							if(pLoopUnit != pUnit)5013							{5014								if(pLoopUnit->isWaiting() || !(pLoopUnit->canMove()))5015								{5016									iValue += pLoopUnit->GetMaxDefenseStrength(pLoopPlot, NULL) * pLoopUnit->GetCurrHitPoints();5017								}5018							}5019						}5020					}5021				}5022			}50235024			iValue -= m_pPlayer->GetPlotDanger(*pLoopPlot);50255026			aBestPlotList.push_back(pLoopPlot, iValue);5027		}5028	}50295030	// Now loop through the sorted score list and go to the best one we can reach in one turn.5031	CvPlot* pBestPlot = NULL;5032	uint uiListSize;5033	if ((uiListSize = aBestPlotList.size()) > 0)5034	{5035		aBestPlotList.SortItems();	// highest score will be first.5036		for (uint i = 0; i < uiListSize; ++i )	5037		{5038			CvPlot* pPlot = aBestPlotList.GetElement(i);50395040			int iPathTurns;5041			if(!pUnit->GeneratePath(pPlot, MOVE_UNITS_IGNORE_DANGER, true, &iPathTurns))5042			{5043				continue;5044			}50455046			// if we can't get there this turn, forget it5047			if(iPathTurns > 1)5048			{5049				continue;5050			}50515052			pBestPlot = pPlot;5053			break;5054		}5055	}50565057	if(pBestPlot != NULL)5058	{5059		if(pUnit->atPlot(*pBestPlot))5060		{5061			if (pUnit->canHold(pBestPlot))5062			{5063				if(GC.getLogging() && GC.getAILogging())5064				{5065					CvString strLogString;5066					CvString strTemp;5067					strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();5068					strLogString.Format("%s (%d) tried to move to safety but is at the best spot, X: %d, Y: %d", strTemp.GetCString(), pUnit->GetID(), pBestPlot->getX(), pBestPlot->getY());5069					LogHomelandMessage(strLogString);5070				}50715072				pUnit->PushMission(CvTypes::getMISSION_SKIP());5073				return true;5074			}5075			else5076			{5077				if(GC.getLogging() && GC.getAILogging())5078				{5079					CvString strLogString;5080					CvString strTemp;5081					strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();5082					strLogString.Format("%s (%d) tried to move to safety but cannot hold in current location, X: %d, Y: %d", strTemp.GetCString(), pUnit->GetID(), pBestPlot->getX(), pBestPlot->getY());5083					LogHomelandMessage(strLogString);5084				}5085				pUnit->SetAutomateType(NO_AUTOMATE);5086			}5087		}5088		else5089		{5090			if(GC.getLogging() && GC.getAILogging())5091			{5092				CvString strLogString;5093				CvString strTemp;5094				strTemp = GC.getUnitInfo(pUnit->getUnitType())->GetDescription();5095				strLogString.Format("%s (%d) moving to safety, X: %d, Y: %d", strTemp.GetCString(), pUnit->GetID(), pBestPlot->getX(), pBestPlot->getY());5096				LogHomelandMessage(strLogString);5097			}50985099			pUnit->PushMission(CvTypes::getMISSION_MOVE_TO(), pBestPlot->getX(), pBestPlot->getY(), MOVE_UNITS_IGNORE_DANGER);5100			return true;5101		}5102	}5103	else5104	{5105		if(GC.getLogging() && GC.getAILogging())5106		{5107			CvString strLogString;5108			CvString strTemp;5109			strTemp = pUnit->getUnitInfo().GetDescription();5110			strLogString.Format("%s (%d) tried to move to a safe point but couldn't find a good place to go", strTemp.GetCString(), pUnit->GetID());5111			LogHomelandMessage(strLogString);5112		}5113	}511451155116	return false;5117}

Calls

Called by