Bazaar developer reference

CvCitySiteEvaluator::PlotFoundValue(CvPlot *, CvPlayer *, YieldTypes, bool)

Defined in
CvSiteEvaluationClasses.cpp, line 280
Class
CvCitySiteEvaluator
Hook name
CivHooks::CvCitySiteEvaluator_PlotFoundValue
Overridden by
CvSiteEvaluatorForSettler::PlotFoundValue(CvPlot *, CvPlayer *, YieldTypes, bool), CvSiteEvaluatorForStart::PlotFoundValue(CvPlot *, CvPlayer *, YieldTypes, bool)

Hooks

static bool BeforeCvCitySiteEvaluator_PlotFoundValue(CvCitySiteEvaluator* self, CvPlot* pPlot, CvPlayer* pPlayer, YieldTypes eYield, bool arg3, int& result);static void AfterCvCitySiteEvaluator_PlotFoundValue(CvCitySiteEvaluator* self, CvPlot* pPlot, CvPlayer* pPlayer, YieldTypes eYield, bool arg3, int& result);static int ReplaceCvCitySiteEvaluator_PlotFoundValue(int (*original)(CvCitySiteEvaluator*, CvPlot*, CvPlayer*, YieldTypes, bool), CvCitySiteEvaluator* self, CvPlot* pPlot, CvPlayer* pPlayer, YieldTypes eYield, bool arg3);CivRegisterBefore<CivHooks::CvCitySiteEvaluator_PlotFoundValue>(host, &BeforeCvCitySiteEvaluator_PlotFoundValue);CivRegisterAfter<CivHooks::CvCitySiteEvaluator_PlotFoundValue>(host, &AfterCvCitySiteEvaluator_PlotFoundValue);CivRegisterReplace<CivHooks::CvCitySiteEvaluator_PlotFoundValue>(host, &ReplaceCvCitySiteEvaluator_PlotFoundValue);

Code

