Hooks
static bool BeforeCvCity_init(CvCity* self, int iID, PlayerTypes eOwner, int iX, int iY, bool bBumpUnits, bool bInitialFounding, ReligionTypes eInitialReligion, const char* szName);static void AfterCvCity_init(CvCity* self, int iID, PlayerTypes eOwner, int iX, int iY, bool bBumpUnits, bool bInitialFounding, ReligionTypes eInitialReligion, const char* szName);static void ReplaceCvCity_init(void (*original)(CvCity*, int, PlayerTypes, int, int, bool, bool, ReligionTypes, const char*), CvCity* self, int iID, PlayerTypes eOwner, int iX, int iY, bool bBumpUnits, bool bInitialFounding, ReligionTypes eInitialReligion, const char* szName);CivRegisterBefore<CivHooks::CvCity_init>(host, &BeforeCvCity_init);CivRegisterAfter<CivHooks::CvCity_init>(host, &AfterCvCity_init);CivRegisterReplace<CivHooks::CvCity_init>(host, &ReplaceCvCity_init);
Code
301#if defined(MOD_API_EXTENSIONS)302void CvCity::init(int iID, PlayerTypes eOwner, int iX, int iY, bool bBumpUnits, bool bInitialFounding, ReligionTypes eInitialReligion, const char* szName)303#else304void CvCity::init(int iID, PlayerTypes eOwner, int iX, int iY, bool bBumpUnits, bool bInitialFounding)305#endif306{307 VALIDATE_OBJECT308 //CvPlot* pAdjacentPlot;309 CvPlot* pPlot;310 BuildingTypes eLoopBuilding;311 int iI;312313 pPlot = GC.getMap().plot(iX, iY);314315 //--------------------------------316 // Init saved data317 reset(iID, eOwner, pPlot->getX(), pPlot->getY());318319 CvPlayerAI& owningPlayer = GET_PLAYER(getOwner());320321 //--------------------------------322 // Init non-saved data323324 //--------------------------------325 // Init other game data326 CvString strNewCityName = owningPlayer.getNewCityName();327 setName(strNewCityName.c_str());328329#if !defined(NO_ACHIEVEMENTS)330 if(strcmp(strNewCityName.c_str(), "TXT_KEY_CITY_NAME_LLANFAIRPWLLGWYNGYLL") == 0)331 {332 gDLL->UnlockAchievement(ACHIEVEMENT_XP1_34);333 }334#endif335336 // Plot Ownership337 setEverOwned(getOwner(), true);338339 pPlot->setOwner(getOwner(), m_iID, bBumpUnits);340 // Clear the improvement before the city attaches itself to the plot, else the improvement does not341 // remove the resource allocation from the current owner. This would result in double resource points because342 // the plot has already had setOwner called on it (above), giving the player the resource points.343 pPlot->setImprovementType(NO_IMPROVEMENT);344#if defined(MOD_BUGFIX_MINOR)345#if defined(MOD_EVENTS_TILE_IMPROVEMENTS)346 pPlot->SetImprovementPillaged(false, false);347 pPlot->SetRoutePillaged(false, false);348#else349 pPlot->SetImprovementPillaged(false);350 pPlot->SetRoutePillaged(false);351#endif352#endif353 pPlot->setPlotCity(this);354 pPlot->SetCityPurchaseID(m_iID);355356 int iRange = 1;357#if defined(MOD_CONFIG_GAME_IN_XML)358 iRange = GD_INT_GET(CITY_STARTING_RINGS);359#endif360 for(int iDX = -iRange; iDX <= iRange; iDX++)361 {362 for(int iDY = -iRange; iDY <= iRange; iDY++)363 {364 CvPlot* pLoopPlot = plotXYWithRangeCheck(getX(), getY(), iDX, iDY, iRange);365 if(pLoopPlot != NULL)366 {367 if(pLoopPlot != NULL)368 {369 if(pLoopPlot->getOwner() == NO_PLAYER)370 {371 pLoopPlot->setOwner(getOwner(), m_iID, bBumpUnits);372 }373 if(pLoopPlot->getOwner() == getOwner())374 {375 pLoopPlot->SetCityPurchaseID(m_iID);376 }377 }378 }379 }380 }381382 // this is a list of plot that are owned by the player383 owningPlayer.UpdatePlots();384385#if defined(MOD_GLOBAL_CITY_FOREST_BONUS)386 static BuildTypes eBuildRemoveForest = (BuildTypes)GC.getInfoTypeForString("BUILD_REMOVE_FOREST");387 bool bClearedForest = false;388 FeatureTypes eFeature = pPlot->getFeatureType();389#endif390391#if defined(MOD_GLOBAL_CITY_JUNGLE_BONUS)392 static BuildTypes eBuildRemoveJungle = (BuildTypes)GC.getInfoTypeForString("BUILD_REMOVE_JUNGLE");393 bool bClearedJungle = false;394#if !defined(MOD_GLOBAL_CITY_FOREST_BONUS)395 FeatureTypes eFeature = pPlot->getFeatureType();396#endif397#endif398399 //SCRIPT call ' bool citiesDestroyFeatures(iX, iY);'400 if(pPlot->getFeatureType() != NO_FEATURE)401 {402#if defined(MOD_GLOBAL_CITY_FOREST_BONUS)403 // Only for major civs building on a forest404 if(MOD_GLOBAL_CITY_FOREST_BONUS && eBuildRemoveForest != -1 && !owningPlayer.isMinorCiv() && eFeature == FEATURE_FOREST)405 {406 // Don't do this for the AI capitals - it's just too much of an initial boost!407 if (owningPlayer.isHuman() || owningPlayer.getCapitalCity() != NULL) {408 TechTypes iRequiredTech = (TechTypes) gCustomMods.getOption("GLOBAL_CITY_FOREST_BONUS_TECH", -1);409 bClearedForest = (iRequiredTech == -1 || GET_TEAM(owningPlayer.getTeam()).GetTeamTechs()->HasTech(iRequiredTech));410 }411 }412#endif413414#if defined(MOD_GLOBAL_CITY_JUNGLE_BONUS)415 // Only for major civs building on a jungle416 if(MOD_GLOBAL_CITY_JUNGLE_BONUS && eBuildRemoveJungle != -1 && !owningPlayer.isMinorCiv() && eFeature == FEATURE_JUNGLE)417 {418 // Don't do this for the AI capitals - it's just too much of an initial boost!419 if (owningPlayer.isHuman() || owningPlayer.getCapitalCity() != NULL) {420 TechTypes iRequiredTech = (TechTypes) gCustomMods.getOption("GLOBAL_CITY_JUNGLE_BONUS_TECH", -1);421 bClearedJungle = (iRequiredTech == -1 || GET_TEAM(owningPlayer.getTeam()).GetTeamTechs()->HasTech(iRequiredTech));422 }423 }424#endif425 426 pPlot->setFeatureType(NO_FEATURE);427 }428429 // wipe out dig sites430 ResourceTypes eArtifactResourceType = static_cast<ResourceTypes>(GC.getARTIFACT_RESOURCE());431 ResourceTypes eHiddenArtifactResourceType = static_cast<ResourceTypes>(GC.getHIDDEN_ARTIFACT_RESOURCE());432 if (pPlot->getResourceType() == eArtifactResourceType || pPlot->getResourceType() == eHiddenArtifactResourceType)433 {434 pPlot->setResourceType(NO_RESOURCE, 0);435 pPlot->ClearArchaeologicalRecord();436 }437438 setupGraphical();439440 pPlot->updateCityRoute();441442 for(iI = 0; iI < MAX_TEAMS; iI++)443 {444 if(GET_TEAM((TeamTypes)iI).isAlive())445 {446 if(pPlot->isVisible(((TeamTypes)iI)))447 {448 setRevealed(((TeamTypes)iI), true);449 }450 }451 }452453 int iNumBuildingInfos = GC.getNumBuildingInfos();454 for(iI = 0; iI < iNumBuildingInfos; iI++)455 {456 if(owningPlayer.isBuildingFree((BuildingTypes)iI))457 {458 if(isValidBuildingLocation((BuildingTypes)iI))459 {460 m_pCityBuildings->SetNumFreeBuilding(((BuildingTypes)iI), 1);461 }462 }463 }464465 area()->changeCitiesPerPlayer(getOwner(), 1);466467 GET_TEAM(getTeam()).changeNumCities(1);468469 GC.getGame().changeNumCities(1);470 // Tell the city manager now as well.471 CvCityManager::OnCityCreated(this);472473 int iGameTurn = GC.getGame().getGameTurn();474 setGameTurnFounded(iGameTurn);475 setGameTurnAcquired(iGameTurn);476 setGameTurnLastExpanded(iGameTurn);477478#if defined(MOD_GLOBAL_CITY_WORKING)479 GC.getMap().updateWorkingCity(pPlot,getWorkPlotDistance()*2);480#else 481 GC.getMap().updateWorkingCity(pPlot,NUM_CITY_RINGS*2);482#endif483 GetCityCitizens()->DoFoundCity();484485 // Default starting population486 changePopulation(GC.getINITIAL_CITY_POPULATION() + GC.getGame().getStartEraInfo().getFreePopulation());487 // Free population from things (e.g. Policies)488 changePopulation(GET_PLAYER(getOwner()).GetNewCityExtraPopulation());489490#if defined(MOD_API_EXTENSIONS)491 // We do this here as changePopulation() sends a game event we may have caught to do funky renaming things492 if (szName) {493 setName(szName);494 }495#endif496497 // Free food from things (e.g. Policies)498 int iFreeFood = growthThreshold() * GET_PLAYER(getOwner()).GetFreeFoodBox();499 changeFoodTimes100(iFreeFood);500 501 if (bInitialFounding)502 {503 owningPlayer.setFoundedFirstCity(true);504 owningPlayer.ChangeNumCitiesFounded(1);505506 // Free resources under city?507 for(int i = 0; i < GC.getNumResourceInfos(); i++)508 {509 ResourceTypes eResource = (ResourceTypes)i;510 FreeResourceXCities freeResource = owningPlayer.GetPlayerTraits()->GetFreeResourceXCities(eResource);511512 if(freeResource.m_iResourceQuantity > 0)513 {514 if(owningPlayer.GetNumCitiesFounded() <= freeResource.m_iNumCities)515 {516 plot()->setResourceType(NO_RESOURCE, 0);517 plot()->setResourceType(eResource, freeResource.m_iResourceQuantity);518 }519 }520 }521522 owningPlayer.GetPlayerTraits()->AddUniqueLuxuries(this);523 if(owningPlayer.isMinorCiv())524 {525 owningPlayer.GetMinorCivAI()->DoAddStartingResources(plot());526 }527 }528529 // make sure that all the team members get the city connection update530 for(int i = 0; i < MAX_PLAYERS; i++)531 {532 PlayerTypes ePlayer = (PlayerTypes)i;533 if(GET_PLAYER(ePlayer).getTeam() == owningPlayer.getTeam())534 {535 GET_PLAYER(ePlayer).GetCityConnections()->Update();536 }537 }538 owningPlayer.DoUpdateHappiness();539540 // Policy changes541 PolicyTypes ePolicy;542 for(int iPoliciesLoop = 0; iPoliciesLoop < GC.getNumPolicyInfos(); iPoliciesLoop++)543 {544 ePolicy = (PolicyTypes) iPoliciesLoop;545546 if(owningPlayer.GetPlayerPolicies()->HasPolicy(ePolicy) && !owningPlayer.GetPlayerPolicies()->IsPolicyBlocked(ePolicy))547 {548 // Free Culture-per-turn in every City from Policies549 ChangeJONSCulturePerTurnFromPolicies(GC.getPolicyInfo(ePolicy)->GetCulturePerCity());550 }551 }552553 // Add Resource Quantity to total554 if(plot()->getResourceType() != NO_RESOURCE)555 {556 if(GET_TEAM(getTeam()).GetTeamTechs()->HasTech((TechTypes) GC.getResourceInfo(plot()->getResourceType())->getTechCityTrade()))557 {558 owningPlayer.changeNumResourceTotal(plot()->getResourceType(), plot()->getNumResourceForPlayer(getOwner()));559 }560 }561562 CvPlot* pLoopPlot;563564 // We may need to link Resources to this City if it's constructed within previous borders and the Resources were too far away for another City to link to565#if defined(MOD_GLOBAL_CITY_WORKING)566 for(int iJ = 0; iJ < GetNumWorkablePlots(); iJ++)567#else568 for(int iJ = 0; iJ < NUM_CITY_PLOTS; iJ++)569#endif570 {571 pLoopPlot = plotCity(getX(), getY(), iJ);572573 if(pLoopPlot != NULL)574 {575 if(pLoopPlot->getOwner() == getOwner())576 {577 if(pLoopPlot->getResourceType() != NO_RESOURCE)578 {579 // Is this Resource as of yet unlinked?580 if(pLoopPlot->GetResourceLinkedCity() == NULL)581 {582 pLoopPlot->DoFindCityToLinkResourceTo();583 }584 }585 }586 }587 }588589 PlayerTypes ePlayer;590591 // Update Proximity between this Player and all others592 for(int iPlayerLoop = 0; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)593 {594 ePlayer = (PlayerTypes) iPlayerLoop;595596 if(ePlayer != getOwner())597 {598 if(GET_PLAYER(ePlayer).isAlive())599 {600 // Players do NOT have to know one another in order to calculate proximity. Having this info available (even whey they haven't met) can be useful601 owningPlayer.DoUpdateProximityToPlayer(ePlayer);602 GET_PLAYER(ePlayer).DoUpdateProximityToPlayer(getOwner());603 }604 }605 }606607 // Free Buildings in the first City608 CvCivilizationInfo& thisCiv = getCivilizationInfo();609 if(GC.getGame().isFinalInitialized())610 {611 if(owningPlayer.getNumCities() == 1)612 {613#if defined(MOD_EVENTS_CITY_CAPITAL)614 int eCapitalBuilding = thisCiv.getCivilizationBuildings(GC.getCAPITAL_BUILDINGCLASS());615#endif616 617 for(iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)618 {619 CvBuildingClassInfo* pkBuildingClassInfo = GC.getBuildingClassInfo((BuildingClassTypes)iI);620 if(!pkBuildingClassInfo)621 {622 continue;623 }624625 if(thisCiv.isCivilizationFreeBuildingClass(iI))626 {627 eLoopBuilding = ((BuildingTypes)(thisCiv.getCivilizationBuildings(iI)));628629 if(eLoopBuilding != NO_BUILDING)630 {631 m_pCityBuildings->SetNumRealBuilding(eLoopBuilding, true);632633#if defined(MOD_EVENTS_CITY_CAPITAL)634 if (iI == eCapitalBuilding && MOD_EVENTS_CITY_CAPITAL) {635 GAMEEVENTINVOKE_HOOK(GAMEEVENT_CapitalChanged, getOwner(), GetID(), -1);636 }637#endif638 }639 }640 }641642 if(!isHuman())643 {644 changeOverflowProduction(GC.getINITIAL_AI_CITY_PRODUCTION());645#if defined(ACHIEVEMENT_HACKS)646 } else {647 CvAchievementUnlocker::UnlockFromDatabase();648#endif649 }650 }651 }652653 // How long before this City picks a Resource to demand?654 DoSeedResourceDemandedCountdown();655656 // Update City Strength657 updateStrengthValue();658659 // Update Unit Maintenance for the player660 CvPlayer& kPlayer = GET_PLAYER(getOwner());661 kPlayer.UpdateUnitProductionMaintenanceMod();662663 // Spread a pantheon here if one is active664 CvPlayerReligions* pReligions = kPlayer.GetReligions();665 if(pReligions->HasCreatedPantheon() && !pReligions->HasCreatedReligion())666 {667 GetCityReligions()->AddReligiousPressure(FOLLOWER_CHANGE_PANTHEON_FOUNDED, RELIGION_PANTHEON, GC.getRELIGION_ATHEISM_PRESSURE_PER_POP() * getPopulation() * 2);668 }669 670#if defined(MOD_API_EXTENSIONS)671 if (bInitialFounding) {672 if (eInitialReligion != NO_RELIGION) {673 // Spread an initial religion here if one was given674 GetCityReligions()->AdoptReligionFully(eInitialReligion);675 }676677#if defined(MOD_RELIGION_LOCAL_RELIGIONS)678 else if (MOD_RELIGION_LOCAL_RELIGIONS) {679 // Spread a local religion here if one is active680 if(pReligions->HasCreatedReligion() && GC.getReligionInfo(pReligions->GetReligionCreatedByPlayer())->IsLocalReligion()) {681 GetCityReligions()->AdoptReligionFully(pReligions->GetReligionCreatedByPlayer());682 }683 }684#endif685 }686#endif687688 // A new City might change our victory progress689 GET_TEAM(getTeam()).DoTestSmallAwards();690691 DLLUI->setDirty(NationalBorders_DIRTY_BIT, true);692693 // Garrisoned?694 if (GetGarrisonedUnit())695 {696 ChangeJONSCulturePerTurnFromPolicies(GET_PLAYER(getOwner()).GetPlayerPolicies()->GetNumericModifier(POLICYMOD_CULTURE_FROM_GARRISON));697 }698699#if defined(MOD_GLOBAL_CITY_FOREST_BONUS)700 if (bClearedForest) {701 int iProduction;702703 // Base value704 if (GET_PLAYER(getOwner()).GetAllFeatureProduction() > 0) {705 iProduction = GET_PLAYER(getOwner()).GetAllFeatureProduction();706 } else {707 iProduction = GC.getBuildInfo(eBuildRemoveForest)->getFeatureProduction(FEATURE_FOREST);708 }709710 iProduction *= std::max(0, (GET_PLAYER(getOwner()).getFeatureProductionModifier() + 100));711 iProduction /= 100;712713 iProduction *= GC.getGame().getGameSpeedInfo().getFeatureProductionPercent();714 iProduction /= 100;715716 if (iProduction > 0) {717 // Make the production higher than a "ring-1 chop"718 iProduction *= gCustomMods.getOption("GLOBAL_CITY_FOREST_BONUS_PERCENT", 125);719 iProduction /= 100;720721 changeFeatureProduction(iProduction);722 CUSTOMLOG("Founding of %s on a forest created %d initial production", getName().GetCString(), iProduction);723724 if (getOwner() == GC.getGame().getActivePlayer()) {725 CvString strBuffer = GetLocalizedText("TXT_KEY_MISC_CLEARING_FEATURE_RESOURCE", GC.getFeatureInfo(eFeature)->GetTextKey(), iProduction, getNameKey());726 GC.GetEngineUserInterface()->AddCityMessage(0, GetIDInfo(), getOwner(), false, GC.getEVENT_MESSAGE_TIME(), strBuffer);727 }728 }729 }730#endif731732#if defined(MOD_GLOBAL_CITY_JUNGLE_BONUS)733 if (bClearedJungle) {734 int iProduction;735736 // Base value737 if (GET_PLAYER(getOwner()).GetAllFeatureProduction() > 0) {738 iProduction = GET_PLAYER(getOwner()).GetAllFeatureProduction();739 } else {740 iProduction = GC.getBuildInfo(eBuildRemoveJungle)->getFeatureProduction(FEATURE_JUNGLE);741 }742743 iProduction *= std::max(0, (GET_PLAYER(getOwner()).getFeatureProductionModifier() + 100));744 iProduction /= 100;745746 iProduction *= GC.getGame().getGameSpeedInfo().getFeatureProductionPercent();747 iProduction /= 100;748749 if (iProduction > 0) {750 // Make the production higher than a "ring-1 chop"751 iProduction *= gCustomMods.getOption("GLOBAL_CITY_JUNGLE_BONUS_PERCENT", 125);752 iProduction /= 100;753754 changeFeatureProduction(iProduction);755 CUSTOMLOG("Founding of %s on a jungle created %d initial production", getName().GetCString(), iProduction);756757 if (getOwner() == GC.getGame().getActivePlayer()) {758 CvString strBuffer = GetLocalizedText("TXT_KEY_MISC_CLEARING_FEATURE_RESOURCE", GC.getFeatureInfo(eFeature)->GetTextKey(), iProduction, getNameKey());759 GC.GetEngineUserInterface()->AddCityMessage(0, GetIDInfo(), getOwner(), false, GC.getEVENT_MESSAGE_TIME(), strBuffer);760 }761 }762 }763#endif764765 AI_init();766767 if (GC.getGame().getGameTurn() == 0)768 {769 chooseProduction();770 }771}