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}