279/// Retrieve the relative value of this plot (including plots that would be in city radius)280int CvCitySiteEvaluator::PlotFoundValue(CvPlot* pPlot, CvPlayer* pPlayer, YieldTypes eYield, bool)281{282	CvAssert(pPlot);283	if(!pPlot)284		return 0;285286	// Make sure this player can even build a city here287	if(!CanFound(pPlot, pPlayer, false))288	{289		return 0;290	}291292	int rtnValue = 0;293294	int iFoodValue = 0;295	int iHappinessValue = 0;296	int iProductionValue = 0;297	int iGoldValue = 0;298	int iScienceValue = 0;299	int iFaithValue = 0;300	int iResourceValue = 0;301	int iStrategicValue = 0;302303	int iCelticForestCount = 0;304	int iIroquoisForestCount = 0;305	int iBrazilJungleCount = 0;306	int iNaturalWonderCount = 0;307	int iDesertCount = 0;308	int iWetlandsCount = 0;309310	int iTotalFoodValue = 0;311	int iTotalHappinessValue = 0;312	int iTotalProductionValue = 0;313	int iTotalGoldValue = 0;314	int iTotalScienceValue = 0;315	int iTotalFaithValue = 0;316	int iTotalResourceValue = 0;317	int iTotalStrategicValue = 0;318319	int iClosestCityOfMine = 999;320	int iClosestEnemyCity = 999;321322	int iCapitalArea = NULL;323324	bool bIsInca = false;325	int iAdjacentMountains = 0;326327	if ( pPlayer->getCapitalCity() )328		iCapitalArea = pPlayer->getCapitalCity()->getArea();329330	// Custom code for Inca ideal terrace farm locations331	ImprovementTypes eIncaImprovement = (ImprovementTypes)GC.getInfoTypeForString("IMPROVEMENT_TERRACE_FARM", true);  332	if(eIncaImprovement != NO_IMPROVEMENT)333	{334		CvImprovementEntry* pkEntry = GC.getImprovementInfo(eIncaImprovement);335		if(pkEntry != NULL && pkEntry->IsSpecificCivRequired())336		{337			CivilizationTypes eCiv = pkEntry->GetRequiredCivilization();338			if(eCiv == pPlayer->getCivilizationType())339			{340				bIsInca = true;341			}342		}343	}344345	for (int iDX = -7; iDX <= 7; iDX++)346	{347		for (int iDY = -7; iDY <= 7; iDY++)348		{349			CvPlot* pLoopPlot = plotXY(pPlot->getX(), pPlot->getY(), iDX, iDY);350351			if (pLoopPlot != NULL)352			{353				int iDistance = plotDistance(pPlot->getX(), pPlot->getY(), pLoopPlot->getX(), pLoopPlot->getY());354				if (iDistance <= 7)355				{356					if ((pLoopPlot->getOwner() == NO_PLAYER) || (pLoopPlot->getOwner() == pPlayer->GetID()))357					{358						// See if there are other cities nearby359						if (iClosestCityOfMine > iDistance)360						{361							if (pLoopPlot->isCity())362							{363								iClosestCityOfMine = iDistance;364							}365						}366367						// Skip the city plot itself for now368						if (iDistance <= 5)369						{370							int iRingModifier = m_iRingModifier[iDistance];371372							iFoodValue = 0;373							iProductionValue = 0;374							iGoldValue = 0;375							iScienceValue = 0;376							iHappinessValue = 0;377							iResourceValue = 0;378							iStrategicValue = 0;379380#if defined(MOD_GLOBAL_CITY_WORKING)381							if (iDistance > 0 && iDistance <= pPlayer->getWorkPlotDistance())382#else	383							if (iDistance > 0 && iDistance <= NUM_CITY_RINGS)384#endif385							{386								if (eYield == NO_YIELD || eYield == YIELD_FOOD)387								{388									iFoodValue = iRingModifier * ComputeFoodValue(pLoopPlot, pPlayer) * /*15*/ GC.getSETTLER_FOOD_MULTIPLIER();389								}390								if (eYield == NO_YIELD || eYield == YIELD_PRODUCTION)391								{392									iProductionValue = iRingModifier * ComputeProductionValue(pLoopPlot, pPlayer) * /*3*/ GC.getSETTLER_PRODUCTION_MULTIPLIER();393								}394								if (eYield == NO_YIELD || eYield == YIELD_GOLD)395								{396									iGoldValue = iRingModifier * ComputeGoldValue(pLoopPlot, pPlayer) * /*2*/ GC.getSETTLER_GOLD_MULTIPLIER();397								}398								if (eYield == NO_YIELD || eYield == YIELD_SCIENCE)399								{400									iScienceValue = iRingModifier * ComputeScienceValue(pLoopPlot, pPlayer) * /*1*/ GC.getSETTLER_SCIENCE_MULTIPLIER();401								}402								if (eYield == NO_YIELD || eYield == YIELD_FAITH)403								{404									iFaithValue = iRingModifier * ComputeFaithValue(pLoopPlot, pPlayer) * /*1*/ GC.getSETTLER_FAITH_MULTIPLIER();405								}406#if defined(MOD_API_UNIFIED_YIELDS)407								// We don't flavour settle site choice by tourism - way to early for that!!!408#endif409							}410411							// whether or not we are working these we get the benefit as long as culture can grow to take them412							if (iDistance <= 5 && pLoopPlot->getOwner() == NO_PLAYER) // there is no benefit if we already own these tiles413							{414								iHappinessValue = iRingModifier * ComputeHappinessValue(pLoopPlot, pPlayer) * /*6*/ GC.getSETTLER_HAPPINESS_MULTIPLIER();415								iResourceValue = iRingModifier * ComputeTradeableResourceValue(pLoopPlot, pPlayer) * /*1*/ GC.getSETTLER_RESOURCE_MULTIPLIER();416								if (iDistance)417									iStrategicValue = ComputeStrategicValue(pLoopPlot, pPlayer, iDistance) * /*1*/ GC.getSETTLER_STRATEGIC_MULTIPLIER();  // the ring is included in the computation418							}419420							iTotalFoodValue += iFoodValue;421							iTotalHappinessValue += iHappinessValue;422							iTotalProductionValue += iProductionValue;423							iTotalGoldValue += iGoldValue;424							iTotalScienceValue += iScienceValue;425							iTotalFaithValue += iFaithValue;426							iTotalResourceValue += iResourceValue;427							iTotalStrategicValue += iStrategicValue;428429							int iPlotValue = iFoodValue + iHappinessValue + iProductionValue + iGoldValue + iScienceValue + iFaithValue + iResourceValue;430							431							if (iPlotValue == 0)432							{433								// this tile is so bad it gets negatives434								iPlotValue -= iRingModifier * GC.getSETTLER_FOOD_MULTIPLIER() * 2;435							}436							iPlotValue += iStrategicValue;437438							// if this tile is a NW boost the value just so that we force the AI to claim them (if we can work it)439#if defined(MOD_GLOBAL_CITY_WORKING)440							if (pLoopPlot->IsNaturalWonder() && iDistance > 0 && iDistance <= pPlayer->getWorkPlotDistance())441#else	442							if (pLoopPlot->IsNaturalWonder() && iDistance > 0 && iDistance <= NUM_CITY_RINGS)443#endif444							{445								//iPlotValue += iPlotValue * 2 + 10;446								iPlotValue += iPlotValue * 2 + 500;447							}448449							// lower value a lot if we already own this tile450							if (iPlotValue > 0 && pLoopPlot->getOwner() == pPlayer->GetID())451							{452								iPlotValue /= 4;453							}454455							// add this plot into the total456							rtnValue += iPlotValue;457458							FeatureTypes ePlotFeature = pLoopPlot->getFeatureType();459							ImprovementTypes ePlotImprovement = pLoopPlot->getImprovementType();460							ResourceTypes ePlotResource = pLoopPlot->getResourceType();461462							if (ePlotFeature == FEATURE_FOREST)463							{464								if (iDistance <= 5)465								{466									++iIroquoisForestCount;467									if (iDistance == 1)468									{469										if (ePlotImprovement == NO_IMPROVEMENT)470										{471											++iCelticForestCount;472										}473									}474								}475							}476							else if (ePlotFeature == FEATURE_JUNGLE)477							{478#if defined(MOD_GLOBAL_CITY_WORKING)479								if (iDistance <= pPlayer->getWorkPlotDistance())480#else	481								if (iDistance <= NUM_CITY_RINGS)482#endif483								{484									++iBrazilJungleCount;485								}486							}487							else if (ePlotFeature == FEATURE_MARSH || ePlotFeature == FEATURE_FLOOD_PLAINS)488							{489#if defined(MOD_GLOBAL_CITY_WORKING)490								if (iDistance <= pPlayer->getWorkPlotDistance())491#else	492								if (iDistance <= NUM_CITY_RINGS)493#endif494								{495									++iWetlandsCount;496								}497							}498499							if (pLoopPlot->IsNaturalWonder())500							{501								if (iDistance <= 1)502								{503									++iNaturalWonderCount;504								}505							}506507							if (pLoopPlot->getTerrainType() == TERRAIN_DESERT)508							{509#if defined(MOD_GLOBAL_CITY_WORKING)510								if (iDistance <= pPlayer->getWorkPlotDistance())511#else	512								if (iDistance <= NUM_CITY_RINGS)513#endif514								{515									if (ePlotResource == NO_RESOURCE)516									{517										++iDesertCount;518									}519								}520							}521522							if (bIsInca)523							{524								if (pLoopPlot->isHills())525								{526#if defined(MOD_GLOBAL_CITY_WORKING)527								if (iDistance <= pPlayer->getWorkPlotDistance())528#else	529								if (iDistance <= NUM_CITY_RINGS)530#endif531									{532										iAdjacentMountains = pLoopPlot->GetNumAdjacentMountains();533										if (iAdjacentMountains > 0 && iAdjacentMountains < 6)534										{535											//give the bonus if it's hills, with additional if bordered by mountains536											rtnValue += m_iIncaMultiplier + (iAdjacentMountains * m_iIncaMultiplier);537										}538									}539									540								}541							}542						}543					}544					else // this tile is owned by someone else545					{546						// See if there are other cities nearby (only count major civs)547						if (iClosestEnemyCity > iDistance)548						{549							if (pLoopPlot->isCity() && (pLoopPlot->getOwner() < MAX_MAJOR_CIVS))550							{551								iClosestEnemyCity = iDistance;552							}553						}554					}555				}556			}557		}558	}559560	if (pPlayer->GetPlayerTraits()->IsFaithFromUnimprovedForest())561	{562		if (iCelticForestCount >= 3)563		{564			rtnValue += 2 * 1000 * m_iFlavorMultiplier[YIELD_FAITH];565		}566		else if (iCelticForestCount >= 1)567		{568			rtnValue += 1 * 1000 * m_iFlavorMultiplier[YIELD_FAITH];569		}570	}571	else if (pPlayer->GetPlayerTraits()->IsMoveFriendlyWoodsAsRoad())572	{573		rtnValue += iIroquoisForestCount * 10;	574	}575	else if (pPlayer->GetPlayerTraits()->GetNaturalWonderYieldModifier() > 0)	//ie: Spain576	{577		rtnValue += iNaturalWonderCount * m_iSpainMultiplier;	578	}579580	// Custom code for Brazil581	ImprovementTypes eBrazilImprovement = (ImprovementTypes)GC.getInfoTypeForString("IMPROVEMENT_BRAZILWOOD_CAMP", true);  582	if(eBrazilImprovement != NO_IMPROVEMENT)583	{584		CvImprovementEntry* pkEntry = GC.getImprovementInfo(eBrazilImprovement);585		if(pkEntry != NULL && pkEntry->IsSpecificCivRequired())586		{587			CivilizationTypes eCiv = pkEntry->GetRequiredCivilization();588			if(eCiv == pPlayer->getCivilizationType())589			{590				rtnValue += iBrazilJungleCount * m_iBrazilMultiplier;591			}592		}593	}594595	// Custom code for Morocco596	ImprovementTypes eMoroccoImprovement = (ImprovementTypes)GC.getInfoTypeForString("IMPROVEMENT_KASBAH", true);  597	if(eMoroccoImprovement != NO_IMPROVEMENT)598	{599		CvImprovementEntry* pkEntry = GC.getImprovementInfo(eMoroccoImprovement);600		if(pkEntry != NULL && pkEntry->IsSpecificCivRequired())601		{602			CivilizationTypes eCiv = pkEntry->GetRequiredCivilization();603			if(eCiv == pPlayer->getCivilizationType())604			{605				rtnValue += iDesertCount * m_iMorrocoMultiplier;606			}607		}608	}609610	//Custom code for Netherlands611	ImprovementTypes ePolderImprovement = (ImprovementTypes)GC.getInfoTypeForString("IMPROVEMENT_POLDER", true);  612	if(ePolderImprovement != NO_IMPROVEMENT)613	{614		CvImprovementEntry* pkEntry = GC.getImprovementInfo(ePolderImprovement);615		if(pkEntry != NULL && pkEntry->IsSpecificCivRequired())616		{617			CivilizationTypes eCiv = pkEntry->GetRequiredCivilization();618			if(eCiv == pPlayer->getCivilizationType())619			{620				rtnValue += iWetlandsCount * m_iNetherlandsMultiplier;621			}622		}623	}624625	if (rtnValue < 0) rtnValue = 0;626627	// Finally, look at the city plot itself and use it as an overall multiplier628	if (pPlot->getResourceType(pPlayer->getTeam()) != NO_RESOURCE)629	{630		rtnValue += (int)rtnValue * /*-50*/ GC.getBUILD_ON_RESOURCE_PERCENT() / 100;631	}632633	if (pPlot->isRiver())634	{635		rtnValue += (int)rtnValue * /*15*/ GC.getBUILD_ON_RIVER_PERCENT() / 100;636	}637638	if (pPlot->isCoastalLand(GC.getMIN_WATER_SIZE_FOR_OCEAN()))639	{640		// okay, coast used to have lots of gold so players settled there "naturally", it doesn't any more, so I am going to give it a nudge in that direction641		// slewis - removed Brian(?)'s rtnValue adjustment and raised the BUILD_ON_COAST_PERCENT to 40 from 25642		//rtnValue += rtnValue > 0 ? 10 : 0;643		rtnValue += (int)rtnValue * /*40*/ GC.getSETTLER_BUILD_ON_COAST_PERCENT() / 100;644		int iNavalFlavor = pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)m_iNavalIndex);645		if (iNavalFlavor > 7)646		{647			rtnValue += (int)rtnValue * /*40*/ GC.getSETTLER_BUILD_ON_COAST_PERCENT() / 100;648		}649		if (pPlayer->getCivilizationInfo().isCoastalCiv()) // we really like the coast (England, Norway, Polynesia, Carthage, etc.)650		{651			rtnValue += rtnValue > 0 ? 25 : 0;652			rtnValue *= 2;653		}654	}655656	// Nearby Cities?657658	// Human659	if (pPlayer != NULL && pPlayer->isHuman())660	{661		if (iClosestCityOfMine == 3)662		{663			rtnValue /= 2;664		}665	}666	// AI667	else668	{669		int iGrowthFlavor = pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)m_iGrowthIndex);670		int iExpansionFlavor = pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)m_iExpansionIndex);671672		int iSweetSpot = 5;673		iSweetSpot += (iGrowthFlavor > 7) ?  1 : 0;674		iSweetSpot += (iExpansionFlavor > 7) ?  -1 : 0;675		iSweetSpot += (iGrowthFlavor < 4) ?  -1 : 0;676		iSweetSpot += (iExpansionFlavor < 4) ?  1 : 0;677		iSweetSpot = max(4,iSweetSpot);678		iSweetSpot = min(6,iSweetSpot);679680		if (iClosestCityOfMine == iSweetSpot) 681		{682			// 1.5 was not enough 2.0 was too much, so lets split the difference683			rtnValue *= 175;684			rtnValue /= 100;685		}686		else if (iClosestCityOfMine < iSweetSpot)687		{688			rtnValue /= 2;689		}690		else if (iClosestCityOfMine > 7)691		{692			rtnValue *= 2;693			rtnValue /= 3;694		}695696		// use boldness to decide if we want to push close to enemies697		int iBoldness = pPlayer->GetDiplomacyAI()->GetBoldness();698		if (iBoldness < 4)699		{700			if (iClosestEnemyCity <= 4)701			{702				rtnValue /= 4;703			}704			else if (iClosestEnemyCity == 5)705			{706				rtnValue /= 2;707			}708		}709		else if (iBoldness > 7)710		{711			if (iClosestEnemyCity <= 5 && iClosestCityOfMine < 8)712			{713				rtnValue *= 3;714				rtnValue /= 2;715			}716		}717		else718		{719			if (iClosestEnemyCity < 5)720			{721				rtnValue *= 2;722				rtnValue /= 3;723			}724		}725726		// if we are offshore, pull cities in tighter727		if (iCapitalArea != pPlot->getArea())728		{729			if (iClosestCityOfMine < 7)730			{731				rtnValue *= 3;732				rtnValue /= 2;733			}734		}735	}736737	rtnValue = (rtnValue > 0) ? rtnValue : 0;738739	return rtnValue;740}

Calls

Called by