Bazaar developer reference

CvBuilderTaskingAI::EvaluateBuilder(CvUnit *, BuilderDirective *, UINT, bool, bool, bool)

Defined in
CvBuilderTaskingAI.cpp, line 648
Class
CvBuilderTaskingAI
Hook name
CivHooks::CvBuilderTaskingAI_EvaluateBuilder

Hooks

static bool BeforeCvBuilderTaskingAI_EvaluateBuilder(CvBuilderTaskingAI* self, CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit, bool& result);static void AfterCvBuilderTaskingAI_EvaluateBuilder(CvBuilderTaskingAI* self, CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit, bool& result);static bool ReplaceCvBuilderTaskingAI_EvaluateBuilder(bool (*original)(CvBuilderTaskingAI*, CvUnit*, BuilderDirective*, UINT, bool, bool, bool), CvBuilderTaskingAI* self, CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit);CivRegisterBefore<CivHooks::CvBuilderTaskingAI_EvaluateBuilder>(host, &BeforeCvBuilderTaskingAI_EvaluateBuilder);CivRegisterAfter<CivHooks::CvBuilderTaskingAI_EvaluateBuilder>(host, &AfterCvBuilderTaskingAI_EvaluateBuilder);CivRegisterReplace<CivHooks::CvBuilderTaskingAI_EvaluateBuilder>(host, &ReplaceCvBuilderTaskingAI_EvaluateBuilder);

Code

