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}