Bazaar developer reference

CvBuilderTaskingAI::ConnectCitiesToCapital(CvCity *, CvCity *, RouteTypes)

Defined in
CvBuilderTaskingAI.cpp, line 278
Class
CvBuilderTaskingAI
Hook name
CivHooks::CvBuilderTaskingAI_ConnectCitiesToCapital

Hooks

static bool BeforeCvBuilderTaskingAI_ConnectCitiesToCapital(CvBuilderTaskingAI* self, CvCity* pPlayerCapital, CvCity* pTargetCity, RouteTypes eRoute);static void AfterCvBuilderTaskingAI_ConnectCitiesToCapital(CvBuilderTaskingAI* self, CvCity* pPlayerCapital, CvCity* pTargetCity, RouteTypes eRoute);static void ReplaceCvBuilderTaskingAI_ConnectCitiesToCapital(void (*original)(CvBuilderTaskingAI*, CvCity*, CvCity*, RouteTypes), CvBuilderTaskingAI* self, CvCity* pPlayerCapital, CvCity* pTargetCity, RouteTypes eRoute);CivRegisterBefore<CivHooks::CvBuilderTaskingAI_ConnectCitiesToCapital>(host, &BeforeCvBuilderTaskingAI_ConnectCitiesToCapital);CivRegisterAfter<CivHooks::CvBuilderTaskingAI_ConnectCitiesToCapital>(host, &AfterCvBuilderTaskingAI_ConnectCitiesToCapital);CivRegisterReplace<CivHooks::CvBuilderTaskingAI_ConnectCitiesToCapital>(host, &ReplaceCvBuilderTaskingAI_ConnectCitiesToCapital);

Code

