Bazaar developer reference

CityStrategyAIHelpers::IsTestCityStrategy_WantTileImprovers(AICityStrategyTypes, CvCity *)

Defined in
CvCityStrategyAI.cpp, line 2422
Hook name
CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers

Hooks

static bool BeforeCityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers(AICityStrategyTypes eStrategy, CvCity* pCity, bool& result);static void AfterCityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers(AICityStrategyTypes eStrategy, CvCity* pCity, bool& result);static bool ReplaceCityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers(bool (*original)(AICityStrategyTypes, CvCity*), AICityStrategyTypes eStrategy, CvCity* pCity);CivRegisterBefore<CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers>(host, &BeforeCityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers);CivRegisterAfter<CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers>(host, &AfterCityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers);CivRegisterReplace<CivHooks::CityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers>(host, &ReplaceCityStrategyAIHelpers_IsTestCityStrategy_WantTileImprovers);

Code

2421/// "Want Tile Improvers" City Strategy: Looks at how many Builders are available empire-wide.  This is not a Player Strategy because it's only worried about training new Builders in Cities, and not Techs, Policies, etc.2422bool CityStrategyAIHelpers::IsTestCityStrategy_WantTileImprovers(AICityStrategyTypes eStrategy, CvCity* pCity)2423{2424	CvPlayer& kPlayer = GET_PLAYER(pCity->getOwner());2425	int iLastTurnWorkerDisbanded = kPlayer.GetEconomicAI()->GetLastTurnWorkerDisbanded();2426	if(iLastTurnWorkerDisbanded >= 0 && GC.getGame().getGameTurn() - iLastTurnWorkerDisbanded <= 10)2427	{2428		return false;2429	}24302431	if(!GET_PLAYER(pCity->getOwner()).isMinorCiv())2432	{2433		// If we're losing at war, return false2434		if(GET_PLAYER(pCity->getOwner()).GetDiplomacyAI()->GetStateAllWars() == STATE_ALL_WARS_LOSING)2435			return false;2436	}24372438	int iNumWorkers = kPlayer.GetNumUnitsWithUnitAI(UNITAI_WORKER, true, false);2439	if(iNumWorkers >= ((kPlayer.getNumCities() *  3) / 2) + 1)2440		return false;24412442	// If we're under attack from Barbs and have 1 or fewer cities then training more Workers will only hurt us2443	//if (kPlayer.getNumCities() <= 1)2444	//{2445	//	MilitaryAIStrategyTypes eStrategyKillBarbs = (MilitaryAIStrategyTypes) GC.getInfoTypeForString("MILITARYAISTRATEGY_ERADICATE_BARBARIANS");2446	//	if (eStrategyKillBarbs != NO_MILITARYAISTRATEGY)2447	//	{2448	//		if (GET_PLAYER(pCity->getOwner()).GetMilitaryAI()->IsUsingStrategy(eStrategyKillBarbs))2449	//			return false;2450	//	}2451	//}24522453	// Don't get desperate for training a Builder here unless the City is at least of a certain size2454	if(pCity->getPopulation() >= /*2*/ GC.getAI_CITYSTRATEGY_WANT_TILE_IMPROVERS_MINIMUM_SIZE())2455	{2456		int iNumBuilders = kPlayer.GetNumUnitsWithUnitAI(UNITAI_WORKER, true, false);24572458		// If we don't even have 1 builder on map or in a queue, turn this on immediately2459		if(iNumBuilders < 1)2460		{2461			return true;2462		}24632464		CvAICityStrategyEntry* pCityStrategy = pCity->GetCityStrategyAI()->GetAICityStrategies()->GetEntry(eStrategy);24652466		int iWeightThresholdModifier = CityStrategyAIHelpers::GetWeightThresholdModifier(eStrategy, pCity);	// 2 Extra Weight per TILE_IMPROVEMENT Flavor2467		int iPerCityThreshold = pCityStrategy->GetWeightThreshold() + iWeightThresholdModifier;	// 4024682469		// Look at all Tiles this City could potentially work to see if there are any Water Resources that could be improved2470		CvPlot* pLoopPlot;2471		int iNumResources = 0;2472		int iNumImprovedResources = 0;24732474#if defined(MOD_GLOBAL_CITY_WORKING)2475		for(int iPlotLoop = 0; iPlotLoop < pCity->GetNumWorkablePlots(); iPlotLoop++)2476#else2477		for(int iPlotLoop = 0; iPlotLoop < NUM_CITY_PLOTS; iPlotLoop++)2478#endif2479		{2480			pLoopPlot = plotCity(pCity->getX(), pCity->getY(), iPlotLoop);24812482			if(pLoopPlot != NULL)2483			{2484				if(pLoopPlot->getOwner() == pCity->getOwner())2485				{2486					if(!pLoopPlot->isWater())2487					{2488						ResourceTypes eResource = pLoopPlot->getResourceType(kPlayer.getTeam());2489						if(eResource == NO_RESOURCE)2490						{2491							continue;2492						}24932494						// loop through the build types to find one that we can use2495						ImprovementTypes eCorrectImprovement = NO_IMPROVEMENT;2496						BuildTypes eCorrectBuild = NO_BUILD;2497						int iBuildIndex;2498						for(iBuildIndex = 0; iBuildIndex < GC.getNumBuildInfos(); iBuildIndex++)2499						{2500							const BuildTypes eBuild = static_cast<BuildTypes>(iBuildIndex);2501							CvBuildInfo* pkBuildInfo = GC.getBuildInfo(eBuild);2502							if(pkBuildInfo)2503							{2504								const ImprovementTypes eImprovement = (ImprovementTypes)pkBuildInfo->getImprovement();25052506								// if this is the improvement we're looking for2507								if(eImprovement != NO_IMPROVEMENT)2508								{2509									CvImprovementEntry* pkImprovementInfo = GC.getImprovementInfo(eImprovement);2510									if(pkImprovementInfo)2511									{2512										if(pkImprovementInfo->IsImprovementResourceTrade(eResource))2513										{2514											eCorrectBuild = eBuild;2515											eCorrectImprovement = eImprovement;2516											break;2517										}2518									}2519								}2520							}25212522						}25232524						// no valid build found2525						if(eCorrectBuild == NO_BUILD || eCorrectImprovement == NO_IMPROVEMENT)2526						{2527							continue;2528						}252925302531						// if we can't build the improvement for the resource, continue!2532						if(!kPlayer.canBuild(pLoopPlot, eCorrectBuild, false, false))2533						{2534							if(pLoopPlot->getImprovementType() == eCorrectImprovement)2535							{2536								iNumImprovedResources++;2537								iNumResources++;2538							}25392540							continue;2541						}25422543						iNumResources++;2544					}2545				}2546			}2547		}25482549		bool bManyUnimproveResources = (2 * (iNumResources - iNumImprovedResources)) > iNumResources;2550		int iMultiplier = kPlayer.getNumCities();2551		iMultiplier += kPlayer.countCitiesFeatureSurrounded();2552		if(bManyUnimproveResources)2553			iMultiplier += 1;25542555		int iNumSettlers = kPlayer.GetNumUnitsWithUnitAI(UNITAI_SETTLE, true, false);2556		iMultiplier += iNumSettlers;25572558		int iWeightThreshold = (iPerCityThreshold * iMultiplier);25592560		//Do we want more Builders?2561		if((iNumBuilders * 100) < iWeightThreshold)2562		{2563			// slewis - need to check to see if training another worker will put us below the -10 threshold.2564			// slewis - todo: move -10 to a xml value2565			return (kPlayer.calculateGoldRate() > -10);25662567			// Also want to check and see if we have enough happiness to support another builder2568			//int iBuilderUnhappiness = 0;2569			//int iBuildersInGame = kPlayer.GetNumUnitsWithUnitAI(UNITAI_WORKER, false, false);2570			//if (iBuildersInGame > 0)2571			//{2572			//	CvUnit *pLoopUnit;2573			//	int iLoop;2574			//	for (pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))2575			//	{2576			//		if (pLoopUnit->AI_getUnitAIType() == UNITAI_WORKER)2577			//		{2578			//			break;2579			//		}2580			//	}2581			//	if (pLoopUnit)2582			//	{2583			//		iBuilderUnhappiness = pLoopUnit->getUnitInfo().GetUnhappiness();2584			//	}2585			//}25862587			//return (kPlayer.GetExcessHappiness()) >= (iNumBuilders - iBuildersInGame + 1) * iBuilderUnhappiness;2588		}2589	}25902591	return false;2592}

Calls

Called by