Bazaar developer reference

CvDealAI::GetCityValue(int, int, bool, PlayerTypes, bool)

Defined in
CvDealAI.cpp, line 1354
Class
CvDealAI
Hook name
CivHooks::CvDealAI_GetCityValue

Hooks

static bool BeforeCvDealAI_GetCityValue(CvDealAI* self, int iX, int iY, bool bFromMe, PlayerTypes eOtherPlayer, bool bUseEvenValue, int& result);static void AfterCvDealAI_GetCityValue(CvDealAI* self, int iX, int iY, bool bFromMe, PlayerTypes eOtherPlayer, bool bUseEvenValue, int& result);static int ReplaceCvDealAI_GetCityValue(int (*original)(CvDealAI*, int, int, bool, PlayerTypes, bool), CvDealAI* self, int iX, int iY, bool bFromMe, PlayerTypes eOtherPlayer, bool bUseEvenValue);CivRegisterBefore<CivHooks::CvDealAI_GetCityValue>(host, &BeforeCvDealAI_GetCityValue);CivRegisterAfter<CivHooks::CvDealAI_GetCityValue>(host, &AfterCvDealAI_GetCityValue);CivRegisterReplace<CivHooks::CvDealAI_GetCityValue>(host, &ReplaceCvDealAI_GetCityValue);

Code

