Bazaar developer reference

CvTacticalAI::FindBestBarbarianSeaMove(UnitHandle)

Defined in
CvTacticalAI.cpp, line 10052
Class
CvTacticalAI
Hook name
CivHooks::CvTacticalAI_FindBestBarbarianSeaMove

Hooks

static bool BeforeCvTacticalAI_FindBestBarbarianSeaMove(CvTacticalAI* self, UnitHandle pUnit, CvPlot*& result);static void AfterCvTacticalAI_FindBestBarbarianSeaMove(CvTacticalAI* self, UnitHandle pUnit, CvPlot*& result);static CvPlot* ReplaceCvTacticalAI_FindBestBarbarianSeaMove(CvPlot* (*original)(CvTacticalAI*, UnitHandle), CvTacticalAI* self, UnitHandle pUnit);CivRegisterBefore<CivHooks::CvTacticalAI_FindBestBarbarianSeaMove>(host, &BeforeCvTacticalAI_FindBestBarbarianSeaMove);CivRegisterAfter<CivHooks::CvTacticalAI_FindBestBarbarianSeaMove>(host, &AfterCvTacticalAI_FindBestBarbarianSeaMove);CivRegisterReplace<CivHooks::CvTacticalAI_FindBestBarbarianSeaMove>(host, &ReplaceCvTacticalAI_FindBestBarbarianSeaMove);

Code

