1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Diplomacy AI Development

Discussion in 'Community Patch Project' started by Recursive, Feb 14, 2020.

  1. darkstrat

    darkstrat Chieftain

    Joined:
    Jun 25, 2020
    Messages:
    47
    Gender:
    Male
    Is there a way I can enable this like some config file editing or some modmod? Honestly, I would be fine if this only existed for the human too.
     
    vyyt likes this.
  2. LifeOfBrian

    LifeOfBrian King

    Joined:
    Aug 21, 2019
    Messages:
    619
    Recursive, I'm still seeing a lot of early DoWs (turn 60-90) where my neighbour China bribed faraway Carthage, Poland and Babylon to DoW me. And even later on, around t110, when China was losing a war against Russia (having just lost a city and its capital being attacked), China still decided to spend money on bribing Poland to DoW me, even though I was at peace with China, instead of using it to bolster its defense. So perhaps that's something to be looked at, maybe code it more emphatically that if one of the AIs cities is being attacked or has been conquered, it won't bribe for DoWs except against civs that it is at war with and/or lost a city to?
     
    Recursive likes this.
  3. Ragic

    Ragic Chieftain

    Joined:
    Mar 5, 2020
    Messages:
    30
    Gender:
    Male
    just wanted to quickly add that even though I've made a couple of posts critical of the current build, I'm thrilled Vox Populi exists and I appreciate you guys considering the input of an obviously casual player.
     
  4. Recursive

    Recursive Covets Lands That You Currently Own Moderator

    Joined:
    Dec 19, 2017
    Messages:
    2,229
    Gender:
    Male
    I consider all feedback regardless of the source, I like making people happy and whether someone plays casually or is an expert they may have a good point.

    Obviously, I am still a mere human, and I'm more likely to respond well if criticism is presented constructively (as opposed to some of the angry incoherent ranting I've seen).
     
  5. Legen

    Legen King

    Joined:
    Sep 13, 2015
    Messages:
    830
    Instead of receiving units, it could be a large combat modifier for City-States instead.
     
    InkAxis likes this.
  6. DizzKneeLand33

    DizzKneeLand33 Fall from Heaven 2 still rocks

    Joined:
    Oct 14, 2004
    Messages:
    506
    Location:
    Kansas City
    Here is a thought regarding non-lasting friendships. I don't have this issue in my games (Emperor, Large, Fractal, 13/22) -- many friendships last throughout the game other than of course those with civs close in proximity (sooner or later there will be border disputes, which is a good thing). However, I play Vox with Tech Trading turned off and with Research Agreements turned on. So, there is actually some incentive for friendships (RA's) or at least to not go to war with someone with whom you have a RA. I find the current Diplomacy to be excellent imho (especially after the bribed wars was recently fixed) as a result.
     
    Kim Dong Un and Recursive like this.
  7. tommytoxen

    tommytoxen Warlord

    Joined:
    May 7, 2012
    Messages:
    227
    Gender:
    Male
    Location:
    worksop
    I like how now there's a sense of "historic" friendships and "historic" enemies. In my current game I've practically been friends with the same people and enemies with the same people all game from ancient to modern times.

    The only exception is where I've become aggressive myself. I warned you to stop spending spies, Napoleon. We'll settle this on the battlefield, old friend. Au revoir.
     
    Chaste and Kim Dong Un like this.
  8. Kim Dong Un

    Kim Dong Un The One & Unly Supporter

    Joined:
    Dec 17, 2017
    Messages:
    818
    Gender:
    Male
    Location:
    Pyongyang
    I've been doing this over the last few months as well with similar results. There's been a couple times in prior versions that saw questionable behaviour in terms of civs backstabbing me with low turns remaining on a RA, but everything has been great for the most part.
     
    DizzKneeLand33 likes this.
  9. Stalker0

    Stalker0 Baller Magnus

    Joined:
    Dec 31, 2005
    Messages:
    7,251
    How are War score and Peace Deal Max Value related, if at all? I have a 100 war score against Ottomans, but only a 131 value max peace deal, which seems awefully low.

    Spoiler :

    upload_2021-1-8_0-27-19.png
     
  10. Recursive

    Recursive Covets Lands That You Currently Own Moderator

    Joined:
    Dec 19, 2017
    Messages:
    2,229
    Gender:
    Male
    AI performs this calculation and then sets "max value" to -1x the deal value of the calculation for them.

    Code:
    /// Add appropriate items to pDeal based on what type of PeaceTreaty eTreaty is
    void CvDealAI::DoAddItemsToDealForPeaceTreaty(PlayerTypes eOtherPlayer, CvDeal* pDeal, PeaceTreatyTypes eTreaty, bool bMeSurrendering)
    {
       if(eTreaty < PEACE_TREATY_ARMISTICE)
       {
           return;
       }
       int iDuration = GC.getGame().GetDealDuration();
    
       PlayerTypes eLosingPlayer = bMeSurrendering ? GetPlayer()->GetID() : eOtherPlayer;
       CvPlayer* pLosingPlayer = &GET_PLAYER(eLosingPlayer);
       PlayerTypes eWinningPlayer = bMeSurrendering ? eOtherPlayer : GetPlayer()->GetID();
       pDeal->SetSurrenderingPlayer(eLosingPlayer);
       int iWarScore = pLosingPlayer->GetDiplomacyAI()->GetWarScore(eWinningPlayer);
    #if defined(MOD_DIPLOMACY_CIV4_FEATURES)
       bool bBecomeMyVassal = pLosingPlayer->GetDiplomacyAI()->IsVassalageAcceptable(eWinningPlayer, true);
       bool bRevokeMyVassals = false;
       // Reduce war score if losing player wants to become winning player's vassal
       if(MOD_DIPLOMACY_CIV4_FEATURES && bBecomeMyVassal)
       {
           iWarScore /= 2;
       }
       // Is losing player willing to revoke his vassals?
       if(MOD_DIPLOMACY_CIV4_FEATURES && iWarScore <= -85 && GET_TEAM(pLosingPlayer->getTeam()).GetNumVassals() > 0)
       {
           //If we're willing to do this, give less below.
           bRevokeMyVassals = true;
           iWarScore /= max(2, GET_TEAM(pLosingPlayer->getTeam()).GetNumVassals());
       }
       if(iWarScore < 0)
       {
           iWarScore *= -1;
       }
    #endif
    
       //strategic warscore adjustment
       if (!pLosingPlayer->HasCityInDanger(false,0))
           iWarScore = max(0, iWarScore - 10);
    
       int iPercentGoldToGive = iWarScore;
       int iPercentGPTToGive = (iWarScore / 2);
       bool bGiveUpCities = (iWarScore > 60);
       int iPercentCitiesGiveUp = (iWarScore / 5);
       bool bGiveUpStratResources = (iWarScore > 35);
       bool bGiveUpLuxuryResources = (iWarScore > 15);
       int iGiveUpLuxResources = iWarScore;
       int iGiveUpStratResources = (iWarScore / 4);
    
       pDeal->AddPeaceTreaty(eWinningPlayer, GC.getGame().getGameSpeedInfo().getPeaceDealDuration());
       pDeal->AddPeaceTreaty(eLosingPlayer, GC.getGame().getGameSpeedInfo().getPeaceDealDuration());
       DoAddPlayersAlliesToTreaty(eOtherPlayer, pDeal);
    
       CvCity* pLoopCity;
       int iCityLoop;
       // If the player only has one city then we can't get any more from him
       if (bGiveUpCities && iPercentCitiesGiveUp > 0 && pLosingPlayer->getNumCities() > 1)
       {
           int iTotalCityValue = 0;
    
           // Create vector of the losing players' Cities so we can see which are the closest to the winner
           CvWeightedVector<int> viCityValue;
    
           // Loop through all of the loser's Cities, looking only at valid ones.
           for(pLoopCity = pLosingPlayer->firstCity(&iCityLoop); pLoopCity != NULL; pLoopCity = pLosingPlayer->nextCity(&iCityLoop))
           {
               //do this from the winner's perspective!
               int iCurrentCityValue = GetCityValueForBuyer(pLoopCity, eLosingPlayer, eWinningPlayer, true);
               if (iCurrentCityValue == INT_MAX)
                   continue;
    
               //add up total city value of the loser (before danger and damage adjustment)
               iTotalCityValue += iCurrentCityValue;
    
               //Remember for later
               viCityValue.push_back(pLoopCity->GetID(), iCurrentCityValue);
           }
    
           // Sort the vector based on distance from winner's capital
           viCityValue.SortItems();
           int iSortedCityID;
    
           // Determine the value of Cities to be given up
           int iCityValueToSurrender = iTotalCityValue * iPercentCitiesGiveUp / 100;
           // 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 cheapest cities are
           for(int iSortedCityIndex = viCityValue.size() - 1; iSortedCityIndex > -1 ; iSortedCityIndex--)
           {
               iSortedCityID = viCityValue.GetElement(iSortedCityIndex);
               pLoopCity = pLosingPlayer->getCity(iSortedCityID);
    
               int iCurrentCityValue = GetCityValueForBuyer(pLoopCity, eLosingPlayer, eWinningPlayer, true);
               if (iCurrentCityValue == INT_MAX)
                   continue;
    
               // City is worth less than what is left to be added to the deal, so add it
               if (iCurrentCityValue < iCityValueToSurrender && iCurrentCityValue > 0)
               {
                   pDeal->AddCityTrade(eLosingPlayer, iSortedCityID);
                   iCityValueToSurrender -= iCurrentCityValue;
    
                   //Frontline cities count more than they're worth. Ideally they should satisfy the winner?
                   iCityValueToSurrender -= (pLoopCity->getDamage() * 10);
                   if (pLosingPlayer->GetPlotDanger(pLoopCity) > GC.getCITY_HIT_POINTS_HEALED_PER_TURN())
                       iCityValueToSurrender -= iCurrentCityValue / 10;
               }
           }
       }
       // Gold
       int iGold = 0;
       if (iPercentGoldToGive > 0)
       {
           iGold = pDeal->GetGoldAvailable(eLosingPlayer, TRADE_ITEM_GOLD);
           iGold = iGold * iPercentGoldToGive / 100;
           if(iGold > 0)
           {
               pDeal->AddGoldTrade(eLosingPlayer, iGold);
           }
       }
    
       // Gold per turn
       int iGPT = 0;
       if (iPercentGPTToGive > 0)
       {
           iGPT = pLosingPlayer->calculateGoldRate();
           int iGPTToGive = ((iGPT * iPercentGPTToGive) / 100);
    
           if (iGPTToGive >= iGPT-2)
           {
               iGPTToGive -= 2;
           }
    
           if (iGPTToGive > 0)
           {
               pDeal->AddGoldPerTurnTrade(eLosingPlayer, iGPTToGive, iDuration);
           }
       }
    
       // precalculate, it's expensive
       int iCurrentNetGoldOfReceivingPlayer = GET_PLAYER(eOtherPlayer).GetTreasury()->CalculateBaseNetGold();
    
       // Luxury Resources
       if(bGiveUpLuxuryResources && iGiveUpLuxResources > 0)
       {
           ResourceUsageTypes eUsage;
           ResourceTypes eResource;
           int iResourceQuantity = 1;
           int iTotalResourceValue = 0;
           CvWeightedVector<int> viResourceValue;
           for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)
           {
               eResource = (ResourceTypes) iResourceLoop;
    
               const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);
               if (pkResourceInfo == NULL)
                   continue;
    
               eUsage = pkResourceInfo->getResourceUsage();
    
               // Can't trade bonus Resources
               if (eUsage != RESOURCEUSAGE_LUXURY)
               {
                   continue;
               }
    
               iResourceQuantity = pLosingPlayer->getNumResourceAvailable(eResource, false);
    
               // Don't bother looking at this Resource if the other player doesn't even have any of it
               if (iResourceQuantity == 0)
               {
                   continue;
               }
           
               // Can only get 1 copy of a Luxury
               if (eUsage == RESOURCEUSAGE_LUXURY)
               {
                   iResourceQuantity = 1;
               }
    
               int iCurrentResourceValue = GetResourceValue(eResource, iResourceQuantity, GC.getGame().GetDealDuration(), true, eOtherPlayer, iCurrentNetGoldOfReceivingPlayer);
    
               if(iCurrentResourceValue == INT_MAX)
                   continue;
    
               if(iCurrentResourceValue > 0)
               {
                   // Get total city value of the loser
                   iTotalResourceValue += iCurrentResourceValue;
                   viResourceValue.push_back(eResource, iCurrentResourceValue);
               }
           }
           
           // Determine the value of Cities to be given up
           int iResourceValueToSurrender = (iTotalResourceValue * iGiveUpLuxResources) / 100;
    
           // Sort the vector based on value
           viResourceValue.SortItems();
           if(viResourceValue.size() > 0)
           {
               // 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 are
               for(int iSortedResourceIndex =  0; iSortedResourceIndex < viResourceValue.size(); iSortedResourceIndex++)
               {
                   ResourceTypes eResourceList = (ResourceTypes)viResourceValue.GetElement(iSortedResourceIndex);
    
                   int iCurrentResourceValue = GetResourceValue(eResourceList, 1,  GC.getGame().GetDealDuration(), true, eOtherPlayer, iCurrentNetGoldOfReceivingPlayer);
    
                   if(iCurrentResourceValue == INT_MAX)
                       continue;
    
                   // City is worth less than what is left to be added to the deal, so add it
                   if(iCurrentResourceValue <= iResourceValueToSurrender && iCurrentResourceValue > 0)
                   {
                       pDeal->AddResourceTrade(eLosingPlayer, eResourceList, 1, GC.getGame().GetDealDuration());
                       iResourceValueToSurrender -= iCurrentResourceValue;
                   }
               }
           }
       }
       // Strategic Resources
       if(bGiveUpStratResources && iGiveUpStratResources > 0)
       {
           ResourceUsageTypes eUsage;
           ResourceTypes eResource;
           int iResourceQuantity = 1;
           int iTotalResourceValue = 0;
           CvWeightedVector<int> viResourceValue;
           for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)
           {
               eResource = (ResourceTypes) iResourceLoop;
    
               const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);
               if (pkResourceInfo == NULL)
                   continue;
    
               eUsage = pkResourceInfo->getResourceUsage();
    
               // Can't trade bonus Resources
               if (eUsage != RESOURCEUSAGE_STRATEGIC)
               {
                   continue;
               }
    
               iResourceQuantity = pLosingPlayer->getNumResourceAvailable(eResource, false);
    
               // Don't bother looking at this Resource if the other player doesn't even have any of it
               if (iResourceQuantity == 0)
               {
                   continue;
               }
           
               if (iResourceQuantity > 3)
               {
                   iResourceQuantity = 3;
               }
    
               int iCurrentResourceValue = GetResourceValue(eResource, iResourceQuantity, GC.getGame().GetDealDuration(), true, eOtherPlayer, iCurrentNetGoldOfReceivingPlayer);
    
               if(iCurrentResourceValue == INT_MAX)
                   continue;
    
               if(iCurrentResourceValue > 0)
               {
                   // Get total city value of the loser
                   iTotalResourceValue += iCurrentResourceValue;
                   viResourceValue.push_back(eResource, iCurrentResourceValue);
               }
           }
           
           // Determine the value of Cities to be given up
           int iResourceValueToSurrender = (iTotalResourceValue * iGiveUpStratResources) / 100;
    
           // Sort the vector based on distance from winner's capital
           viResourceValue.SortItems();
           if(viResourceValue.size() > 0)
           {
               // 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 are
               for(int iSortedResourceIndex =  0; iSortedResourceIndex < viResourceValue.size(); iSortedResourceIndex++)
               {
                   ResourceTypes eResourceList = (ResourceTypes)viResourceValue.GetElement(iSortedResourceIndex);               
                   iResourceQuantity = pLosingPlayer->getNumResourceAvailable(eResourceList, false);
                   if (iResourceQuantity > 3)
                   {
                       iResourceQuantity = 3;
                   }
                   int iCurrentResourceValue = GetResourceValue(eResourceList, iResourceQuantity, GC.getGame().GetDealDuration(), true, eOtherPlayer, iCurrentNetGoldOfReceivingPlayer);
    
                   if(iCurrentResourceValue == INT_MAX)
                       continue;
    
                   // City is worth less than what is left to be added to the deal, so add it
                   if(iCurrentResourceValue < iResourceValueToSurrender && iCurrentResourceValue > 0)
                   {
                       pDeal->AddResourceTrade(eLosingPlayer, eResourceList, iResourceQuantity, GC.getGame().GetDealDuration());
                       iResourceValueToSurrender -= iCurrentResourceValue;
                   }
               }
           }
       }
    #if defined(MOD_DIPLOMACY_CIV4_FEATURES)
       if(MOD_DIPLOMACY_CIV4_FEATURES && bBecomeMyVassal)
       {
           pDeal->AddVassalageTrade(eLosingPlayer);
       }
       if(MOD_DIPLOMACY_CIV4_FEATURES && bRevokeMyVassals)
       {
           pDeal->AddRevokeVassalageTrade(eLosingPlayer);
       }
    
    #endif
    }
    
     
  11. CyberPhy

    CyberPhy Chieftain

    Joined:
    May 24, 2019
    Messages:
    69
    Gender:
    Male
    Location:
    U.S.A
    One new problem I noticed with the new patch, is the AI does not seem to care if I settle near them
     
    Ragic likes this.
  12. Rean

    Rean Chieftain

    Joined:
    Jun 11, 2016
    Messages:
    86
    Been the case for more than just this new patch, they don't really seem to care unless you straight up touch borders
     
  13. doublex55

    doublex55 Prince

    Joined:
    Jul 3, 2016
    Messages:
    520
    Yup. Settle in the location they were about to settle in the next turn? +10 we have no contested borders. it really should
    Include territory they would like to settle.
     
  14. wabab

    wabab Chieftain

    Joined:
    Mar 9, 2020
    Messages:
    12
    Been playing on the 1/9 patch, really liking the new AI. Haven't a chance to try the 1/15 patch with the new aggressiveness, but so far the AI is the best it's been. The "friendlier" AI is more unpredictable in a lot of ways now, since it's now not guaranteed that all civs will start to attack you once you start winning. Also really liking how long-lasting alliances form and aren't necessarily going to result in being backstabbed eventually. I'll have to play the newer patch and see how AI aggressiveness is (could stand to be ramped up a bit). Warmongering is in a good place now, you can capture cities and every civ won't immediately hate you; wars don't feel like a binary "defensive only" or "if I capture one city I may as well capture all of them" now. City trading is nice, it opens up a lot more strategic opportunities. I was pleasantly surprised by having some interesting city trades proposed. You can also liberate city states without going to war, which is nice. I think it's been stated before, but the AI values strategic resources way higher than they should during trades.

    I did notice some strange things though: doing certain actions can make other civs hostile to you permanently, but especially having religious differences. After resurrecting two different civs (albeit, keeping their capital cities), they immediately became hostile because of "religious differences." One civ (America) hadn't even founded a religion either. It could have been because I held their capital (though I captured it from a different civ), but that didn't appear in their list of grievances. Unless this is a bug, having certain actions make other civs permanently hostile doesn't feel like a good mechanic. Having the penalty decay over a long while would be fine.

    Other than that, the AI is in a really good spot now.
     
  15. Recursive

    Recursive Covets Lands That You Currently Own Moderator

    Joined:
    Dec 19, 2017
    Messages:
    2,229
    Gender:
    Male
    -160 to opinion if you own a civ's original capital, plus you're marked as untrustworthy which makes them hostile. It isn't religious differences...

    If you return it you should get a diplo bonus now. This functions as intended, only capitulated vassals will disregard you owning their capital/Holy City.

    Odd that it didn't appear in the list though, could you post a bug report with a savegame/screenshots?

    Thanks for the feedback!
     
  16. wabab

    wabab Chieftain

    Joined:
    Mar 9, 2020
    Messages:
    12
    Here are the screenshots, not sure if these are bugs though. If they are, I'll make a bug report:

    Here's Theodora, voluntary vassal, didn't capture capital (but converted her civ to my religion). Been hostile ever since (the negative modifiers for the WC and territorial disputes are recent).

    20210115184058_1.jpg
    Next we have Montezuma, whom I resurrected from another civ. Held onto their capital city, but the positive modifiers outweigh the negative. Also, the message the AI gave me was "religious differences."

    20210115184133_1.jpg
    Finally, here's Greece. Captured their original capital, but haven't had any problems with them since.

    20210115184235_1.jpg
    They only difference is that Greece was a forced vassal whereas the Byzantines and Aztecs were voluntary vassals. Not sure if that's what's driving the different opinions here and is the intended behavior.
     
  17. Recursive

    Recursive Covets Lands That You Currently Own Moderator

    Joined:
    Dec 19, 2017
    Messages:
    2,229
    Gender:
    Male
    Yeah, there is some unintended behavior here. Bug report with savegame/mod list would be appreciated.
     
  18. Stalker0

    Stalker0 Baller Magnus

    Joined:
    Dec 31, 2005
    Messages:
    7,251
    @Recursive, how come the Celts don't have a penalty to our diplomacy because of differing ideologies? Everyone else does, are there things that nullify it?

    Spoiler :

    upload_2021-1-20_0-41-10.png
     
  19. azum4roll

    azum4roll Emperor

    Joined:
    Jul 17, 2018
    Messages:
    1,331
    Gender:
    Male
    I guess it's unintended with the religious opinion change on Celts.

    Why's your map all empty?
     
  20. Stalker0

    Stalker0 Baller Magnus

    Joined:
    Dec 31, 2005
    Messages:
    7,251
    I had all features turned off as I am just doing the "end turn" of a SV, and it speeds things up just a tad.
     

Share This Page