Hooks
static bool BeforeCityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers(AICityStrategyTypes eStrategy, CvCity* pCity, bool& result);static void AfterCityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers(AICityStrategyTypes eStrategy, CvCity* pCity, bool& result);static bool ReplaceCityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers(bool (*original)(AICityStrategyTypes, CvCity*), AICityStrategyTypes eStrategy, CvCity* pCity);CivRegisterBefore<CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers>(host, &BeforeCityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers);CivRegisterAfter<CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers>(host, &AfterCityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers);CivRegisterReplace<CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers>(host, &ReplaceCityStrategyAIHelpers_IsTestCityStrategy_NeedTileImprovers);
Code
2272/// "Need Tile Improvers" City Strategy: Do we REALLY need to train some Workers?2273bool CityStrategyAIHelpers::IsTestCityStrategy_NeedTileImprovers(AICityStrategyTypes eStrategy, CvCity* pCity)2274{2275 CvPlayer& kPlayer = GET_PLAYER(pCity->getOwner());2276 int iCurrentNumCities = kPlayer.getNumCities();22772278 int iLastTurnWorkerDisbanded = kPlayer.GetEconomicAI()->GetLastTurnWorkerDisbanded();2279 if(iLastTurnWorkerDisbanded >= 0 && GC.getGame().getGameTurn() - iLastTurnWorkerDisbanded <= 25)2280 {2281 return false;2282 }22832284 int iNumWorkers = kPlayer.GetNumUnitsWithUnitAI(UNITAI_WORKER, true, false);2285 // If it's a minor with at least 1 worker per city, always return false2286 if(kPlayer.isMinorCiv())2287 {2288 if(iNumWorkers >= iCurrentNumCities)2289 return false;2290 }2291 else2292 {2293#if defined(MOD_AI_SMART_V3)2294 int iNumCities = 1;2295 2296 if (MOD_AI_SMART_V3)2297 {2298 CvCity* pLoopCity = NULL;2299 int iLoop = 0;2300 int iNumImprovedTiles = 0;2301 int iNumEmptyTiles = 0;2302 // Lets check some values in all cities.2303 for(pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))2304 {2305 // Look at all Tiles and count improved vs uninproved.2306 CvPlot* pLoopPlot;2307#if defined(MOD_GLOBAL_CITY_WORKING)2308 for (int iPlotLoop = 0; iPlotLoop < pLoopCity->GetNumWorkablePlots(); iPlotLoop++)2309#else2310 for (int iPlotLoop = 0; iPlotLoop < NUM_CITY_PLOTS; iPlotLoop++)2311#endif2312 {2313 pLoopPlot = plotCity(pLoopCity->getX(), pLoopCity->getY(), iPlotLoop);23142315 if(pLoopPlot != NULL)2316 {2317 if(pLoopPlot->getOwner() == pCity->getOwner())2318 {2319 if(!pLoopPlot->isWater())2320 {2321 if(pLoopPlot->getImprovementType() != NO_IMPROVEMENT)2322 {2323 if (pLoopPlot->IsImprovementPillaged())2324 {2325 iNumEmptyTiles++;2326 }2327 else2328 {2329 iNumImprovedTiles++;2330 }2331 }2332 else2333 {2334 for(int iBuildIndex = 0; iBuildIndex < GC.getNumBuildInfos(); iBuildIndex++)2335 {2336 BuildTypes eBuild = (BuildTypes) iBuildIndex;2337 CvBuildInfo* pBuildInfo = GC.getBuildInfo(eBuild);2338 if(pBuildInfo == NULL)2339 continue;23402341 ImprovementTypes eImprovement = (ImprovementTypes) pBuildInfo->getImprovement();2342 2343 if(eImprovement == NO_IMPROVEMENT)2344 continue;23452346 if(kPlayer.canBuild(pLoopPlot, eBuild, false /*bTestEra*/, false /*bTestVisible*/, false /*bTestGold*/, false))2347 {2348 iNumEmptyTiles++;2349 break;2350 }2351 }2352 }2353 }2354 }2355 }2356 }2357 }2358 2359 if ((iNumImprovedTiles * 3) < iNumEmptyTiles)2360 {2361 iNumCities = max(1, (iCurrentNumCities * 4) / 3);2362 }2363 else if ((iNumEmptyTiles * 3) < iNumImprovedTiles)2364 {2365 iNumCities = max(1, (iCurrentNumCities * 3) / 4);2366 }2367 else2368 {2369 iNumCities = iCurrentNumCities;2370 }2371 }2372 else2373 {2374 iNumCities = max(1, (iCurrentNumCities * 3) / 4);2375 }2376#else2377 int iNumCities = max(1, (iCurrentNumCities * 3) / 4);2378#endif2379 if(iNumWorkers >= iNumCities)2380 return false;2381 // If we're losing at war, return false2382 if(kPlayer.GetDiplomacyAI()->GetStateAllWars() == STATE_ALL_WARS_LOSING)2383 return false;2384 }23852386 // If we're under attack from Barbs and have 1 or fewer Cities and no credible defense then training more Workers will only hurt us2387 if(iCurrentNumCities <= 1)2388 {2389 CvMilitaryAI* pMilitaryAI =kPlayer.GetMilitaryAI();2390 MilitaryAIStrategyTypes eStrategyKillBarbs = (MilitaryAIStrategyTypes) GC.getInfoTypeForString("MILITARYAISTRATEGY_ERADICATE_BARBARIANS");2391 if(eStrategyKillBarbs != NO_MILITARYAISTRATEGY)2392 {2393 if(pMilitaryAI->IsUsingStrategy(eStrategyKillBarbs))2394 {2395 return false;2396 }2397 }2398 }23992400 CvAICityStrategyEntry* pCityStrategy = pCity->GetCityStrategyAI()->GetAICityStrategies()->GetEntry(eStrategy);24012402 int iModdedNumWorkers = iNumWorkers* /*67*/ pCityStrategy->GetWeightThreshold() / 100;2403 int iModdedNumCities = iCurrentNumCities + kPlayer.countCitiesFeatureSurrounded();24042405 // We have fewer than we think we should, or we have none at all2406 if(iModdedNumWorkers <= iModdedNumCities || iModdedNumWorkers == 0)2407 {2408 // If we don't have any Workers by turn 30 we really need to get moving2409 int iDesperateTurn = /*30*/ GC.getAI_CITYSTRATEGY_NEED_TILE_IMPROVERS_DESPERATE_TURN();24102411 iDesperateTurn *= GC.getGame().getGameSpeedInfo().getTrainPercent();2412 iDesperateTurn /= 100;24132414 if(GC.getGame().getElapsedGameTurns() > iDesperateTurn)2415 return true;2416 }24172418 return false;2419}