646/// Use the flavor settings to determine what the worker should do647#if defined(MOD_UNITS_LOCAL_WORKERS) || defined(MOD_AI_SECONDARY_WORKERS)648bool CvBuilderTaskingAI::EvaluateBuilder(CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit)649#else650bool CvBuilderTaskingAI::EvaluateBuilder(CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot)651#endif652{653	// number of cities has changed mid-turn, so we need to re-evaluate what workers should do654	if(m_pPlayer->getNumCities() != m_iNumCities)655	{656		Update();657	}658659	CvAssertMsg(uaDirectives > 0, "Need more than one directive");660661	for(uint ui = 0; ui < uaDirectives; ui++)662	{663		paDirectives[ui].m_eDirective = BuilderDirective::NUM_DIRECTIVES;664	}665666	m_aDirectives.clear();667668	// check for no brainer bail-outs669	// if the builder is already building something670	if(pUnit->getBuildType() != NO_BUILD)671	{672		paDirectives[0].m_eDirective = BuilderDirective::BUILD_IMPROVEMENT;673		paDirectives[0].m_eBuild = pUnit->getBuildType();674		paDirectives[0].m_sX = pUnit->getX();675		paDirectives[0].m_sY = pUnit->getY();676		//inDirective.m_sGoldCost = 0;677		paDirectives[0].m_sMoveTurnsAway = 0;678		return true;679	}680681	m_aiPlots.clear();682	if(bOnlyEvaluateWorkersPlot)683	{684		// can't build on plots others own685		PlayerTypes eOwner = pUnit->plot()->getOwner();686		if(eOwner == m_pPlayer->GetID())687		{688			m_aiPlots.push_back(pUnit->plot()->GetPlotIndex());689		}690	}691	else692	{693		m_aiPlots = m_pPlayer->GetPlots();694	}695696	// go through all the plots the player has under their control697	for(uint uiPlotIndex = 0; uiPlotIndex < m_aiPlots.size(); uiPlotIndex++)698	{699		// when we encounter the first plot that is invalid, the rest of the list will be invalid700		if(m_aiPlots[uiPlotIndex] == -1)701		{702			if(m_bLogging)703			{704				CvString strLog = "end of plot list";705				LogInfo(strLog, m_pPlayer);706			}707			break;708		}709710		CvPlot* pPlot = GC.getMap().plotByIndex(m_aiPlots[uiPlotIndex]);711712		if(!ShouldBuilderConsiderPlot(pUnit, pPlot))713		{714			continue;715		}716717		// distance weight718		// find how many turns the plot is away719#if defined(MOD_UNITS_LOCAL_WORKERS) || defined(MOD_AI_SECONDARY_WORKERS)720		int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot, bLimit);721#else722		int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot);723#endif724		if(iMoveTurnsAway < 0)725		{726			if(m_bLogging)727			{728				CvString strLog;729				strLog.Format("unitx: %d unity: %d, plotx: %d ploty: %d, can't find path", pUnit->getX(), pUnit->getY(), pPlot->getX(), pPlot->getY());730				LogInfo(strLog, m_pPlayer);731			}732733			continue;734		}735736		UpdateCurrentPlotYields(pPlot);737738		//AddRepairDirectives(pUnit, pPlot, iMoveTurnsAway);739		AddRouteDirectives(pUnit, pPlot, iMoveTurnsAway);740		AddImprovingResourcesDirectives(pUnit, pPlot, iMoveTurnsAway);741		AddImprovingPlotsDirectives(pUnit, pPlot, iMoveTurnsAway);742		AddChopDirectives(pUnit, pPlot, iMoveTurnsAway);743		AddScrubFalloutDirectives(pUnit, pPlot, iMoveTurnsAway);744		// only AIs have permission to remove roads745		if(!m_pPlayer->isHuman())746		{747			//AddRemoveUselessRoadDirectives(pUnit, pPlot, iMoveTurnsAway);748		}749	}750751	// we need to evaluate the tiles outside of our territory to build roads752	for(uint ui = 0; ui < m_aiNonTerritoryPlots.size(); ui++)753	{754		//FAssertMsg(!m_pPlayer->isMinorCiv(), "MinorCivs should have no nonterritory plots");755		CvPlot* pPlot = GC.getMap().plotByIndex(m_aiNonTerritoryPlots[ui]);756		CvAssertMsg(pPlot != NULL, "Plot should not be NULL");757		if(!pPlot)758			continue;759760		if(bOnlyEvaluateWorkersPlot)761		{762			if(pPlot != pUnit->plot())763			{764				continue;765			}766		}767768		if(!ShouldBuilderConsiderPlot(pUnit, pPlot))769		{770			continue;771		}772773		// distance weight774		// find how many turns the plot is away775#if defined(MOD_UNITS_LOCAL_WORKERS) || defined(MOD_AI_SECONDARY_WORKERS)776		int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot, bLimit);777#else778		int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot);779#endif780		if(iMoveTurnsAway < 0)781		{782			if(m_bLogging)783			{784				CvString strLog;785				strLog.Format("unitx: %d unity: %d, plotx: %d ploty: %d, Evaluating out of territory plot, can't find path", pUnit->getX(), pUnit->getY(), pPlot->getX(), pPlot->getY());786				LogInfo(strLog, m_pPlayer);787			}788789			continue;790		}791792		if(m_bLogging)793		{794			CvString strLog;795			strLog.Format("x: %d y: %d, Evaluating out of territory plot", pPlot->getX(), pPlot->getY());796			LogInfo(strLog, m_pPlayer);797		}798799		//AddRepairDirectives(pUnit, pPlot, iMoveTurnsAway);800		AddRouteDirectives(pUnit, pPlot, iMoveTurnsAway);801	}802803	m_aDirectives.StableSortItems();804805	int iBestWeight = 0;806807	int iAssignIndex = 0;808	for(int i = 0; i < m_aDirectives.size(); i++)809	{810		// If this target was far away, we only estimated the time to get there.  We need to be sure we have a real path there811		CvPlot* pTarget = GC.getMap().plot(m_aDirectives.GetElement(i).m_sX, m_aDirectives.GetElement(i).m_sY);812		CvAssertMsg(pTarget != NULL, "Not expecting the target to be NULL");813		if(!pTarget)814			continue;815816#if 0	// KWG: We are now always doing a raw estimate when gathering the directives817		int iPlotDistance = plotDistance(pUnit->getX(), pUnit->getY(), pTarget->getX(), pTarget->getY());818		if(iPlotDistance >= GC.getAI_HOMELAND_ESTIMATE_TURNS_DISTANCE())819#endif820		{821			if(TurnsToReachTarget(pUnit, pTarget) == MAX_INT)822			{823				// No path, need to pick a new directive824				continue;825			}826		}827828		if(iBestWeight == 0)829		{830			iBestWeight = m_aDirectives.GetWeight(i);831		}832833		if(bOnlyKeepBest)834		{835			int iWeight = m_aDirectives.GetWeight(i);836			if(iWeight < iBestWeight * 3 / 4)837			{838				break;839			}840		}841842		BuilderDirective directive = m_aDirectives.GetElement(i);843		paDirectives[iAssignIndex] = directive;844		iAssignIndex++;845846		// if we shouldn't copy over any more directives, then break847		if(iAssignIndex >= (int)uaDirectives)848		{849			break;850		}851	}852853	if(m_bLogging)854	{855		if(m_aDirectives.size() > 0)856		{857			//LogFlavors(NO_FLAVOR);858		}859860		LogDirectives(pUnit);861	}862863	//if (m_aDirectives.size() > 0 && iAssignIndex > 0)864	if(iAssignIndex > 0)865	{866		if(m_bLogging)867		{868			LogDirective(paDirectives[0], pUnit, -1, true /*bChosen*/);869		}870		return true;871	}872873	return false;874}

Calls

Called by