Code
970bool CvWorldBuilderMapLoader::InitMap()971{972 CvMap& kMap = GC.getMap();973974 FAssertMsg(975 sg_kSave.GetWidth() == kMap.getGridWidth() &&976 sg_kSave.GetHeight() == kMap.getGridHeight(),977 "Save wrong size");978979 OutputDebugStringA("Setting up players...\n");980981 const uint uiPlayerCount = std::min(sg_kSave.GetPlayerCount(), (byte)MAX_CIV_PLAYERS);982 for(uint i = 0; i < uiPlayerCount; ++i)983 {984 const PlayerTypes ePlayer = (PlayerTypes)i;985 CvPlayer& kGameplayPlayer = GET_PLAYER(ePlayer);986 const CvWorldBuilderMap::Player& kSavedPlayer = sg_kSave.GetPlayer(i);987988 if(kSavedPlayer.m_uiStartX < sg_kSave.GetWidth() &&989 kSavedPlayer.m_uiStartY < sg_kSave.GetHeight())990 {991 CvPlot* pkStartingPlot = kMap.plot(kSavedPlayer.m_uiStartX, kSavedPlayer.m_uiStartY);992 kGameplayPlayer.setStartingPlot(pkStartingPlot);993 }994 }995996 const uint uiCityStateCount = std::min(sg_kSave.GetCityStateCount(), (byte)MAX_MINOR_CIVS);997 for(uint i = 0; i < uiCityStateCount; ++i)998 {999 const PlayerTypes ePlayer = (PlayerTypes)(i + MAX_MAJOR_CIVS);1000 CvPlayer& kGameplayPlayer = GET_PLAYER(ePlayer);1001 const CvWorldBuilderMap::Player& kSavedPlayer = sg_kSave.GetCityState(i);10021003 if(kSavedPlayer.m_uiStartX < sg_kSave.GetWidth() &&1004 kSavedPlayer.m_uiStartY < sg_kSave.GetHeight())1005 {1006 CvPlot* pkStartingPlot = kMap.plot(kSavedPlayer.m_uiStartX, kSavedPlayer.m_uiStartY);1007 kGameplayPlayer.setStartingPlot(pkStartingPlot);1008 }1009 }10101011 const uint uiTeamCount = std::min(sg_kSave.GetTeamCount(), (byte)MAX_TEAMS);10121013 // HACK: Call SetInitialItems early. It has to be called later too :_(1014 // This is because of what is essentially a circular dependency. Techs1015 // need to be initialized before units are created (for the embarkation1016 // promotion among other things). However, units must be created before1017 // CvGame sets up the initial player state otherwise a scenario player may1018 // be given starting units they don't need and shouldn't have. Unfortunately1019 // this also does stuff like reset starting techs. Therefore SetInitialItems1020 // must be called AGAIN to put the player state back to where it should be.1021 // This second call is done from CvInitMgr::GameCoreNew. You may be tempted to1022 // remove this hack but be very careful if you do and test thoroughly with scenario saves.1023 SetInitialItems(true);10241025 FFastVector<CvPlayer*> kMajorCivs;1026 FFastVector<CvPlayer*> kMinorCivs;1027 for(uint i = 0; i < MAX_CIV_PLAYERS; ++i)1028 {1029 PlayerTypes ePlayer = PlayerTypes(i);1030 CvPlayer& kPlayer = GET_PLAYER(ePlayer);1031 if(kPlayer.isAlive() && kPlayer.getStartingPlot() == NULL)1032 {1033 if(kPlayer.isMinorCiv())1034 kMinorCivs.push_back(&kPlayer);1035 else1036 kMajorCivs.push_back(&kPlayer);1037 }1038 }10391040 uint uiMajorCivsPlaced = 0;1041 uint uiMinorCivsPlaced = 0;10421043 OutputDebugStringA("Setting up map...\n");1044 uint uiPlotCount = sg_kSave.GetWidth() * sg_kSave.GetHeight();1045 for(uint i = 0; i < uiPlotCount; ++i)1046 {1047 const CvWorldBuilderMap::PlotMapData& kPlotData = sg_kSave.GetPlotData(i);1048 CvPlot* pkPlot = kMap.plotByIndex(i);1049 FAssertMsg(pkPlot, "Missing CvPlot for this location");1050 if(pkPlot == NULL) continue;10511052 pkPlot->setTerrainType((TerrainTypes)kPlotData.GetTerrainType(), false, false);10531054 CvWorldBuilderMap::PlotMapData::PlotHeight ePlotHeight = kPlotData.GetPlotHeight();1055 if(ePlotHeight != CvWorldBuilderMap::PlotMapData::FLAT_TERRAIN)1056 {1057 if(ePlotHeight == CvWorldBuilderMap::PlotMapData::HILLS)1058 pkPlot->setPlotType(PLOT_HILLS);1059 else1060 pkPlot->setPlotType(PLOT_MOUNTAIN);1061 }10621063 if(kPlotData.GetResourceType() != CvWorldBuilderMap::PlotMapData::InvalidResource)1064 {1065 int iResourceAmount = kPlotData.GetResourceAmount();1066 if(iResourceAmount <= 0)1067 iResourceAmount = 1;10681069 pkPlot->setResourceType((ResourceTypes)kPlotData.GetResourceType(), iResourceAmount);1070 }10711072 if(kPlotData.GetFeatureType() != CvWorldBuilderMap::PlotMapData::InvalidFeature)1073 pkPlot->setFeatureType((FeatureTypes)kPlotData.GetFeatureType());10741075 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::W_OF_RIVER))1076 {1077 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::RIVER_FLOW_S))1078 pkPlot->setWOfRiver(true, FLOWDIRECTION_SOUTH);1079 else1080 pkPlot->setWOfRiver(true, FLOWDIRECTION_NORTH);1081 }10821083 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::NW_OF_RIVER))1084 {1085 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::RIVER_FLOW_NE))1086 pkPlot->setNWOfRiver(true, FLOWDIRECTION_NORTHEAST);1087 else1088 pkPlot->setNWOfRiver(true, FLOWDIRECTION_SOUTHWEST);1089 }10901091 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::NE_OF_RIVER))1092 {1093 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::RIVER_FLOW_NW))1094 pkPlot->setNEOfRiver(true, FLOWDIRECTION_NORTHWEST);1095 else1096 pkPlot->setNEOfRiver(true, FLOWDIRECTION_SOUTHEAST);1097 }10981099 if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::START_POS_MAJOR))1100 {1101 if(uiMajorCivsPlaced < kMajorCivs.size())1102 {1103 kMajorCivs[uiMajorCivsPlaced]->setStartingPlot(pkPlot);1104 uiMajorCivsPlaced++;1105 }1106 }1107 else if(kPlotData.GetFlag(CvWorldBuilderMap::PlotMapData::START_POS_MINOR))1108 {1109 if(uiMinorCivsPlaced < kMinorCivs.size())1110 {1111 kMinorCivs[uiMinorCivsPlaced]->setStartingPlot(pkPlot);1112 uiMinorCivsPlaced++;1113 }1114 }11151116 pkPlot->SetContinentType(kPlotData.GetContinentType());1117 }11181119 OutputDebugStringA("Calculating Areas...\n");11201121 kMap.recalculateAreas();11221123 OutputDebugStringA("Adding Scenario Elements...\n");11241125 GC.getGame().GetTacticalAnalysisMap()->Init(GC.getMap().numPlots());11261127 // Init Diplomacy1128 for(uint uiTeam1 = 0; uiTeam1 < uiTeamCount; ++uiTeam1)1129 {1130 for(uint uiTeam2 = uiTeam1 + 1; uiTeam2 < uiTeamCount; ++uiTeam2)1131 {1132 const TeamTypes eTeam1 = (TeamTypes)uiTeam1;1133 const TeamTypes eTeam2 = (TeamTypes)uiTeam2;1134 CvTeam& kTeam1 = GET_TEAM(eTeam1);1135 CvTeam& kTeam2 = GET_TEAM(eTeam2);11361137 if(sg_kSave.m_kTeamsInContact.Get(uiTeam1, uiTeam2))1138 kTeam1.meet(eTeam2, true);11391140 if(sg_kSave.m_kTeamsAtWar.Get(uiTeam1, uiTeam2))1141 {1142#if defined(MOD_EVENTS_WAR_AND_PEACE)1143 kTeam1.setAtWar(eTeam2, true, true);1144 kTeam2.setAtWar(eTeam1, true, true);1145#else1146 kTeam1.setAtWar(eTeam2, true);1147 kTeam2.setAtWar(eTeam1, true);1148#endif1149 }11501151 if(sg_kSave.m_kTeamsAtPermanentWarOrPeace.Get(uiTeam1, uiTeam2))1152 {1153 kTeam1.setPermanentWarPeace(eTeam2, true);1154 kTeam2.setPermanentWarPeace(eTeam1, true);1155 }11561157 if(sg_kSave.m_kTeamsSharingOpenBorders.Get(uiTeam1, uiTeam2))1158 {1159 kTeam1.SetAllowsOpenBordersToTeam(eTeam2, true);1160 kTeam2.SetAllowsOpenBordersToTeam(eTeam1, true);1161 }11621163 if(sg_kSave.m_kTeamsSharingDefensivePacts.Get(uiTeam1, uiTeam2))1164 {1165 kTeam1.SetHasDefensivePact(eTeam2, true);1166 kTeam2.SetHasDefensivePact(eTeam1, true);1167 }1168 }1169 }11701171 // Init City State Relationships1172 for(uint uiCityState = 0; uiCityState < uiCityStateCount; ++uiCityState)1173 {1174 const PlayerTypes eCityStatePlayer = GetPlayerType((byte)(uiCityState + CvWorldBuilderMap::MaxPlayers));1175 if(eCityStatePlayer != NO_PLAYER)1176 {1177 CvPlayer& kCityState = GET_PLAYER(eCityStatePlayer);1178 CvMinorCivAI* pkAI = kCityState.GetMinorCivAI();1179 FAssertMsg(pkAI, "Cannot set minor civ influence. Missing CvMinorCivAI.");1180 if(pkAI != NULL)1181 {1182 for(uint uiMajorCiv = 0; uiMajorCiv < uiPlayerCount; ++uiMajorCiv)1183 {1184 const PlayerTypes eMajorCivPlayer = GetPlayerType((byte)uiMajorCiv);1185 if(eMajorCivPlayer != NO_PLAYER)1186 {1187 pkAI->SetFriendshipWithMajor(eMajorCivPlayer, sg_kSave.m_aiCityStateInfluence[uiMajorCiv][uiCityState]);1188 }1189 }1190 }1191 }1192 }11931194 // Scenario elements must come after areas have been calculated1195 for(uint i = 0; i < uiPlotCount; ++i)1196 {1197 const CvWorldBuilderMap::PlotScenarioData& kPlotData = sg_kSave.GetPlotScenarioData(i);1198 CvPlot* pkPlot = kMap.plotByIndex(i);1199 FAssertMsg(pkPlot, "Missing CvPlot for this location");1200 if(pkPlot == NULL) continue;12011202 const int iPlotX = pkPlot->getX();1203 const int iPlotY = pkPlot->getY();12041205 const byte byNaturalWonder = sg_kSave.GetPlotData(i).GetNaturalWonderType();1206 if(byNaturalWonder != CvWorldBuilderMap::PlotMapData::InvalidNaturalWonder)1207 pkPlot->setFeatureType((FeatureTypes)byNaturalWonder);12081209 if(kPlotData.m_byImprovement != CvWorldBuilderMap::PlotScenarioData::InvalidImprovement)1210 pkPlot->setImprovementType((ImprovementTypes)kPlotData.m_byImprovement);12111212 if(kPlotData.m_byRoute != CvWorldBuilderMap::PlotScenarioData::InvalidImprovement)1213 {1214 RouteTypes eRoute;1215 if(kPlotData.m_byRoute == 0)1216 eRoute = ROUTE_ROAD;1217 else1218 eRoute = ROUTE_RAILROAD;12191220 pkPlot->setRouteType(eRoute);12211222 const PlayerTypes eOwner = GetPlayerType(kPlotData.m_byRouteOwner);1223 if(eOwner != NO_PLAYER && !pkPlot->isOwned())1224 {1225 // Mark the player as responsible for this route and update the treasury1226 CvTreasury* pkTreasury = GET_PLAYER(eOwner).GetTreasury();1227 const CvRouteInfo* pkRouteInfo = GC.getRouteInfo(eRoute);1228 if(pkTreasury != NULL && pkRouteInfo != NULL)1229 {1230 if(pkPlot->MustPayMaintenanceHere(eOwner))1231 {1232 pkTreasury->ChangeBaseImprovementGoldMaintenance(pkRouteInfo->GetGoldMaintenance());1233 }1234 pkPlot->SetPlayerResponsibleForRoute(eOwner);1235 }1236 }1237 }12381239 const CvWorldBuilderMap::City* pkCity = sg_kSave.m_kCities[kPlotData.m_hCity];1240 if(pkCity != NULL)1241 {1242 SetupCity(*pkCity, iPlotX, iPlotY);1243 }12441245 // Note - All calls to SetupUnit for this plot must come after SetupCity for this plot.1246 // This is because of garrisoned units that need the city to be there first.1247 for(const CvWorldBuilderMap::Unit* pkUnit = sg_kSave.m_kUnits[kPlotData.m_hUnitStack];1248 pkUnit != NULL;1249 pkUnit = sg_kSave.m_kUnits[pkUnit->m_hStackedUnit])1250 {1251 SetupUnit(*pkUnit, iPlotX, iPlotY);1252 }12531254 for(uint uiTeam = 0; uiTeam < uiTeamCount; ++uiTeam)1255 {1256 if(sg_kSave.GetVisibility(iPlotX, iPlotY, uiTeam))1257 pkPlot->setRevealed((TeamTypes)uiTeam, true);1258 }1259 }12601261 // Set culture. This must come after all cities have been added.1262 for(uint i = 0; i < uiPlotCount; ++i)1263 {1264 const CvWorldBuilderMap::PlotScenarioData& kPlotData = sg_kSave.GetPlotScenarioData(i);1265 CvPlot* pkPlot = kMap.plotByIndex(i);1266 FAssertMsg(pkPlot, "Missing CvPlot for this location");1267 if(pkPlot == NULL) continue;12681269 const PlayerTypes eOwner = GetPlayerType(kPlotData.m_byCulture);1270 if(eOwner != NO_PLAYER)1271 {1272 int iCityID = 0;1273 const CvCity* pkCity = FindClosestCity(eOwner, *pkPlot);1274 if(pkCity) iCityID = pkCity->GetID();1275 pkPlot->setOwner(eOwner, iCityID);1276 }1277 }12781279 OutputDebugStringA("Map Load Success!\n");12801281 return true;1282}