/// How many policies in this branch help happiness? int CvPolicyAI::GetNumHappinessPolicies(CvPlayer* pPlayer, PolicyBranchTypes eBranch) { int iRtnValue = 0; int iBuildingClassLoop; BuildingClassTypes eBuildingClass; for(int iPolicyLoop = 0; iPolicyLoop < GC.getNumPolicyInfos(); iPolicyLoop++) { PolicyTypes ePolicy = (PolicyTypes)iPolicyLoop; CvPolicyEntry* pkPolicyInfo = GC.getPolicyInfo(ePolicy); if(pkPolicyInfo) { if (pkPolicyInfo->GetPolicyBranchType() == eBranch) { for(iBuildingClassLoop = 0; iBuildingClassLoop < GC.getNumBuildingClassInfos(); iBuildingClassLoop++) { eBuildingClass = (BuildingClassTypes) iBuildingClassLoop; CvBuildingClassInfo* pkBuildingClassInfo = GC.getBuildingClassInfo(eBuildingClass); if (!pkBuildingClassInfo) { continue; } BuildingTypes eBuilding = (BuildingTypes)pPlayer->getCivilizationInfo().getCivilizationBuildings(eBuildingClass); if (eBuilding != NO_BUILDING) { // Don't count a building that can only be built in conquered cities CvBuildingEntry *pkEntry = GC.getBuildingInfo(eBuilding); if (!pkEntry || pkEntry->IsNoOccupiedUnhappiness()) { continue; } if (pkPolicyInfo->GetBuildingClassHappiness(eBuildingClass) != 0) { iRtnValue++; break; } } } } } } return iRtnValue; }
bool isTechRequiredForBuilding(TechTypes eTech, BuildingTypes eBuilding) { CvBuildingEntry* info = GC.getBuildingInfo(eBuilding); if(info) { if(info->GetPrereqAndTech() == eTech) { return true; } for(int iI = 0; iI < GC.getNUM_BUILDING_AND_TECH_PREREQS(); iI++) { if(info->GetPrereqAndTechs(iI) == eTech) { return true; } } } return false; }
void CvPlayerAI::AI_considerAnnex() { AI_PERF("AI-perf.csv", "AI_ considerAnnex"); // if the empire is unhappy, don't consider annexing if (IsEmpireUnhappy()) { return; } // if we're going for a culture victory, don't consider annexing if (GetDiplomacyAI()->IsGoingForCultureVictory()) { return; } // for Venice if (GetPlayerTraits()->IsNoAnnexing()) { return; } // if their capital city is puppeted, annex it CvCity* pCity = getCapitalCity(); if (pCity && pCity->IsPuppet()) { // we should only annex one city a turn, and sense this is one, we're done! pCity->DoAnnex(); return; } std::vector<CityAndProduction> aCityAndProductions; int iLoop = 0; pCity = NULL; // Find first coastal city in same area as settler for(pCity = firstCity(&iLoop); pCity != NULL; pCity = nextCity(&iLoop)) { CityAndProduction kEval; kEval.pCity = pCity; kEval.iProduction = pCity->getYieldRateTimes100(YIELD_PRODUCTION, false); aCityAndProductions.push_back(kEval); } std::stable_sort(aCityAndProductions.begin(), aCityAndProductions.end(), CityAndProductionEval()); CvCity* pTargetCity = NULL; float fCutoffValue = GC.getNORMAL_ANNEX(); BuildingClassTypes eCourthouseType = NO_BUILDINGCLASS; // find courthouse for(int eBuildingType = 0; eBuildingType < GC.getNumBuildingInfos(); eBuildingType++) { const BuildingTypes eBuilding = static_cast<BuildingTypes>(eBuildingType); CvBuildingEntry* buildingInfo = GC.getBuildingInfo(eBuilding); if(buildingInfo) { if (buildingInfo->IsNoOccupiedUnhappiness()) { eCourthouseType = (BuildingClassTypes)buildingInfo->GetBuildingClassType(); break; } } } bool bCourthouseImprovement = false; if (eCourthouseType != NO_BUILDINGCLASS) { if (GetPlayerPolicies()->GetBuildingClassProductionModifier(eCourthouseType) > 0) { bCourthouseImprovement = true; } } if (bCourthouseImprovement) { fCutoffValue = GC.getAGGRESIVE_ANNEX(); } uint uiCutOff = (uint)(aCityAndProductions.size() * fCutoffValue); for (uint ui = 0; ui < uiCutOff; ui++) { if (aCityAndProductions[ui].pCity->IsPuppet()) { pTargetCity = aCityAndProductions[ui].pCity; break; } } if (pTargetCity) { if (!pTargetCity->IsResistance()) { pTargetCity->DoAnnex(); } } }
void CvCityAI::AI_chooseProduction(bool bInterruptWonders) { VALIDATE_OBJECT CvPlayerAI& kOwner = GET_PLAYER(getOwner()); CvCitySpecializationAI* pSpecializationAI = kOwner.GetCitySpecializationAI(); bool bBuildWonder = false; // See if this is the one AI city that is supposed to be building wonders if(pSpecializationAI->GetWonderBuildCity() == this) { // Is it still working on that wonder and we don't want to interrupt it? if(!bInterruptWonders) { const BuildingTypes eBuilding = getProductionBuilding(); CvBuildingEntry* pkBuilding = (eBuilding != NO_BUILDING)? GC.getBuildingInfo(eBuilding) : NULL; if(pkBuilding && kOwner.GetWonderProductionAI()->IsWonder(*pkBuilding)) { return; // Stay the course } } // So we're the wonder building city but it is not underway yet... // Has the designated wonder been poached by another civ? BuildingTypes eNextWonder = pSpecializationAI->GetNextWonderDesired(); if(!canConstruct(eNextWonder)) { // Reset city specialization kOwner.GetCitySpecializationAI()->SetSpecializationsDirty(SPECIALIZATION_UPDATE_WONDER_BUILT_BY_RIVAL); } else { // to prevent us from continuously locking into building wonders in one city when there are other high priority items to build int iFlavorWonder = kOwner.GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_WONDER")); int iFlavorGP = kOwner.GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_GREAT_PEOPLE")); int iFlavor = (iFlavorWonder > iFlavorGP ) ? iFlavorWonder : iFlavorGP; if (GC.getGame().getJonRandNum(11, "Random roll for whether to continue building wonders") <= iFlavor) bBuildWonder = true; } } if(bBuildWonder) { CvCityBuildable buildable; buildable.m_eBuildableType = CITY_BUILDABLE_BUILDING; buildable.m_iIndex = pSpecializationAI->GetNextWonderDesired(); buildable.m_iTurnsToConstruct = getProductionTurnsLeft((BuildingTypes)buildable.m_eBuildableType, 0); pushOrder(ORDER_CONSTRUCT, buildable.m_iIndex, -1, false, false, false, false); if(GC.getLogging() && GC.getAILogging()) { CvString playerName; FILogFile* pLog; CvString strBaseString; CvString strOutBuf; m_pCityStrategyAI->LogCityProduction(buildable, false); playerName = kOwner.getCivilizationShortDescription(); pLog = LOGFILEMGR.GetLog(kOwner.GetCitySpecializationAI()->GetLogFileName(playerName), FILogFile::kDontTimeStamp); strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns()); strBaseString += playerName + ", "; #ifdef AUI_WARNING_FIXES CvBuildingEntry* pWonderInfo = GC.getBuildingInfo((BuildingTypes)buildable.m_iIndex); if (pWonderInfo) strOutBuf.Format("%s, WONDER - Started %s, Turns: %d", getName().GetCString(), pWonderInfo->GetDescription(), buildable.m_iTurnsToConstruct); #else strOutBuf.Format("%s, WONDER - Started %s, Turns: %d", getName().GetCString(), GC.getBuildingInfo((BuildingTypes)buildable.m_iIndex)->GetDescription(), buildable.m_iTurnsToConstruct); #endif strBaseString += strOutBuf; pLog->Msg(strBaseString); } } else { m_pCityStrategyAI->ChooseProduction(false); AI_setChooseProductionDirty(false); } return; }
AdvisorTypes CvAdvisorRecommender::FindUnassignedAdvisorForBuildable (PlayerTypes /*ePlayer*/, CvCityBuildable& buildable) { int aiAdvisorValues[NUM_ADVISOR_TYPES]; for (uint ui = 0; ui < NUM_ADVISOR_TYPES; ui++) { aiAdvisorValues[ui] = 0; } CvBuildingEntry* pBuilding = NULL; CvUnitEntry* pUnit = NULL; CvProjectEntry* pProject = NULL; switch (buildable.m_eBuildableType) { case CITY_BUILDABLE_UNIT: pUnit = GC.getUnitInfo((UnitTypes)buildable.m_iIndex); break; case CITY_BUILDABLE_BUILDING: pBuilding = GC.getBuildingInfo((BuildingTypes)buildable.m_iIndex); break; case CITY_BUILDABLE_PROJECT: pProject = GC.getProjectInfo((ProjectTypes)buildable.m_iIndex); break; } for (int i = 0; i < GC.getNumFlavorTypes(); i++) { FlavorTypes eFlavor = (FlavorTypes)i; int iFlavorValue = 0; if (pBuilding) { iFlavorValue = pBuilding->GetFlavorValue(eFlavor); } else if (pUnit) { iFlavorValue = pUnit->GetFlavorValue(eFlavor); } else if (pProject) { iFlavorValue = pProject->GetFlavorValue(eFlavor); } if (iFlavorValue <= 0) { continue; } for (uint uiAdvisor = 0; uiAdvisor < NUM_ADVISOR_TYPES; uiAdvisor++) { AdvisorTypes eAdvisor = (AdvisorTypes)uiAdvisor; aiAdvisorValues[uiAdvisor] += iFlavorValue * AdvisorInterestInFlavor(eAdvisor, eFlavor); } } AdvisorTypes eWinningAdvisor = NO_ADVISOR_TYPE; int iHighestValue = 0; for (uint ui = 0; ui < NUM_ADVISOR_TYPES; ui++) { // skip this advisor if already assigned if (m_aRecommendedBuilds[ui].m_eBuildableType != NOT_A_CITY_BUILDABLE) { continue; } if (aiAdvisorValues[ui] > iHighestValue) { eWinningAdvisor = (AdvisorTypes)ui; iHighestValue = aiAdvisorValues[ui]; } } return eWinningAdvisor; }