Hooks
static bool BeforeCvCityStrategyAI_ChooseProduction(CvCityStrategyAI* self, bool bUseAsyncRandom, BuildingTypes eIgnoreBldg, UnitTypes eIgnoreUnit);static void AfterCvCityStrategyAI_ChooseProduction(CvCityStrategyAI* self, bool bUseAsyncRandom, BuildingTypes eIgnoreBldg, UnitTypes eIgnoreUnit);static void ReplaceCvCityStrategyAI_ChooseProduction(void (*original)(CvCityStrategyAI*, bool, BuildingTypes, UnitTypes), CvCityStrategyAI* self, bool bUseAsyncRandom, BuildingTypes eIgnoreBldg, UnitTypes eIgnoreUnit);CivRegisterBefore<CivHooks::CvCityStrategyAI_ChooseProduction>(host, &BeforeCvCityStrategyAI_ChooseProduction);CivRegisterAfter<CivHooks::CvCityStrategyAI_ChooseProduction>(host, &AfterCvCityStrategyAI_ChooseProduction);CivRegisterReplace<CivHooks::CvCityStrategyAI_ChooseProduction>(host, &ReplaceCvCityStrategyAI_ChooseProduction);
Code
742/// Pick the next build for a city (unit, building or wonder)743void CvCityStrategyAI::ChooseProduction(bool bUseAsyncRandom, BuildingTypes eIgnoreBldg /* = NO_BUILDING */, UnitTypes eIgnoreUnit/* = NO_UNIT */)744{745 RandomNumberDelegate fcn;746 int iBldgLoop, iUnitLoop, iProjectLoop, iProcessLoop, iTempWeight;747 CvCityBuildable buildable;748 CvCityBuildable selection;749 UnitTypes eUnitForOperation;750 UnitTypes eUnitForArmy;751752 CvPlayerAI& kPlayer = GET_PLAYER(m_pCity->getOwner());753 CvDiplomacyAI* pDiploAI = kPlayer.GetDiplomacyAI();754755 //int iSettlersOnMap = kPlayer.GetNumUnitsWithUnitAI(UNITAI_SETTLE, true);756757 // Use the asynchronous random number generate if "no random" is set758 if(bUseAsyncRandom)759 {760 fcn = MakeDelegate(&GC.getGame(), &CvGame::getAsyncRandNum);761 }762 else763 {764 fcn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum);765 }766767 // Reset vector holding items we can currently build768 m_Buildables.clear();769770 EconomicAIStrategyTypes eStrategyEnoughSettlers = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_ENOUGH_EXPANSION");771 bool bEnoughSettlers = kPlayer.GetEconomicAI()->IsUsingStrategy(eStrategyEnoughSettlers);772773 // Check units for operations first774 eUnitForOperation = m_pCity->GetUnitForOperation();775 if(eUnitForOperation != NO_UNIT)776 {777 buildable.m_eBuildableType = CITY_BUILDABLE_UNIT_FOR_OPERATION;778 buildable.m_iIndex = (int)eUnitForOperation;779 buildable.m_iTurnsToConstruct = GetCity()->getProductionTurnsLeft(eUnitForOperation, 0);780 iTempWeight = GC.getAI_CITYSTRATEGY_OPERATION_UNIT_BASE_WEIGHT();781 int iOffenseFlavor = kPlayer.GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_OFFENSE")) + kPlayer.GetMilitaryAI()->GetNumberOfTimesOpsBuildSkippedOver();782 iTempWeight += (GC.getAI_CITYSTRATEGY_OPERATION_UNIT_FLAVOR_MULTIPLIER() * iOffenseFlavor);783784 if(GetSpecialization() != NO_CITY_SPECIALIZATION && GC.getCitySpecializationInfo(GetSpecialization())->IsOperationUnitProvider())785 {786 iTempWeight *= 5;787 }788789 // add in the weight of this unit as if I were deciding to build it without having a reason790 iTempWeight += m_pUnitProductionAI->GetWeight(eUnitForOperation);791792 CvUnitEntry* pkUnitEntry = GC.getUnitInfo(eUnitForOperation);793 if(pkUnitEntry && pkUnitEntry->GetDefaultUnitAIType() == UNITAI_SETTLE)794 {795 if(bEnoughSettlers)796 {797 iTempWeight = 0;798 }799 else800 {801 int iBestArea, iSecondBestArea;802 int iNumGoodAreas = kPlayer.GetBestSettleAreas(kPlayer.GetEconomicAI()->GetMinimumSettleFertility(), iBestArea, iSecondBestArea);803 if(iNumGoodAreas == 0)804 {805 iTempWeight = 0;806 }807 }808 }809810#if defined(MOD_AI_SMART_V3)811 if (MOD_AI_SMART_V3)812 {813 iTempWeight = GetUnitProductionAI()->GetTempWeightRevised(eUnitForOperation, iTempWeight);814 }815#endif816 if (iTempWeight > 0)817 {818 m_Buildables.push_back(buildable, iTempWeight);819 kPlayer.GetMilitaryAI()->BumpNumberOfTimesOpsBuildSkippedOver();820 }821822 }823824 // Next units for sneak attack armies825 eUnitForArmy = kPlayer.GetMilitaryAI()->GetUnitForArmy(GetCity());826 if(eUnitForArmy != NO_UNIT)827 {828 buildable.m_eBuildableType = CITY_BUILDABLE_UNIT_FOR_ARMY;829 buildable.m_iIndex = (int)eUnitForArmy;830 buildable.m_iTurnsToConstruct = GetCity()->getProductionTurnsLeft(eUnitForArmy, 0);831 iTempWeight = GC.getAI_CITYSTRATEGY_ARMY_UNIT_BASE_WEIGHT();832 int iOffenseFlavor = kPlayer.GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_OFFENSE"));833 int iBonusMultiplier = max(1,GC.getGame().getHandicapInfo().GetID() - 5); // more at the higher difficulties834 iTempWeight += (GC.getAI_CITYSTRATEGY_OPERATION_UNIT_FLAVOR_MULTIPLIER() * iOffenseFlavor * iBonusMultiplier);835 // add in the weight of this unit as if I were deciding to build it without having a reason836 iTempWeight += m_pUnitProductionAI->GetWeight(eUnitForArmy);837838#if defined(MOD_AI_SMART_V3)839 if (MOD_AI_SMART_V3)840 {841 iTempWeight = GetUnitProductionAI()->GetTempWeightRevised(eUnitForArmy, iTempWeight);842 }843#endif844 if (iTempWeight > 0)845 {846 m_Buildables.push_back(buildable, iTempWeight);847 }848 }849850 // Loop through adding the available buildings851 for(iBldgLoop = 0; iBldgLoop < GC.GetGameBuildings()->GetNumBuildings(); iBldgLoop++)852 {853 const BuildingTypes eLoopBuilding = static_cast<BuildingTypes>(iBldgLoop);854 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eLoopBuilding);855856 //Skip if null857 if(pkBuildingInfo == NULL)858 continue;859860 // Make sure this building can be built now861 if(iBldgLoop != eIgnoreBldg && m_pCity->canConstruct(eLoopBuilding))862 {863 buildable.m_eBuildableType = CITY_BUILDABLE_BUILDING;864 buildable.m_iIndex = iBldgLoop;865 buildable.m_iTurnsToConstruct = GetCity()->getProductionTurnsLeft(eLoopBuilding, 0);866867 iTempWeight = m_pBuildingProductionAI->GetWeight(eLoopBuilding);868869 // Don't build the UN if you aren't going for the diplo victory870 if(pkBuildingInfo->IsDiplomaticVoting())871 {872 int iVotesNeededToWin = GC.getGame().GetVotesNeededForDiploVictory();873 int iSecuredVotes = 0;874 TeamTypes myTeamID = kPlayer.getTeam();875 PlayerTypes myPlayerID = kPlayer.GetID();876877 // Loop through Players to see if they'll vote for this player878 PlayerTypes eLoopPlayer;879 TeamTypes eLoopTeam;880 for(int iPlayerLoop = 0; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)881 {882 eLoopPlayer = (PlayerTypes) iPlayerLoop;883884 if(GET_PLAYER(eLoopPlayer).isAlive())885 {886 eLoopTeam = GET_PLAYER(eLoopPlayer).getTeam();887888 // Liberated?889 if(GET_TEAM(eLoopTeam).GetLiberatedByTeam() == myTeamID)890 {891 iSecuredVotes++;892 }893894 // Minor civ?895 else if(GET_PLAYER(eLoopPlayer).isMinorCiv())896 {897 // Best Relations?898 if(GET_PLAYER(eLoopPlayer).GetMinorCivAI()->GetAlly() == myPlayerID)899 {900 iSecuredVotes++;901 }902 }903 }904 }905906 int iNumberOfPlayersWeNeedToBuyOff = MAX(0, iVotesNeededToWin - iSecuredVotes);907908 if(!pDiploAI || !pDiploAI->IsGoingForDiploVictory() || kPlayer.GetTreasury()->GetGold() < iNumberOfPlayersWeNeedToBuyOff * 500)909 {910 iTempWeight = 0;911 }912 }913914 // If the City is a puppet, it avoids Wonders (because the human can't change it if he wants to build it somewhere else!)915 if(GetCity()->IsPuppet())916 {917 const CvBuildingClassInfo& kBuildingClassInfo = pkBuildingInfo->GetBuildingClassInfo();918919 if(isWorldWonderClass(kBuildingClassInfo) || isTeamWonderClass(kBuildingClassInfo) || isNationalWonderClass(kBuildingClassInfo) || isLimitedWonderClass(kBuildingClassInfo))920 {921 iTempWeight = 0;922 }923 924#if defined(MOD_AI_SMART_V3)925 if (!MOD_AI_SMART_V3)926#endif927 // it also avoids military training buildings - since it can't build units928 if(pkBuildingInfo->GetDomainFreeExperience(DOMAIN_LAND))929 {930 iTempWeight = 0;931 }932 // they also like stuff that won't burden the empire with maintenance costs933 if(pkBuildingInfo->GetGoldMaintenance() == 0)934 {935 iTempWeight *= 2;936 }937 // and they avoid any buildings that require resources938 int iNumResources = GC.getNumResourceInfos();939 for(int iResourceLoop = 0; iResourceLoop < iNumResources; iResourceLoop++)940 {941 if(pkBuildingInfo->GetResourceQuantityRequirement(iResourceLoop) > 0)942 {943 iTempWeight = 0;944 }945 }946 }947 948#if defined(MOD_AI_SMART_V3)949 if (MOD_AI_SMART_V3)950 {951 const CvBuildingClassInfo& kbClassInfo = pkBuildingInfo->GetBuildingClassInfo();952 // Buiding that only can produce one in empire? (National/World wonder)953 if((kbClassInfo.getMaxPlayerInstances() == 1) || (kbClassInfo.getMaxGlobalInstances() == 1))954 {955 // All worls wonders have a specific restriction behavior.956 bool bIsWorldWonder = kbClassInfo.getMaxGlobalInstances() == 1;957958 // Grand Temple restriction!959 bool bRequireHolyCity = pkBuildingInfo->IsRequiresHolyCity();960961 // Hermitage, Tourist Center962 bool bIsCultureRelatedBuilding = (pkBuildingInfo->GetCultureRateModifier() > 0) || ((pkBuildingInfo->GetLandmarksTourismPercent() + pkBuildingInfo->GetGreatWorksTourismModifier()) > 0);963964 // National college, Oxford University965 bool bIsScienceBoostBuilding = (pkBuildingInfo->GetYieldModifier(YIELD_SCIENCE) > 0) || (pkBuildingInfo->GetYieldChange(YIELD_SCIENCE) > 1);966967 // All Guilds968 bool bIsGreatPeopleProvider = pkBuildingInfo->GetSpecialistCount() > 0;969970 // National Epic971 bool bIsGreatPleopleBooster = pkBuildingInfo->GetGreatPeopleRateModifier() > 0;972973 // East India Company974 bool bIsTradeRouteBooster = (pkBuildingInfo->GetTradeRouteRecipientBonus() + pkBuildingInfo->GetTradeRouteTargetBonus()) > 0;975976 // Iron works, Circus Maximus, National Intelligence agency, any custom National wonder without any bonus previously checked.977 bool bOtherNationalWonder = !bIsWorldWonder && !bRequireHolyCity && !bIsCultureRelatedBuilding && !bIsScienceBoostBuilding && !bIsGreatPeopleProvider && !bIsGreatPleopleBooster && !bIsTradeRouteBooster;978979 CvWeightedVector<CvCity *, SAFE_ESTIMATE_NUM_CITIES, true> weightedCityList;980 CvCity* pLoopCity = NULL;981 int iLoop = 0;982 int nonPuppetCities = 0;983 // Lets check some values in all cities.984 for(pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))985 {986 if (!pLoopCity->IsPuppet())987 {988 nonPuppetCities++;989 // City could build current building being checked?990 if (pLoopCity->canConstruct(eLoopBuilding))991 {992 int cityScore = 0;993994 if (bRequireHolyCity)995 {996 // canConstruct filter will filter out any non holy city.997 cityScore += 100;998 }9991000 if (bIsCultureRelatedBuilding)1001 {1002 cityScore += pLoopCity->getJONSCulturePerTurn();1003 }1004 if(bIsScienceBoostBuilding)1005 {1006 cityScore += pLoopCity->getYieldRate(YIELD_SCIENCE, true);1007 }1008 if (bIsGreatPleopleBooster)1009 {1010 int gpCount = pLoopCity->GetCityCitizens()->GetTotalSpecialistCount();1011 if (gpCount > 2)1012 {1013 cityScore += (gpCount * 20);1014 } 1015 }1016 if (bIsGreatPeopleProvider)1017 {1018 int gpScore = pLoopCity->foodDifference() + pLoopCity->getPopulation() - (pLoopCity->GetCityCitizens()->GetTotalSpecialistCount() * 2);1019 if (gpScore > 7)1020 {1021 cityScore += (gpScore * 5);1022 } 1023 }1024 if (bIsTradeRouteBooster)1025 {1026 CvPlayerTrade* pTrade = GET_PLAYER(m_pCity->getOwner()).GetTrade();1027 if(pTrade)1028 {1029 int iLandTrade = pTrade->GetNumPotentialConnections(pLoopCity, DOMAIN_LAND);1030 int iSeaTrade = pTrade->GetNumPotentialConnections(pLoopCity, DOMAIN_SEA);1031 cityScore += (iLandTrade + iSeaTrade);1032 }1033 else1034 {1035 // Shouldn't happen, but anyways...1036 bOtherNationalWonder = true;1037 }1038 }10391040 if (bOtherNationalWonder || bIsWorldWonder)1041 {1042 cityScore += pLoopCity->getCurrentProductionDifference(true, false);1043 }10441045 if (cityScore > 0)1046 {1047 weightedCityList.push_back(pLoopCity, cityScore);1048 } 1049 }1050 }1051 }10521053 // Start checking more cities for wide empires, starting at two cities with 5 non-puppets, for wonders 3.1054 int cityDivisor = bIsWorldWonder? 3 : 5;1055 int numCitiesChecked = min(weightedCityList.size(), (1 + (nonPuppetCities / cityDivisor)));1056 bool bValidCity = false;1057 // Sort for higher scored cities on top.1058 weightedCityList.SortItems();1059 for (int cityIt = 0; cityIt < numCitiesChecked; cityIt++)1060 {1061 if ((weightedCityList.GetElement(cityIt)->GetID() == GetCity()->GetID()) && (weightedCityList.GetWeight(cityIt) > 0))1062 {1063 bValidCity = true;1064 if (!bIsWorldWonder)1065 {1066 // We also boost the national wonder weight: we want it ASAP.1067 iTempWeight = (iTempWeight * 3) / 2;1068 }1069 break;1070 }1071 } 10721073 if (!bValidCity)1074 {1075 iTempWeight = 0;1076 }1077 }1078 }1079#endif10801081 if(iTempWeight > 0)1082 m_Buildables.push_back(buildable, iTempWeight);1083 }1084 }10851086 // If the City is a puppet, it avoids training Units and projects1087 if(!GetCity()->IsPuppet())1088 {1089 // Loop through adding the available units1090 for(iUnitLoop = 0; iUnitLoop < GC.GetGameUnits()->GetNumUnits(); iUnitLoop++)1091 {1092 // Make sure this unit can be built now1093 if(iUnitLoop != eIgnoreUnit &&1094 //GC.GetGameBuildings()->GetEntry(iUnitLoop)->GetAdvisorType() != eIgnoreAdvisor &&1095 m_pCity->canTrain((UnitTypes)iUnitLoop))1096 {1097 buildable.m_eBuildableType = CITY_BUILDABLE_UNIT;1098 buildable.m_iIndex = iUnitLoop;1099 buildable.m_iTurnsToConstruct = GetCity()->getProductionTurnsLeft((UnitTypes)iUnitLoop, 0);11001101 iTempWeight = m_pUnitProductionAI->GetWeight((UnitTypes)iUnitLoop);11021103 CvUnitEntry* pkUnitEntry = GC.getUnitInfo((UnitTypes)iUnitLoop);1104 if(pkUnitEntry && pkUnitEntry->GetDefaultUnitAIType() == UNITAI_SETTLE)1105 {1106 if(bEnoughSettlers)1107 {1108 iTempWeight = 0;1109 }1110 else1111 {1112 int iBestArea, iSecondBestArea;1113 int iNumGoodAreas = kPlayer.GetBestSettleAreas(kPlayer.GetEconomicAI()->GetMinimumSettleFertility(), iBestArea, iSecondBestArea);1114 if(iNumGoodAreas == 0)1115 {1116 iTempWeight = 0;1117 }1118 }1119 }11201121 // sanity check for building ships on small inland seas (not lakes)1122 if (pkUnitEntry)1123 {1124 DomainTypes eDomain = (DomainTypes) pkUnitEntry->GetDomainType();1125 if (eDomain == DOMAIN_SEA && pkUnitEntry->GetDefaultUnitAIType() != UNITAI_WORKER_SEA) // if needed allow workboats...1126 {1127 CvArea* pBiggestNearbyBodyOfWater = m_pCity->waterArea();1128 if (pBiggestNearbyBodyOfWater)1129 {1130 int iWaterTiles = pBiggestNearbyBodyOfWater->getNumTiles();1131 int iNumUnitsofMine = pBiggestNearbyBodyOfWater->getUnitsPerPlayer(m_pCity->getOwner());1132#if defined(MOD_CONFIG_AI_IN_XML)1133 int iFactor = GC.getAI_CONFIG_MILITARY_TILES_PER_SHIP();1134 if (iNumUnitsofMine * iFactor > iWaterTiles)1135#else1136 if (iNumUnitsofMine * 5 > iWaterTiles)1137#endif1138 {1139 iTempWeight = 0;1140 }1141 }1142 else // this should never happen, but...1143 {1144 iTempWeight = 0;1145 }1146 }1147 }1148#if defined(MOD_AI_SMART_V3)1149 if (MOD_AI_SMART_V3)1150 {1151 iTempWeight = GetUnitProductionAI()->GetTempWeightRevised((UnitTypes)iUnitLoop, iTempWeight);1152 }1153#endif115411551156 if(iTempWeight > 0)1157 m_Buildables.push_back(buildable, iTempWeight);1158 }1159 }11601161 // Loop through adding the available projects1162 for(iProjectLoop = 0; iProjectLoop < GC.GetGameProjects()->GetNumProjects(); iProjectLoop++)1163 {1164 if(m_pCity->canCreate((ProjectTypes)iProjectLoop))1165 {1166 buildable.m_eBuildableType = CITY_BUILDABLE_PROJECT;1167 buildable.m_iIndex = iProjectLoop;1168 buildable.m_iTurnsToConstruct = GetCity()->getProductionTurnsLeft((ProjectTypes)iProjectLoop, 0);1169 m_Buildables.push_back(buildable, m_pProjectProductionAI->GetWeight((ProjectTypes)iProjectLoop));1170 }1171 }1172 }11731174 // Normally, a puppeted city cannot run processes, but as Venice they are allowed to.1175 bool bIsVenice = kPlayer.GetPlayerTraits()->IsNoAnnexing();1176 if (!GetCity()->IsPuppet() || bIsVenice)1177 { 1178 // Loop through adding available processes1179 if (!GET_PLAYER(m_pCity->getOwner()).isMinorCiv())1180 {1181 //I cannot use the yield rate since it adds in set process yield, which is what I am trying to set...1182 int iBaseYield = GetCity()->getBaseYieldRate(YIELD_PRODUCTION) * 100;1183 iBaseYield += (GetCity()->GetYieldPerPopTimes100(YIELD_PRODUCTION) * GetCity()->getPopulation());1184 int iModifiedYield = iBaseYield * GetCity()->getBaseYieldRateModifier(YIELD_PRODUCTION);1185 iModifiedYield /= 100;11861187 if (iModifiedYield >= 8)1188 {1189 for (iProcessLoop = 0; iProcessLoop < GC.getNumProcessInfos(); iProcessLoop++)1190 {1191 ProcessTypes eProcess = (ProcessTypes)iProcessLoop;1192 if (m_pCity->canMaintain(eProcess))1193 {1194 iTempWeight = m_pProcessProductionAI->GetWeight((ProcessTypes)iProcessLoop);1195 buildable.m_eBuildableType = CITY_BUILDABLE_PROCESS;1196 buildable.m_iIndex = iProcessLoop;1197 buildable.m_iTurnsToConstruct = 1;1198 m_Buildables.push_back(buildable, iTempWeight);1199 }1200 }1201 }1202 }1203 }12041205 ReweightByCost();12061207 m_Buildables.SortItems();12081209 LogPossibleBuilds();12101211 if(m_Buildables.GetTotalWeight() > 0)1212 {1213 // Choose from the best options (currently 2)1214 int iNumChoices = GC.getGame().getHandicapInfo().GetCityProductionNumOptions();1215 selection = m_Buildables.ChooseFromTopChoices(iNumChoices, &fcn, "Choosing city build from Top Choices");1216 int iRushIfMoreThanXTurns = GC.getAI_ATTEMPT_RUSH_OVER_X_TURNS_TO_BUILD();1217 if(GET_PLAYER(m_pCity->getOwner()).isMinorCiv())1218 {1219 iRushIfMoreThanXTurns *= GC.getMINOR_CIV_PRODUCTION_PERCENT();1220 iRushIfMoreThanXTurns /= 100;1221 }12221223 bool bRush = selection.m_iTurnsToConstruct > iRushIfMoreThanXTurns;1224 LogCityProduction(selection, bRush);12251226 switch(selection.m_eBuildableType)1227 {1228 case CITY_BUILDABLE_UNIT:1229 case CITY_BUILDABLE_UNIT_FOR_ARMY:1230 {1231 UnitTypes eUnitType = (UnitTypes) selection.m_iIndex;1232 CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eUnitType);1233 if(pkUnitInfo)1234 {1235 UnitAITypes eUnitAI = (UnitAITypes) pkUnitInfo->GetDefaultUnitAIType();1236 GetCity()->pushOrder(ORDER_TRAIN, eUnitType, eUnitAI, false, true, false, bRush);1237 }1238 }1239 break;12401241 case CITY_BUILDABLE_BUILDING:1242 {1243 BuildingTypes eBuildingType = (BuildingTypes) selection.m_iIndex;1244 GetCity()->pushOrder(ORDER_CONSTRUCT, eBuildingType, -1, false, true, false, bRush);1245 }1246 break;12471248 case CITY_BUILDABLE_PROJECT:1249 {1250 ProjectTypes eProjectType = (ProjectTypes) selection.m_iIndex;1251 GetCity()->pushOrder(ORDER_CREATE, eProjectType, -1, false, true, false, bRush);1252 }1253 break;12541255 case CITY_BUILDABLE_PROCESS:1256 {1257 ProcessTypes eProcessType = (ProcessTypes)selection.m_iIndex;1258 GetCity()->pushOrder(ORDER_MAINTAIN, eProcessType, -1, false, true, false, false); // ignoring rush because we can't rush a process1259 }12601261 case CITY_BUILDABLE_UNIT_FOR_OPERATION:1262 {1263 GetCity()->CommitToBuildingUnitForOperation();1264 kPlayer.GetMilitaryAI()->ResetNumberOfTimesOpsBuildSkippedOver();1265 }1266 break;1267 }12681269 }12701271 return;1272}