278void CvBuilderTaskingAI::ConnectCitiesToCapital(CvCity* pPlayerCapital, CvCity* pTargetCity, RouteTypes eRoute)279{280	bool bMajorMinorConnection = false;281	if(pTargetCity->getOwner() != pPlayerCapital->getOwner())282	{283		bMajorMinorConnection = true;284	}285286	bool bIndustrialRoute = false;287	if(GC.getGame().GetIndustrialRoute() == eRoute)288	{289		bIndustrialRoute = true;290	}291292	// if we already have a connection, bail out293	if(bIndustrialRoute && pTargetCity->IsIndustrialRouteToCapital())294	{295		return;296	}297	else if(m_pPlayer->IsCapitalConnectedToCity(pTargetCity, eRoute))298	{299		return;300	}301302	int iGoldForRoute = 0;303	if(!bMajorMinorConnection)304	{305		iGoldForRoute = m_pPlayer->GetTreasury()->GetCityConnectionRouteGoldTimes100(pTargetCity) / 100;306	}307308	CvRouteInfo* pRouteInfo = GC.getRouteInfo(eRoute);309	if(!pRouteInfo)310	{311		return;312	}313	int iMaintenancePerTile = pRouteInfo->GetGoldMaintenance();314	if(iMaintenancePerTile < 0)  // div by zero check315	{316		return;317	}318319	// build a path between the two cities320	int iPathfinderFlags = m_pPlayer->GetID();321	int iRouteValue = eRoute + 1;322	// assuming that there are fewer than 256 players323	iPathfinderFlags |= (iRouteValue << 8);324	bool bFoundPath = GC.GetBuildRouteFinder().GeneratePath(pPlayerCapital->plot()->getX(), pPlayerCapital->plot()->getY(), pTargetCity->plot()->getX(), pTargetCity->plot()->getY(), iPathfinderFlags);325326	//  if no path, then bail!327	if(!bFoundPath)328	{329		return;330	}331332	// walk the path333	CvPlot* pPlot = NULL;334335	// go through the route to see how long it is and how many plots already have roads336	int iRoadLength = 0;337	int iPlotsNeeded = 0;338	CvAStarNode* pNode = GC.GetBuildRouteFinder().GetLastNode();339	while(pNode)340	{341		pPlot = GC.getMap().plotCheckInvalid(pNode->m_iX, pNode->m_iY);342		pNode = pNode->m_pParent;343		if(!pPlot)344		{345			break;346		}347348		CvCity* pCity = pPlot->getPlotCity();349		if(NULL != pCity && pCity->getTeam() == m_pPlayer->getTeam())350		{351			continue;352		}353354		if(pPlot->getRouteType() == eRoute && !pPlot->IsRoutePillaged())355		{356			// if this is already a trade route or someone else built it, we can count is as free357			if(pPlot->IsTradeRoute(m_pPlayer->GetID()) || pPlot->GetPlayerResponsibleForRoute() != m_pPlayer->GetID())358			{359				continue;360			}361			iRoadLength++;362		}363		else364		{365			iRoadLength++;366			iPlotsNeeded++;367		}368	}369370	// This is very odd371	if(iRoadLength <= 0 || iPlotsNeeded <= 0)372	{373		return;374	}375376377	short sValue = -1;378	int iProfit = iGoldForRoute - (iRoadLength * iMaintenancePerTile);379	if(bIndustrialRoute)380	{381		if(iProfit >= 0)382		{383			sValue = MAX_SHORT;384		}385		else if(m_pPlayer->calculateGoldRate() + iProfit >= 0)386		{387			sValue = pTargetCity->getYieldRate(YIELD_PRODUCTION, false) * GC.getINDUSTRIAL_ROUTE_PRODUCTION_MOD();388		}389		else390		{391			return;392		}393	}394	else if(bMajorMinorConnection)395	{396		sValue = min(GC.getMINOR_CIV_ROUTE_QUEST_WEIGHT() / iPlotsNeeded, MAX_SHORT);397	}398	else // normal route399	{400		// is this route worth building?401		if(iProfit < 0)402		{403			return;404		}405406		int iValue = (iGoldForRoute * 100) / (iRoadLength * (iMaintenancePerTile + 1));407		iValue = (iValue * iRoadLength) / iPlotsNeeded;408		sValue = min(iValue, MAX_SHORT);409	}410411	pPlot = NULL;412	pNode = GC.GetBuildRouteFinder().GetLastNode();413414	int iGameTurn = GC.getGame().getGameTurn();415416	while(pNode)417	{418		pPlot = GC.getMap().plotCheckInvalid(pNode->m_iX, pNode->m_iY);419		pNode = pNode->m_pParent;420421		if(!pPlot)422		{423			break;424		}425426		if(pPlot->getRouteType() == eRoute && !pPlot->IsRoutePillaged())427		{428			continue;429		}430431		// if we already know about this plot, continue on432		if(pPlot->GetBuilderAIScratchPadTurn() == iGameTurn && pPlot->GetBuilderAIScratchPadPlayer() == m_pPlayer->GetID())433		{434			if(sValue > pPlot->GetBuilderAIScratchPadValue())435			{436				pPlot->SetBuilderAIScratchPadValue(sValue);437				pPlot->SetBuilderAIScratchPadRoute(eRoute);438			}439			continue;440		}441442		// mark nodes and reset values443		pPlot->SetBuilderAIScratchPadTurn(iGameTurn);444		pPlot->SetBuilderAIScratchPadPlayer(m_pPlayer->GetID());445		pPlot->SetBuilderAIScratchPadValue(sValue);446		pPlot->SetBuilderAIScratchPadRoute(eRoute);447448		// add nodes that are not in territory to extra list449		// minors should not build out of their borders when they are doing a major/minor connection, only when connecting their two cities450		if(!(m_pPlayer->isMinorCiv() && bMajorMinorConnection))451		{452			if(pPlot->getOwner() != m_pPlayer->GetID())453			{454				m_aiNonTerritoryPlots.push_back(GC.getMap().plotNum(pPlot->getX(), pPlot->getY()));455			}456		}457	}458}

Calls

Called by