int CvProcessProductionAI::CheckProcessBuildSanity(ProcessTypes eProcess, int iTempWeight, int iNumBuildables, int iGPT) { CvProcessInfo* pProcess = GC.getProcessInfo(eProcess); if(!pProcess) { return 0; } if(iTempWeight == 0) return 0; if(iNumBuildables > 0) { if(iTempWeight > 300) { iTempWeight = 300; } } else { if(iTempWeight > 400) { iTempWeight = 400; } } CvPlayerAI& kPlayer = GET_PLAYER(m_pCity->getOwner()); int iModifier = 0; //Bonus % additive. All values below will be added to this and combined with real value at end. int iBonus = 0; ////// //WAR /////// //Fewer processes while at war. int iNumWar = kPlayer.GetMilitaryAI()->GetNumberCivsAtWarWith(false); if(iNumWar > 0) { iBonus -= (iNumWar * 50); if(kPlayer.getNumCities() > 1 && m_pCity->GetThreatCriteria() != -1) { //More cities = more threat. int iThreat = (kPlayer.getNumCities() - m_pCity->GetThreatCriteria()) * 25; if(iThreat > 0) { iBonus -= iThreat; } } if(m_pCity->IsBastion()) { iBonus -= 100; } if(m_pCity->IsBlockaded(true)) { iBonus -= 100; } if(m_pCity->IsBlockadedWaterAndLand()) { iBonus -= 100; } } //Tiny army? Eek! if(kPlayer.getNumMilitaryUnits() <= (kPlayer.getNumCities() * 2)) { iBonus -= 100; } MilitaryAIStrategyTypes eBuildCriticalDefenses = (MilitaryAIStrategyTypes) GC.getInfoTypeForString("MILITARYAISTRATEGY_LOSING_WARS"); // scale based on flavor and world size if(eBuildCriticalDefenses != NO_MILITARYAISTRATEGY && kPlayer.GetMilitaryAI()->IsUsingStrategy(eBuildCriticalDefenses)) { iModifier -= 50; } EconomicAIStrategyTypes eStrategyLosingMoney = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_LOSING_MONEY"); EconomicAIStrategyTypes eStrategyCultureGS = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_GS_CULTURE"); AICityStrategyTypes eNeedFood = (AICityStrategyTypes) GC.getInfoTypeForString("AICITYSTRATEGY_NEED_IMPROVEMENT_FOOD"); AICityStrategyTypes eNeedFoodNaval = (AICityStrategyTypes) GC.getInfoTypeForString("AICITYSTRATEGY_NEED_NAVAL_GROWTH"); EconomicAIStrategyTypes eGrowCrazy = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_GROW_LIKE_CRAZY"); AICityStrategyTypes eScienceCap = (AICityStrategyTypes) GC.getInfoTypeForString("AICITYSTRATEGY_KEY_SCIENCE_CITY"); //Yield value. //Base value of production. iModifier += (m_pCity->getYieldRate(YIELD_PRODUCTION, false) / 5); for(int iYield = 0; iYield < NUM_YIELD_TYPES; iYield++) { YieldTypes eYield = (YieldTypes)iYield; if(eYield == NO_YIELD) continue; if(m_pCity->GetCityStrategyAI()->GetMostDeficientYield() == eYield) { iModifier += 50; } if(pProcess->getProductionToYieldModifier(eYield) > 0) { switch(eYield) { case YIELD_GOLD: { if(MOD_BALANCE_CORE_HAPPINESS) { if(m_pCity->getUnhappinessFromGold() > 0) { iModifier += (m_pCity->getUnhappinessFromGold() * 2); } } if(eStrategyLosingMoney != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyLosingMoney)) { iModifier += 25; } } break; case YIELD_CULTURE: { if(MOD_BALANCE_CORE_HAPPINESS) { if(m_pCity->getUnhappinessFromCulture() > 0) { iModifier += (m_pCity->getUnhappinessFromCulture() * 2); } } if(eStrategyCultureGS != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyCultureGS)) { iModifier += 25; } } break; case YIELD_SCIENCE: { if(MOD_BALANCE_CORE_HAPPINESS) { if(m_pCity->getUnhappinessFromScience() > 0) { iModifier += (m_pCity->getUnhappinessFromScience() * 2); } } if(eScienceCap != NO_AICITYSTRATEGY && m_pCity->GetCityStrategyAI()->IsUsingCityStrategy(eScienceCap)) { iModifier += 25; } } break; case YIELD_FOOD: { if(m_pCity->GetCityCitizens()->IsForcedAvoidGrowth()) return 0; int iExcessFoodTimes100 = m_pCity->getYieldRateTimes100(YIELD_FOOD, false) - (m_pCity->foodConsumption() * 100); if (iExcessFoodTimes100 < 0) { iModifier += 25; } if(MOD_BALANCE_CORE_HAPPINESS) { if(m_pCity->getUnhappinessFromStarving() > 0) { iModifier += (m_pCity->getUnhappinessFromStarving() * 5); } } if(eGrowCrazy != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eGrowCrazy)) { iModifier += 15; } if(eNeedFood != NO_AICITYSTRATEGY && m_pCity->GetCityStrategyAI()->IsUsingCityStrategy(eNeedFood)) { iModifier += 15; } if(eNeedFoodNaval != NO_AICITYSTRATEGY && m_pCity->GetCityStrategyAI()->IsUsingCityStrategy(eNeedFoodNaval)) { iModifier += 10; } } break; } } } for(int iI = 0; iI < GC.getNumLeagueProjectInfos(); iI++) { LeagueProjectTypes eLeagueProject = (LeagueProjectTypes) iI; CvLeagueProjectEntry* pInfo = GC.getLeagueProjectInfo(eLeagueProject); if (pInfo && pInfo->GetProcess() == eProcess) { if (GC.getGame().GetGameLeagues()->CanContributeToLeagueProject(m_pCity->getOwner(), eLeagueProject)) { FStaticVector<LeagueProjectRewardTypes, 4, true, c_eCiv5GameplayDLL> veRewards; veRewards.push_back(pInfo->GetRewardTier3()); veRewards.push_back(pInfo->GetRewardTier2()); veRewards.push_back(pInfo->GetRewardTier1()); for (uint i = 0; i < veRewards.size(); i++) { CvLeagueProjectRewardEntry* pRewardInfo = GC.getLeagueProjectRewardInfo(veRewards[i]); CvAssert(pRewardInfo); if (!pRewardInfo) continue; // Free Building in Capital if (pRewardInfo->GetBuilding() != NO_BUILDING) { CvBuildingEntry* pBuildingInfo = GC.getBuildingInfo(pRewardInfo->GetBuilding()); if(pBuildingInfo) { int iValue = 1000; if(kPlayer.getCapitalCity() != NULL) { iValue = kPlayer.getCapitalCity()->GetCityStrategyAI()->GetBuildingProductionAI()->CheckBuildingBuildSanity(pRewardInfo->GetBuilding(), iValue, 5, 5, 1); iModifier += iValue; } else { iModifier += m_pCity->GetCityStrategyAI()->GetBuildingProductionAI()->GetWeight(pRewardInfo->GetBuilding()); } } } // Happiness if (pRewardInfo->GetHappiness() != 0) { iModifier += pRewardInfo->GetHappiness() * (50 - kPlayer.GetHappiness()); } // Free Social Policy if (pRewardInfo->GetFreeSocialPolicies() > 0) { iModifier += (kPlayer.GetPlayerPolicies()->GetNumPoliciesOwned() * 20); } EconomicAIStrategyTypes eStrategyCultureGS = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_GS_CULTURE"); // Temporary Culture Modifier if (pRewardInfo->GetCultureBonusTurns() > 0) { if(eStrategyCultureGS != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyCultureGS)) { iModifier += 250; } } // Temporary Tourism Modifier if (pRewardInfo->GetTourismBonusTurns() > 0) { if(eStrategyCultureGS != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyCultureGS)) { iModifier += 250; } } // Golden Age Points if (pRewardInfo->GetGoldenAgePoints() > 0) { if(kPlayer.GetPlayerTraits()->GetGoldenAgeDurationModifier() > 0) { iModifier += (pRewardInfo->GetGoldenAgePoints() + kPlayer.GetPlayerTraits()->GetGoldenAgeDurationModifier()) * 5; } else { iModifier += (pRewardInfo->GetGoldenAgePoints() + kPlayer.getGoldenAgeModifier()) * 5; } } // City-State Influence Boost //antonjs: todo: ordering, to prevent ally / no longer ally notif spam EconomicAIStrategyTypes eStrategyUNGS = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_GS_DIPLOMACY"); if (pRewardInfo->GetCityStateInfluenceBoost() > 0) { if(eStrategyUNGS != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyUNGS)) { iModifier += 250; } } EconomicAIStrategyTypes eStrategySpaceShip = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_GS_SPACESHIP"); // Beaker boost based on previous turns if (pRewardInfo->GetBaseBeakersTurnsToCount() > 0) { if(eStrategySpaceShip != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategySpaceShip)) { iModifier += 250; } } // Free unit class if (pRewardInfo->GetFreeUnitClass() != NO_UNITCLASS) { UnitTypes eUnit = (UnitTypes) kPlayer.getCivilizationInfo().getCivilizationUnits(pRewardInfo->GetFreeUnitClass()); if (eUnit != NO_UNIT) { CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eUnit); if(pkUnitInfo) { int iValue = 500; if(kPlayer.getCapitalCity() != NULL) { iValue = kPlayer.getCapitalCity()->GetCityStrategyAI()->GetUnitProductionAI()->CheckUnitBuildSanity(eUnit, false, NULL, iValue, 1); } iModifier += iValue; } } } EconomicAIStrategyTypes eStrategyConquest = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_GS_CONQUEST"); #if defined(MOD_DIPLOMACY_CITYSTATES_RESOLUTIONS) if (MOD_DIPLOMACY_CITYSTATES_RESOLUTIONS) { //CSD Project Rewards if (pRewardInfo->GetAttackBonusTurns() > 0) { if(eStrategyConquest != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyConquest)) { iModifier += 150; } } if (pRewardInfo->GetBaseFreeUnits() > 0) { if(eStrategyConquest != NO_ECONOMICAISTRATEGY && kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyConquest)) { iModifier += 150; } } // Temporary Culture Modifier if (pRewardInfo->GetNumFreeGreatPeople() > 0) { iModifier += 250; } } #endif } } } } if(iGPT <= 0) { iModifier += (iGPT *= -2); } if(m_pCity->IsPuppet()) { iTempWeight *= (60 + iModifier); iTempWeight /= 100; } else { iTempWeight *= (100 + iModifier); iTempWeight /= 100; } return iTempWeight; }