Hooks
static bool BeforeCvDealAI_DoAddItemsToDealForPeaceTreaty(CvDealAI* self, PlayerTypes eOtherPlayer, CvDeal* pDeal, PeaceTreatyTypes eTreaty, bool bMeSurrendering);static void AfterCvDealAI_DoAddItemsToDealForPeaceTreaty(CvDealAI* self, PlayerTypes eOtherPlayer, CvDeal* pDeal, PeaceTreatyTypes eTreaty, bool bMeSurrendering);static void ReplaceCvDealAI_DoAddItemsToDealForPeaceTreaty(void (*original)(CvDealAI*, PlayerTypes, CvDeal*, PeaceTreatyTypes, bool), CvDealAI* self, PlayerTypes eOtherPlayer, CvDeal* pDeal, PeaceTreatyTypes eTreaty, bool bMeSurrendering);CivRegisterBefore<CivHooks::CvDealAI_DoAddItemsToDealForPeaceTreaty>(host, &BeforeCvDealAI_DoAddItemsToDealForPeaceTreaty);CivRegisterAfter<CivHooks::CvDealAI_DoAddItemsToDealForPeaceTreaty>(host, &AfterCvDealAI_DoAddItemsToDealForPeaceTreaty);CivRegisterReplace<CivHooks::CvDealAI_DoAddItemsToDealForPeaceTreaty>(host, &ReplaceCvDealAI_DoAddItemsToDealForPeaceTreaty);
Code
3381/// Add appropriate items to pDeal based on what type of PeaceTreaty eTreaty is3382void CvDealAI::DoAddItemsToDealForPeaceTreaty(PlayerTypes eOtherPlayer, CvDeal* pDeal, PeaceTreatyTypes eTreaty, bool bMeSurrendering)3383{3384 int iPercentGoldToGive = 0;3385 int iPercentGPTToGive = 0;3386 bool bGiveOpenBorders = false;3387 bool bGiveOnlyOneCity = false;3388 int iPercentCitiesGiveUp = 0; /* 100 = all but capital */3389 bool bGiveUpStratResources = false;3390 bool bGiveUpLuxuryResources = false;33913392 // Setup what needs to be given up based on the level of the treaty3393 switch (eTreaty)3394 {3395 case PEACE_TREATY_WHITE_PEACE:3396 // White Peace: nothing changes hands3397 break;33983399 case PEACE_TREATY_ARMISTICE:3400 iPercentGoldToGive = 50;3401 iPercentGPTToGive = 50;3402 break;34033404 case PEACE_TREATY_SETTLEMENT:3405 iPercentGoldToGive = 100;3406 iPercentGPTToGive = 100;3407 break;34083409 case PEACE_TREATY_BACKDOWN:3410 iPercentGoldToGive = 100;3411 iPercentGPTToGive = 100;3412 bGiveOpenBorders = true;3413 bGiveUpStratResources = true;3414 break;34153416 case PEACE_TREATY_SUBMISSION:3417 iPercentGoldToGive = 100;3418 iPercentGPTToGive = 100;3419 bGiveOpenBorders = true;3420 bGiveUpStratResources = true;3421 bGiveUpLuxuryResources = true;3422 break;34233424 case PEACE_TREATY_SURRENDER:3425 bGiveOnlyOneCity = true;3426 break;34273428 case PEACE_TREATY_CESSION:3429 iPercentCitiesGiveUp = 25;3430 iPercentGoldToGive = 50;3431 break;34323433 case PEACE_TREATY_CAPITULATION:3434 iPercentCitiesGiveUp = 33;3435 iPercentGoldToGive = 100;3436 break;34373438 case PEACE_TREATY_UNCONDITIONAL_SURRENDER:3439 iPercentCitiesGiveUp = 100;3440 iPercentGoldToGive = 100;3441 break;3442 }34433444 int iDuration = GC.getGame().GetDealDuration();34453446 PlayerTypes eLosingPlayer = bMeSurrendering ? GetPlayer()->GetID() : eOtherPlayer;3447 CvPlayer* pLosingPlayer = &GET_PLAYER(eLosingPlayer);3448 PlayerTypes eWinningPlayer = bMeSurrendering ? eOtherPlayer : GetPlayer()->GetID();3449 CvPlayer* pWinningPlayer = &GET_PLAYER(eWinningPlayer);34503451 DoAddPlayersAlliesToTreaty(eOtherPlayer, pDeal);34523453 CvCity* pLoopCity;3454 int iCityLoop;34553456 // Gold3457 int iGold = 0;3458 if (iPercentGoldToGive > 0)3459 {3460 iGold = pDeal->GetGoldAvailable(eLosingPlayer, TRADE_ITEM_GOLD);3461 if(iGold > 0)3462 {3463 iGold = iGold * iPercentGoldToGive / 100;34643465 if(pDeal->IsPossibleToTradeItem(eLosingPlayer, eWinningPlayer, TRADE_ITEM_GOLD, iGold))3466 {3467 pDeal->AddGoldTrade(eLosingPlayer, iGold);3468 }3469 }3470 }34713472 // Gold per turn3473 int iGPT = 0;3474 if (iPercentGPTToGive > 0)3475 {3476 iGPT = min(pLosingPlayer->calculateGoldRate(), pWinningPlayer->calculateGoldRate() / /*3*/ GC.getARMISTICE_GPT_DIVISOR());3477 if (iGPT > 0)3478 {3479 iGPT = iGPT * iPercentGPTToGive / 100;34803481 if(iGPT > 0 && pDeal->IsPossibleToTradeItem(eLosingPlayer, eWinningPlayer, TRADE_ITEM_GOLD_PER_TURN, iGPT, iDuration))3482 {3483 pDeal->AddGoldPerTurnTrade(eLosingPlayer, iGPT, iDuration);3484 }3485 }3486 }34873488 // Open Borders3489 if (bGiveOpenBorders)3490 {3491 if(pDeal->IsPossibleToTradeItem(eLosingPlayer, eWinningPlayer, TRADE_ITEM_OPEN_BORDERS))3492 {3493 pDeal->AddOpenBorders(eLosingPlayer, iDuration);3494 }3495 }34963497 // Resources3498 ResourceUsageTypes eUsage;3499 ResourceTypes eResource;3500 int iResourceQuantity;3501 for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)3502 {3503 eResource = (ResourceTypes) iResourceLoop;35043505 const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);3506 if (pkResourceInfo == NULL)3507 continue;35083509 eUsage = pkResourceInfo->getResourceUsage();35103511 // Can't trade bonus Resources3512 if(eUsage == RESOURCEUSAGE_BONUS)3513 {3514 continue;3515 }35163517 iResourceQuantity = pLosingPlayer->getNumResourceAvailable(eResource, false);35183519 // Don't bother looking at this Resource if the other player doesn't even have any of it3520 if (iResourceQuantity == 0)3521 {3522 continue;3523 }35243525 // Match with deal type3526 if (eUsage == RESOURCEUSAGE_LUXURY && !bGiveUpLuxuryResources)3527 {3528 continue;3529 }35303531 if (eUsage == RESOURCEUSAGE_STRATEGIC && !bGiveUpStratResources)3532 {3533 continue;3534 }35353536 // Can only get 1 copy of a Luxury3537 if (eUsage == RESOURCEUSAGE_LUXURY)3538 {3539 iResourceQuantity = 1;3540 }35413542 if(pDeal->IsPossibleToTradeItem(eLosingPlayer, eWinningPlayer, TRADE_ITEM_RESOURCES, eResource, iResourceQuantity))3543 {3544 pDeal->AddResourceTrade(eLosingPlayer, eResource, iResourceQuantity, iDuration);3545 }3546 }35473548 // Give up all but capital?3549 if (iPercentCitiesGiveUp == 100)3550 {3551 // All Cities but the capital3552 for(pLoopCity = pLosingPlayer->firstCity(&iCityLoop); pLoopCity != NULL; pLoopCity = pLosingPlayer->nextCity(&iCityLoop))3553 {3554 if(pLoopCity->isCapital())3555 {3556 continue;3557 }35583559 if(pDeal->IsPossibleToTradeItem(eLosingPlayer, eWinningPlayer, TRADE_ITEM_CITIES, pLoopCity->getX(), pLoopCity->getY()))3560 {3561 pDeal->AddCityTrade(eLosingPlayer, pLoopCity->GetID());3562 }3563 }3564 }35653566 // If the player only has 1 City then we can't get any more from him3567 else if (iPercentCitiesGiveUp > 0 || bGiveOnlyOneCity && pLosingPlayer->getNumCities() > 1)3568 {3569 int iCityValue = 0;3570 int iCityDistanceFromWinnersCapital = 0;3571 int iWinnerCapitalX = -1, iWinnerCapitalY = -1;35723573 // If winner has no capital then we can't use proximity - it will stay at 03574 CvCity* pWinnerCapital = pWinningPlayer->getCapitalCity();3575 if(pWinnerCapital != NULL)3576 {3577 iWinnerCapitalX = pWinnerCapital->getX();3578 iWinnerCapitalY = pWinnerCapital->getY();3579 }35803581 // Create vector of the losing players' Cities so we can see which are the closest to the winner3582 CvWeightedVector<int> viCityProximities;35833584 // Loop through all of the loser's Cities3585 for(pLoopCity = pLosingPlayer->firstCity(&iCityLoop); pLoopCity != NULL; pLoopCity = pLosingPlayer->nextCity(&iCityLoop))3586 {3587 // Get total city value of the loser3588 iCityValue += GetCityValue(pLoopCity->getX(), pLoopCity->getY(), bMeSurrendering, eOtherPlayer, /*bUseEvenValue*/ true);35893590 // If winner has no capital, Distance defaults to 03591 if(pWinnerCapital != NULL)3592 {3593 iCityDistanceFromWinnersCapital = plotDistance(iWinnerCapitalX, iWinnerCapitalY, pLoopCity->getX(), pLoopCity->getY());3594 }35953596 // Divide the distance by three if the city was originally owned by the winning player to make these cities more likely3597 if (pLoopCity->getOriginalOwner() == eWinningPlayer)3598 {3599 iCityDistanceFromWinnersCapital /= 3;3600 }36013602 // Don't include the capital in the list of Cities the winner can receive3603 if(!pLoopCity->isCapital())3604 {3605 viCityProximities.push_back(pLoopCity->GetID(), iCityDistanceFromWinnersCapital);3606 }3607 }36083609 // Sort the vector based on distance from winner's capital3610 viCityProximities.SortItems();3611 int iSortedCityID;36123613 // Just one city?3614 if (bGiveOnlyOneCity)3615 {3616 iSortedCityID = viCityProximities.GetElement(viCityProximities.size() - 1);3617 pDeal->AddCityTrade(eLosingPlayer, iSortedCityID);3618 }36193620 else3621 {3622 // Determine the value of Cities to be given up3623 int iCityValueToSurrender = iCityValue * iPercentCitiesGiveUp / 100;36243625 // Loop through sorted Cities and add them to the deal if they're under the amount to give up - start from the back of the list, because that's where the CLOSEST cities are3626 for(int iSortedCityIndex = viCityProximities.size() - 1; iSortedCityIndex > -1 ; iSortedCityIndex--)3627 {3628 iSortedCityID = viCityProximities.GetElement(iSortedCityIndex);3629 pLoopCity = pLosingPlayer->getCity(iSortedCityID);36303631 iCityValue = GetCityValue(pLoopCity->getX(), pLoopCity->getY(), bMeSurrendering, eOtherPlayer, /*bUseEvenValue*/ true);36323633 // City is worth less than what is left to be added to the deal, so add it3634 if(iCityValue < iCityValueToSurrender)3635 {3636 if(pDeal->IsPossibleToTradeItem(eLosingPlayer, eWinningPlayer, TRADE_ITEM_CITIES, pLoopCity->getX(), pLoopCity->getY()))3637 {3638 pDeal->AddCityTrade(eLosingPlayer, iSortedCityID);3639 iCityValueToSurrender -= iCityValue;3640 }3641 }3642 }3643 }3644 }3645}