Bazaar developer reference

CvCityConnections::UpdateRouteInfo()

Defined in
CvCityConnections.cpp, line 220
Class
CvCityConnections
Hook name
CivHooks::CvCityConnections_UpdateRouteInfo
Lua events
GameEvents.CityConnections, GameEvents.CityConnected

Hooks

static bool BeforeCvCityConnections_UpdateRouteInfo(CvCityConnections* self);static void AfterCvCityConnections_UpdateRouteInfo(CvCityConnections* self);static void ReplaceCvCityConnections_UpdateRouteInfo(void (*original)(CvCityConnections*), CvCityConnections* self);CivRegisterBefore<CivHooks::CvCityConnections_UpdateRouteInfo>(host, &BeforeCvCityConnections_UpdateRouteInfo);CivRegisterAfter<CivHooks::CvCityConnections_UpdateRouteInfo>(host, &AfterCvCityConnections_UpdateRouteInfo);CivRegisterReplace<CivHooks::CvCityConnections_UpdateRouteInfo>(host, &ReplaceCvCityConnections_UpdateRouteInfo);

Code

220void CvCityConnections::UpdateRouteInfo(void)221{222	RouteTypes eBestRouteType = m_pPlayer->getBestRoute();223224	// build city list225	FStaticVector<CvCity*, SAFE_ESTIMATE_NUM_CITIES, true, c_eCiv5GameplayDLL, 0> vpCities;226	CvCity* pLoopCity = NULL;227	int iLoop;228229#if defined(MOD_EVENTS_CITY_CONNECTIONS)230	bool bAllowDirectRoutes = (eBestRouteType != NO_ROUTE);231	bool bAllowIndirectRoutes = false;232	233	bool bCallDirectEvents = false;234	bool bCallIndirectEvents = false;235#else236	bool bAllowWaterRoutes = false;237#endif238239	// add all the cities we control and those that we want to connect to240	for(uint ui = 0; ui < MAX_CIV_PLAYERS; ui++)241	{242		PlayerTypes ePlayer = (PlayerTypes)ui;243		if(GET_PLAYER(ePlayer).isBarbarian())244		{245			continue;246		}247248		if(ePlayer == m_pPlayer->GetID())249		{250			// player's city251			for(pLoopCity = m_pPlayer->firstCity(&iLoop); pLoopCity != NULL; pLoopCity = m_pPlayer->nextCity(&iLoop))252			{253				vpCities.push_back(pLoopCity);254				pLoopCity->SetRouteToCapitalConnected(false);255256#if defined(MOD_EVENTS_CITY_CONNECTIONS)257				if(!bAllowIndirectRoutes)258#else259				if(!bAllowWaterRoutes)260#endif261				{262					for(uint uiBuildingTypes = 0; uiBuildingTypes < m_aBuildingsAllowWaterRoutes.size(); uiBuildingTypes++)263					{264						if(pLoopCity->GetCityBuildings()->GetNumActiveBuilding(m_aBuildingsAllowWaterRoutes[uiBuildingTypes]) > 0)265						{266#if defined(MOD_EVENTS_CITY_CONNECTIONS)267							bAllowIndirectRoutes = true;268#else269							bAllowWaterRoutes = true;270#endif271						}272					}273				}274			}275		}276		else if(ShouldConnectToOtherPlayer(ePlayer))277		{278			CvCity* pOtherCapital = GET_PLAYER(ePlayer).getCapitalCity();279			if(pOtherCapital)280			{281				vpCities.push_back(pOtherCapital);282			}283		}284	}285286	if(vpCities.size() > m_uiRouteInfosDimension)287	{288		ResizeRouteInfo((uint)((float)m_uiRouteInfosDimension * 1.5f));289	}290	ResetRouteInfo();291	292#if defined(MOD_EVENTS_CITY_CONNECTIONS)293	if (MOD_EVENTS_CITY_CONNECTIONS) {294		// Events to determine if we support alternative direct and/or indirect route types295		if (GAMEEVENTINVOKE_TESTANY(GAMEEVENT_CityConnections, m_pPlayer->GetID(), true) == GAMEEVENTRETURN_TRUE) {296			bAllowDirectRoutes = true;297			bCallDirectEvents = true;298		}299300		if (GAMEEVENTINVOKE_TESTANY(GAMEEVENT_CityConnections, m_pPlayer->GetID(), false) == GAMEEVENTRETURN_TRUE) {301			bAllowIndirectRoutes = true;302			bCallIndirectEvents = true;303		}304	}305#endif306307	// if the player can't build any routes, then we don't need to check this308#if defined(MOD_EVENTS_CITY_CONNECTIONS)309	if(!(bAllowDirectRoutes || bAllowIndirectRoutes))310#else311	if(eBestRouteType == NO_ROUTE && !bAllowWaterRoutes)312#endif313	{314		return;315	}316317	// pass 0 = can cities connect via water routes318	// pass 1 = can cities connect via land and water routes319	for(int iPass = 0; iPass < 2; iPass++)320	{321#if defined(MOD_EVENTS_CITY_CONNECTIONS)322		if(iPass == 0 && !bAllowIndirectRoutes)  // if in the first pass and we can't create indirect routes, skip323#else324		if(iPass == 0 && !bAllowWaterRoutes)  // if in the first pass, we can't embark, skip325#endif326		{327			continue;328		}329#if defined(MOD_EVENTS_CITY_CONNECTIONS)330		else if(iPass == 1 && !(bAllowDirectRoutes || bAllowIndirectRoutes))  // if in the second pass and we can't create any routes (this allows for harbour to harbour connections without The Wheel), skip331#else332#if defined(MOD_BUGFIX_MINOR)333		else if(iPass == 1 && !(eBestRouteType != NO_ROUTE || bAllowWaterRoutes))  // if in the second pass, we can't build a road or a water connection, skip334#else335		else if(iPass == 1 && eBestRouteType == NO_ROUTE)  // if in the second pass, we can't build a road, skip336#endif337#endif338		{339			continue;340		}341342		CvCity* pFirstCity = NULL;343		CvCity* pSecondCity = NULL;344345		CvAStar* pkLandRouteFinder;346		pkLandRouteFinder = &GC.getRouteFinder();347348		for(uint uiFirstCityIndex = 0; uiFirstCityIndex < vpCities.size(); uiFirstCityIndex++)349		{350			pFirstCity = vpCities[uiFirstCityIndex];351			int iFirstCityArrayIndex = GetIndexFromCity(pFirstCity);352353			for(uint uiSecondCityIndex = 0; uiSecondCityIndex < vpCities.size(); uiSecondCityIndex++)354			{355				// same city! ignore356				if(uiSecondCityIndex == uiFirstCityIndex)357				{358					continue;359				}360				pSecondCity = vpCities[uiSecondCityIndex];361				int iSecondCityArrayIndex = GetIndexFromCity(pSecondCity);362363				RouteInfo* pRouteInfo = GetRouteInfo(iFirstCityArrayIndex, iSecondCityArrayIndex);364				RouteInfo* pInverseRouteInfo = GetRouteInfo(iSecondCityArrayIndex, iFirstCityArrayIndex);365366				// bail if either are null367				if(!pRouteInfo || !pInverseRouteInfo)368				{369					continue;370				}371372				// if the route has already been evaluated, copy the data373				if(pInverseRouteInfo->m_cPassEval > iPass)374				{375					pRouteInfo->m_cPassEval = pInverseRouteInfo->m_cPassEval;376					pRouteInfo->m_cRouteState = pInverseRouteInfo->m_cRouteState;377					continue;378				}379380#if !defined(MOD_EVENTS_CITY_CONNECTIONS)381				// this path already has an existing route (usually water)382				//if(pRouteInfo->m_cRouteState & (HAS_ANY_ROUTE | HAS_BEST_ROUTE | HAS_WATER_ROUTE))383				//{384				//	continue;385				//}386#endif387388				pRouteInfo->m_cPassEval = iPass + 1;389390				if(iPass == 0)  // check water route391				{392					// if either city is blockaded, don't consider a water connection393					if(pFirstCity->IsBlockaded() || pSecondCity->IsBlockaded())394					{395						continue;396					}397398					bool bFirstCityHasHarbor = false;399					bool bSecondCityHasHarbor = false;400401					// Loop through adding the available buildings402					for(int i = 0; i < (int)m_aBuildingsAllowWaterRoutes.size(); i++)403					{404						if(pFirstCity->GetCityBuildings()->GetNumActiveBuilding(m_aBuildingsAllowWaterRoutes[i]) > 0)405						{406							bFirstCityHasHarbor = true;407						}408409						if(pSecondCity->GetCityBuildings()->GetNumActiveBuilding(m_aBuildingsAllowWaterRoutes[i]) > 0)410						{411							bSecondCityHasHarbor = true;412						}413					}414415					if(bFirstCityHasHarbor && bSecondCityHasHarbor)416					{417						if(GC.GetWaterRouteFinder().GeneratePath(pFirstCity->getX(), pFirstCity->getY(), pSecondCity->getX(), pSecondCity->getY(), m_pPlayer->GetID(), true))418						{419#if defined(MOD_EVENTS_CITY_CONNECTIONS)420							pRouteInfo->m_cRouteState |= HAS_ANY_ROUTE | HAS_INDIRECT_ROUTE;421#else422							pRouteInfo->m_cRouteState |= HAS_ANY_ROUTE | HAS_WATER_ROUTE;423#endif424						}425					}426427#if defined(MOD_EVENTS_CITY_CONNECTIONS)428					if (!(pRouteInfo->m_cRouteState & HAS_ANY_ROUTE) && bCallIndirectEvents)429					{430						// Event to determine if pFirstCity is connected to pSecondCity by an alternative indirect route type431						if (GAMEEVENTINVOKE_TESTANY(GAMEEVENT_CityConnected, m_pPlayer->GetID(), pFirstCity->getX(), pFirstCity->getY(), pSecondCity->getX(), pSecondCity->getY(), false) == GAMEEVENTRETURN_TRUE) {432							pRouteInfo->m_cRouteState |= HAS_ANY_ROUTE | HAS_INDIRECT_ROUTE;433						}434					}435#endif436				}437				else if(iPass == 1)  // check land route438				{439					bool bAnyRouteFound = false;440#if !defined(MOD_EVENTS_CITY_CONNECTIONS)441					bool bBestRouteFound = false;442443					// assuming that there are fewer than 256 players444					int iRouteValue = eBestRouteType + 1;445					int iPathfinderFlags = (iRouteValue << 8);446447					if(pkLandRouteFinder->GeneratePath(pFirstCity->getX(), pFirstCity->getY(), pSecondCity->getX(), pSecondCity->getY(), iPathfinderFlags | m_pPlayer->GetID(), true))448					{449						bAnyRouteFound = true;450						bBestRouteFound = true;451					}452#endif453454#if !defined(MOD_EVENTS_CITY_CONNECTIONS)455					if(!bAnyRouteFound)456#endif457					{458						if(pkLandRouteFinder->GeneratePath(pFirstCity->getX(), pFirstCity->getY(), pSecondCity->getX(), pSecondCity->getY(), MOVE_ANY_ROUTE | m_pPlayer->GetID(), true))459						{460							bAnyRouteFound = true;461						}462					}463464#if defined(MOD_EVENTS_CITY_CONNECTIONS)465					if (!bAnyRouteFound && bCallDirectEvents)466					{467						// Event to determine if pFirstCity is connected to pSecondCity by an alternative direct route type468						if (GAMEEVENTINVOKE_TESTANY(GAMEEVENT_CityConnected, m_pPlayer->GetID(), pFirstCity->getX(), pFirstCity->getY(), pSecondCity->getX(), pSecondCity->getY(), true) == GAMEEVENTRETURN_TRUE) {469							bAnyRouteFound = true;470						}471					}472#endif473474#if !defined(MOD_EVENTS_CITY_CONNECTIONS)475					if(bBestRouteFound)476					{477						pRouteInfo->m_cRouteState |= HAS_BEST_ROUTE | HAS_ANY_ROUTE;478					}479					else if(bAnyRouteFound)480#else481					if(bAnyRouteFound)482#endif483					{484						pRouteInfo->m_cRouteState |= HAS_ANY_ROUTE;485					}486487					// walk through the nodes for plot route info488					if(pFirstCity->isCapital() || pSecondCity->isCapital())489					{490						if(bAnyRouteFound)491						{492							CvPlot* pPlot = NULL;493							CvAStarNode* pNode = pkLandRouteFinder->GetLastNode();494							while(pNode)495							{496								pPlot = GC.getMap().plot(pNode->m_iX, pNode->m_iY);497								ConnectPlotRoute(pPlot);498								pNode = pNode->m_pParent;499							}500501							pFirstCity->SetRouteToCapitalConnected(true);502							pSecondCity->SetRouteToCapitalConnected(true);503						}504					}505				}506			}507		}508	}509}

Calls

Called by