10051/// Find a multi-turn target for a sea barbarian to wander towards10052CvPlot* CvTacticalAI::FindBestBarbarianSeaMove(UnitHandle pUnit)10053{10054	CvPlot* pBestMovePlot = NULL;10055	int iBestValue;10056	int iValue;10057	CvPlot* pPlot;10058	CvTacticalTarget* pTarget;10059	int iMovementRate;1006010061	iMovementRate = pUnit->baseMoves();10062	iBestValue = MAX_INT;10063	pBestMovePlot = NULL;1006410065	// Loop through all unit targets to find the closest10066	pTarget = GetFirstUnitTarget();10067	while(pTarget != NULL)10068	{10069		// Is this unit nearby enough?10070		if(plotDistance(pUnit->getX(), pUnit->getY(), pTarget->GetTargetX(), pTarget->GetTargetY()) < m_iSeaBarbarianRange)10071		{10072			pPlot = GC.getMap().plot(pTarget->GetTargetX(), pTarget->GetTargetY());10073#if defined(MOD_BUGFIX_MINOR)10074			if(pPlot && pUnit->getArea() == pPlot->getArea())10075#else10076			if(pUnit->getArea() == pPlot->getArea())10077#endif10078			{10079				iValue = TurnsToReachTarget(pUnit, pPlot, true /*bReusePaths*/);10080				if(iValue < iBestValue)10081				{10082					iBestValue = iValue;10083					pBestMovePlot = pPlot;10084				}10085			}10086		}10087		pTarget = GetNextUnitTarget();10088	}1008910090	// move toward trade routes10091	if (pBestMovePlot == NULL)10092	{10093		pBestMovePlot = FindBarbarianGankTradeRouteTarget(pUnit);10094	}1009510096	// No units to pick on, so sail to a tile adjacent to the second closest barbarian camp10097	if(pBestMovePlot == NULL)10098	{10099		CvPlot* pNearestCamp = NULL;10100		int iBestCampDistance = MAX_INT;1010110102		// Start by finding the very nearest camp10103		pTarget = GetFirstZoneTarget(AI_TACTICAL_TARGET_BARBARIAN_CAMP);10104		while(pTarget != NULL)10105		{10106			int iDistance = plotDistance(pUnit->getX(), pUnit->getY(), pTarget->GetTargetX(), pTarget->GetTargetY());10107			if(iDistance < iBestCampDistance)10108			{10109				pNearestCamp = GC.getMap().plot(pTarget->GetTargetX(), pTarget->GetTargetY());10110				iBestCampDistance = iDistance;10111			}10112			pTarget = GetNextZoneTarget();10113		}1011410115		// The obvious way to do this next part is to plot moves to each naval tile adjacent to each camp ...10116		// starting with the first camp and then proceeding to the final one.  But our optimization (to drop out10117		// targets that are further from the closest we've found so far) might in worst case not help at all if we10118		// check the closest camp last.  So instead we'll loop by DIRECTIONS first which should mean we pick up some plot10119		// from a close camp early (and the optimization will help)10120		for(int jJ = 0; jJ < NUM_DIRECTION_TYPES; jJ++)10121		{10122			pTarget = GetFirstZoneTarget(AI_TACTICAL_TARGET_BARBARIAN_CAMP);10123			while(pTarget != NULL)10124			{10125				CvPlot* pCamp = GC.getMap().plot(pTarget->GetTargetX(), pTarget->GetTargetY());10126				if(pCamp != pNearestCamp)10127				{10128					pPlot = plotDirection(pCamp->getX(), pCamp->getY(), ((DirectionTypes)jJ));10129					if(pPlot && pPlot->isWater())10130					{10131						int iDistance = plotDistance(pUnit->getX(), pUnit->getY(), pPlot->getX(), pPlot->getY());1013210133						// Optimization10134						if(iDistance < iMovementRate * iBestValue && iDistance < (m_iSeaBarbarianRange * 3))10135						{10136							iValue = TurnsToReachTarget(pUnit, pPlot, true /*bReusePaths*/);10137							if(iValue < iBestValue)10138							{10139								iBestValue = iValue;10140								pBestMovePlot = pPlot;10141							}10142						}10143					}10144				}10145				pTarget = GetNextZoneTarget();10146			}10147		}10148	}1014910150	// No obvious target, let's scan nearby tiles for the best choice, borrowing some of the code from the explore AI10151	if(pBestMovePlot == NULL)10152	{10153		// Now looking for BEST score10154		iBestValue = 0;10155		int iMovementRange = pUnit->movesLeft() / GC.getMOVE_DENOMINATOR();10156		for(int iX = -iMovementRange; iX <= iMovementRange; iX++)10157		{10158			for(int iY = -iMovementRange; iY <= iMovementRange; iY++)10159			{10160				CvPlot* pConsiderPlot = plotXYWithRangeCheck(pUnit->getX(), pUnit->getY(), iX, iY, iMovementRange);10161				if(!pConsiderPlot)10162				{10163					continue;10164				}1016510166				if(pUnit->atPlot(*pConsiderPlot))10167				{10168					continue;10169				}1017010171				if(!pConsiderPlot->isRevealed(pUnit->getTeam()))10172				{10173					continue;10174				}1017510176				if(pConsiderPlot->area() != pUnit->area())10177				{10178					continue;10179				}1018010181				if(!CanReachInXTurns(pUnit, pConsiderPlot, 1))10182				{10183					continue;10184				}1018510186				// Value them based on their explore value10187				DomainTypes eDomain = pUnit->getDomainType();10188				iValue = CvEconomicAI::ScoreExplorePlot(pConsiderPlot, pUnit->getTeam(), pUnit->getUnitInfo().GetBaseSightRange(), eDomain);1018910190				// Add special value for being near enemy lands10191				if(pConsiderPlot->isAdjacentOwned())10192				{10193					iValue += 100;10194				}10195				else if(pConsiderPlot->isOwned())10196				{10197					iValue += 200;10198				}1019910200				// If still have no value, score equal to distance from my current plot10201				if(iValue == 0)10202				{10203					iValue = plotDistance(pUnit->getX(), pUnit->getY(), pConsiderPlot->getX(), pConsiderPlot->getY());10204				}1020510206				if(iValue > iBestValue)10207				{10208					pBestMovePlot = pConsiderPlot;10209					iBestValue = iValue;10210				}10211			}10212		}10213	}1021410215	return pBestMovePlot;10216}

Calls

Called by