1353/// How much is a City worth?1354int CvDealAI::GetCityValue(int iX, int iY, bool bFromMe, PlayerTypes eOtherPlayer, bool bUseEvenValue)1355{1356	CvAssertMsg(GetPlayer()->GetID() != eOtherPlayer, "DEAL_AI: Trying to check value of City with oneself.  Please send Jon this with your last 5 autosaves and what changelist # you're playing.");13571358	int iItemValue = 0;13591360	CvCity* pCity = GC.getMap().plot(iX, iY)->getPlotCity();13611362	if(pCity != NULL)1363	{1364		iItemValue = 440 + (pCity->getPopulation() * 200);13651366		// add in the value of every plot this city owns (plus improvements and resources)1367		// okay, I'm only going to count in the 3-rings plots since we can't actually use any others (I realize there may be a resource way out there)13681369		int goldPerPlot = GetPlayer()->GetBuyPlotCost(); // this is how much ANY plot is worth to me right now13701371		int iGoldValueOfPlots = 0;1372		int iGoldValueOfImprovedPlots = 0;1373		int iGoldValueOfResourcePlots = 0;1374#if defined(MOD_GLOBAL_CITY_WORKING)1375		for(int iI = 0; iI < pCity->GetNumWorkablePlots(); iI++)1376#else1377		for(int iI = 0; iI < NUM_CITY_PLOTS; iI++)1378#endif1379		{1380			CvPlot* pLoopPlot = pCity->GetCityCitizens()->GetCityPlotFromIndex(iI);1381			if(NULL != pLoopPlot && pCity->GetID() == pLoopPlot->GetCityPurchaseID())1382			{1383				if(iI > 6)1384				{1385					iGoldValueOfPlots += goldPerPlot; // this is a bargain, but at least it's in the ballpark1386				}1387				if(pLoopPlot->getImprovementType() != NO_IMPROVEMENT)1388				{1389					iGoldValueOfImprovedPlots += goldPerPlot * 25;1390				}1391				ResourceTypes eResource = pLoopPlot->getNonObsoleteResourceType(GetPlayer()->getTeam());1392				if(eResource != NO_RESOURCE)1393				{1394					const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);1395					if (pkResourceInfo)1396					{1397						ResourceUsageTypes eUsage = pkResourceInfo->getResourceUsage();1398						int iResourceQuantity = pLoopPlot->getNumResource();1399						// Luxury Resource1400						if(eUsage == RESOURCEUSAGE_LUXURY)1401						{1402							int iNumTurns = min(1,GC.getGame().getMaxTurns() - GC.getGame().getGameTurn());1403							iNumTurns = max(120,iNumTurns); // let's not go hog wild here1404							int iHappinessFromResource = pkResourceInfo->getHappiness();1405							iGoldValueOfResourcePlots += (iResourceQuantity * iHappinessFromResource * iNumTurns * 2);	// Ex: 1 Silk for 4 Happiness * 30 turns * 2 = 2401406							// If we only have 1 of a Luxury then we value it much more1407							if(bFromMe)1408							{1409								if(GetPlayer()->getNumResourceAvailable(eResource) == 1)1410								{1411									iGoldValueOfResourcePlots += (iResourceQuantity * iHappinessFromResource * iNumTurns * 4);1412								}1413							}1414						}1415						// Strategic Resource1416						else if(eUsage == RESOURCEUSAGE_STRATEGIC)1417						{1418							int iNumTurns = 60; // okay, this is a reasonable estimate1419							iGoldValueOfResourcePlots += (iResourceQuantity * iNumTurns * 150 / 100);1420						}1421					}1422				}1423			}1424		}1425		iGoldValueOfImprovedPlots /= 100;14261427		iItemValue = iItemValue + iGoldValueOfPlots + iGoldValueOfImprovedPlots + iGoldValueOfResourcePlots;14281429		// add in the (gold) value of the buildings (Or should we?  Will they transfer?)14301431		// From this player - add extra weight (don't want the human giving the AI a bit of gold for good cities)1432		if(bFromMe)1433		{1434			// Wonders are nice1435			if(pCity->hasActiveWorldWonder())1436				iItemValue *= 2;14371438			// Adjust for how well a war against this player would go (or is going)1439			switch(GetPlayer()->GetDiplomacyAI()->GetWarProjection(eOtherPlayer))1440			{1441			case WAR_PROJECTION_DESTRUCTION:1442				iItemValue *= 100;1443				break;1444			case WAR_PROJECTION_DEFEAT:1445				iItemValue *= 180;1446				break;1447			case WAR_PROJECTION_STALEMATE:1448				iItemValue *= 220;1449				break;1450			case WAR_PROJECTION_UNKNOWN:1451				iItemValue *= 250;1452				break;1453			case WAR_PROJECTION_GOOD:1454				iItemValue *= 400;1455				break;1456			case WAR_PROJECTION_VERY_GOOD:1457				iItemValue *= 400;1458				break;1459			default:1460				CvAssertMsg(false, "DEAL_AI: AI player has no valid War Projection for City valuation.  Please send Jon this with your last 5 autosaves and what changelist # you're playing.")1461				iItemValue *= 300;1462				break;1463			}1464			iItemValue /= 100;14651466			// AI players should be less willing to trade cities when not at war1467			if(!GET_TEAM(GetTeam()).isAtWar(GET_PLAYER(eOtherPlayer).getTeam()))1468			{1469				iItemValue *= 2;1470			}14711472		}	// END bFromMe1473		else1474		{1475			CvPlayerAI& theOtherPlayer = GET_PLAYER(eOtherPlayer);1476			if(!GET_TEAM(GetTeam()).isAtWar(theOtherPlayer.getTeam()))1477			{1478				if(theOtherPlayer.isHuman())  // he is obviously trying to trick us1479				{1480					CvCity* pLoopCity;1481					int iCityLoop;1482					int iBestDistance = 99;1483					for(pLoopCity = m_pPlayer->firstCity(&iCityLoop); pLoopCity != NULL; pLoopCity = m_pPlayer->nextCity(&iCityLoop))1484					{1485						int iDistFromThisCity = plotDistance(iX, iY, pLoopCity->getX(), pLoopCity->getY());1486						if(iDistFromThisCity < iBestDistance)1487						{1488							iBestDistance = iDistFromThisCity;1489						}1490					}1491					iBestDistance = (iBestDistance > 4) ? iBestDistance : 5;1492					iItemValue /= iBestDistance - 4;1493					iItemValue = (iItemValue >= 100) ? iItemValue : 100;1494				}1495			}1496		}14971498		// slewis - Due to rule changes, value of major capitals should go up quite a bit because someone can win the game by owning them1499		if (pCity->IsOriginalMajorCapital())1500		{1501			iItemValue *= 2;1502		}1503	}15041505	// Are we trying to find the middle point between what we think this item is worth and what another player thinks it's worth?1506	if(bUseEvenValue)1507	{1508		iItemValue += GET_PLAYER(eOtherPlayer).GetDealAI()->GetCityValue(iX, iY, !bFromMe, GetPlayer()->GetID(), /*bUseEvenValue*/ false);15091510		iItemValue /= 2;1511	}15121513	return iItemValue;1514}

Calls

Called by