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

Going for Gold: Pantheons

Discussion in 'General Balance' started by Stalker0, May 16, 2018.

?

Is this item in a reasonable state of balance?

Poll closed May 30, 2018.
  1. Yes

    60.0%
  2. No

    40.0%
  1. Gidoza

    Gidoza Emperor

    Joined:
    Jul 26, 2013
    Messages:
    1,160
    I think border spread generally just needs to be re-wired. Ridiculously, it ends up being a balance issue if my border spread picks something awful and someone else's border spread randomly picks something good. Can't we just *select* where the border spread is going to go rather than dealing with this non-sensical system?
     
  2. pineappledan

    pineappledan Deity

    Joined:
    Aug 9, 2017
    Messages:
    5,002
    Gender:
    Male
    Location:
    Alberta, Canada
    ... I really don't want to micromanage borders...
     
    JamesNinelives likes this.
  3. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    The current border expansion system mostly makes sense to me. I don't remember the details but it's not random.
    Yes, that would be ideal. I just don't know if that's something which we can change or if it's difficult to do. Would anyone be against lakes being higher priority for border expansion?
     
    Last edited: Apr 7, 2020
  4. pineappledan

    pineappledan Deity

    Joined:
    Aug 9, 2017
    Messages:
    5,002
    Gender:
    Male
    Location:
    Alberta, Canada
    It’s very easy to do. Give me until this afternoon and I could tell you how. It’s just a matter of updating a single tile priority value in the SQL
     
    LifeOfBrian and JamesNinelives like this.
  5. azum4roll

    azum4roll King

    Joined:
    Jul 17, 2018
    Messages:
    612
    Gender:
    Male
    I think the expansion prioritizes tiles in city connections first. Maybe don't build roads until the city expands to lakes?
     
  6. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    It's more than that though. I didn't notice until I started using purity. From what I can tell, land tiles at a similar distance (without resources or city connections) will almost always be selected before lake tiles.

    Spoiler :
    20200402153128_1.jpg


    Spoiler :
    20200402155858_1.jpg
     
  7. pineappledan

    pineappledan Deity

    Joined:
    Aug 9, 2017
    Messages:
    5,002
    Gender:
    Male
    Location:
    Alberta, Canada
    nevermind. It's not as simple as I thought.

    Lakes aren't really a feature, they are coast terrain with <10 tiles together. This means they appear on the map as "Lakes", but share a lot of their code with, including tile claim priority, with coast.
     
    JamesNinelives likes this.
  8. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    I knew it! I think I've seen them treated like other water tiles somewhere else as well. That is a pain though. Was hoping it would be easier to fix :(.
     
  9. HungryForFood

    HungryForFood Prince

    Joined:
    Oct 4, 2016
    Messages:
    399
    Location:
    Malaysia
    Don't think that's true; I remember tile acquisition used to prioritise lakes a while back, but not coasts.
     
  10. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    Are you sure? If you know how to read the code then you are always welcome to check yourself. Otherwise, I'm inclined to trust pdan.

    Looking around, it seems lakes not being picked was an issue back in 2016.
     
  11. HungryForFood

    HungryForFood Prince

    Joined:
    Oct 4, 2016
    Messages:
    399
    Location:
    Malaysia
    In CvCity::GetBuyablePlotList():

    Higher cost = less likely to acquire next.
    Code:
                       if (iResourceMod == 0) //no resource or ignored resource
                       {
    
                           // Water Plots claimed later
                           if (pLoopPlot->isWater() && !pLoopPlot->isLake())
                               iInfluenceCost += iPLOT_INFLUENCE_WATER_COST;
                           }
                       else
                           iInfluenceCost += iResourceMod;
    
    Water gets increased cost if not a resource tile, but lakes are specifically excluded.
    Code:
                       if (pLoopPlot->isLake())
                       {
                           iInfluenceCost += (iPLOT_INFLUENCE_NW_COST / 2);
                       }
    
    In fact, lakes get a cost reduction.

    upload_2020-4-9_11-50-42.png

    There are the cost increase/decrease values. So cost of water is +20, while cost of lake is -500/2=-250, not to mention lakes have high base yield, so the yield point cost reduction applies too.

    Full function:
    Spoiler :
    Code:
    void CvCity::GetBuyablePlotList(std::vector<int>& aiPlotList, bool bForPurchase, int nChoices)
    {
       aiPlotList.clear();
       std::vector< pair<int,int> > resultList;
    
       CvPlot* pLoopPlot = NULL;
       CvPlot* pThisPlot = plot();
       const int iMaxRange = /*5*/ GC.getMAXIMUM_ACQUIRE_PLOT_DISTANCE();
       TeamTypes thisTeam = getTeam();
    
       int iPLOT_INFLUENCE_DISTANCE_MULTIPLIER =   /*100*/ GC.getPLOT_INFLUENCE_DISTANCE_MULTIPLIER();
       int iPLOT_INFLUENCE_RING_COST =               /*100*/ GC.getPLOT_INFLUENCE_RING_COST();
       int iPLOT_INFLUENCE_RESOURCE_COST =           /*-150*/ GC.getPLOT_INFLUENCE_RESOURCE_COST();
       int iPLOT_INFLUENCE_NW_COST =               /*-500*/ GC.getPLOT_INFLUENCE_NW_COST();
       int iPLOT_INFLUENCE_WATER_COST =           /* 20*/ GC.getPLOT_INFLUENCE_WATER_COST();
       int iPLOT_INFLUENCE_YIELD_POINT_COST =       /*-10*/   GC.getPLOT_INFLUENCE_YIELD_POINT_COST();
       int iPLOT_INFLUENCE_NO_ADJACENT_OWNED_COST = /*1000*/ GC.getPLOT_INFLUENCE_NO_ADJACENT_OWNED_COST();
       int iPLOT_INFLUENCE_ADJACENT_NW_COST = -3;
       int iPLOT_INFLUENCE_ADJACENT_RESOURCE_COST = -2;
       int iPLOT_INFLUENCE_ADJACENT_ENEMY_COST = -1;
    
       int iYieldLoop;
       int iDirectionLoop;
       bool bFoundAdjacentOwnedByCity;
    
       SPathFinderUserData data(getOwner(), PT_CITY_INFLUENCE, iMaxRange);
       ReachablePlots influencePlots = GC.GetStepFinder().GetPlotsInReach( pThisPlot, data );
    
       int iWorkPlotDistance = getWorkPlotDistance();
       ImprovementTypes eBarbCamptype = (ImprovementTypes)GC.getBARBARIAN_CAMP_IMPROVEMENT();
    
       for (int iDX = -iMaxRange; iDX <= iMaxRange; iDX++)
       {
           for (int iDY = -iMaxRange; iDY <= iMaxRange; iDY++)
           {
               pLoopPlot = plotXYWithRangeCheck(getX(), getY(), iDX, iDY, iMaxRange);
               if (pLoopPlot != NULL)
               {
                   if (pLoopPlot->getOwner() != NO_PLAYER)
                   {
    #if defined(MOD_BALANCE_CORE)
                       if(MOD_BALANCE_CORE && GET_PLAYER(getOwner()).GetPlayerTraits()->IsBuyOwnedTiles() && bForPurchase)
                       {
                           if(pLoopPlot->getOwner() == getOwner() || pLoopPlot->isCity())
                           {
                               continue;
                           }
                       }
                       else
                       {
    #endif
                       continue;
    #if defined(MOD_BALANCE_CORE)
                       }
    #endif
                   }
    #if defined(MOD_BALANCE_CORE)
                   //Let's rule out getting plots for which we lack an adjacent owned plot.
                   bool bNoNeighbor = true;
                   bool bPromiseNeighbor = false;
                   for (int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)
                   {
                       CvPlot* pAdjacentPlot = plotDirection(pLoopPlot->getX(), pLoopPlot->getY(), ((DirectionTypes)iI));
    
                       if (pAdjacentPlot != NULL)
                       {
                           if(pAdjacentPlot->getOwner() == getOwner() && pAdjacentPlot->getOwningCityID()==GetID())
                           {
                               bNoNeighbor = false;
                               break;
                           }
                           if(bForPurchase && pAdjacentPlot->getOwner() != NO_PLAYER && !GET_PLAYER(pAdjacentPlot->getOwner()).isMinorCiv())
                           {
                               if(GET_PLAYER(pAdjacentPlot->getOwner()).GetDiplomacyAI()->GetPlayerMadeBorderPromise(getOwner()))
                               {
                                   bPromiseNeighbor = true;
                                   break;
                               }
                           }
                       }
                   }
                   if(bNoNeighbor)
                   {
                       continue;
                   }
                   if(bPromiseNeighbor)
                   {
                       continue;
                   }
    #endif
    #if defined(MOD_EVENTS_CITY_BORDERS)
                   // This can be used to implement a 12-mile limit
                   if (MOD_EVENTS_CITY_BORDERS) {
                       if (GAMEEVENTINVOKE_TESTALL(GAMEEVENT_CityCanAcquirePlot, getOwner(), GetID(), pLoopPlot->getX(), pLoopPlot->getY()) == GAMEEVENTRETURN_FALSE) {
                           continue;
                       }
                   } else {
    #endif               
                   ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();
                   if (pkScriptSystem)
                   {
                       CvLuaArgsHandle args;
                       args->Push(getOwner());
                       args->Push(GetID());
                       args->Push(pLoopPlot->getX());
                       args->Push(pLoopPlot->getY());
    
                       bool bResult = false;
                       if (LuaSupport::CallTestAll(pkScriptSystem, "CityCanAcquirePlot", args.get(), bResult))
                       {
                           if (bResult == false) {
                               continue;
                           }
                       }
                   }
    #if defined(MOD_EVENTS_CITY_BORDERS)
                   }
    #endif           
    
                   ReachablePlots::iterator it = influencePlots.find( pLoopPlot->GetPlotIndex() );
                   int iInfluenceCost = ( it != influencePlots.end() ) ? it->iNormalizedDistanceRaw : -1;
    
                   if (iInfluenceCost >= 0)
                   {
                       iInfluenceCost *= iPLOT_INFLUENCE_DISTANCE_MULTIPLIER;
    
                       // Resource Plots claimed first
                       int iResourceMod = 0;
                       ResourceTypes eResource = pLoopPlot->getResourceType(thisTeam);
                       if (eResource != NO_RESOURCE)
                       {
                           CvResourceInfo *pkResource = GC.getResourceInfo(eResource);
                           if (pkResource)
                           {
                               if (pkResource->getResourceUsage() == RESOURCEUSAGE_LUXURY || pkResource->getResourceUsage() == RESOURCEUSAGE_STRATEGIC)
                                   iResourceMod += iPLOT_INFLUENCE_RESOURCE_COST;
                               else if (plotDistance(pLoopPlot->getX(),pLoopPlot->getY(),getX(),getY()) <= iWorkPlotDistance)
                                   //bonus resources are meh, even if they are in range
                                   iResourceMod += iPLOT_INFLUENCE_RESOURCE_COST/2;
                           }
                       }
    
                       if (iResourceMod == 0) //no resource or ignored resource
                       {
    
                           // Water Plots claimed later
                           if (pLoopPlot->isWater() && !pLoopPlot->isLake())
                               iInfluenceCost += iPLOT_INFLUENCE_WATER_COST;
                           }
                       else
                           iInfluenceCost += iResourceMod;
    
                       // if we can't work this tile in this city make it much less likely to be picked
                       if (plotDistance(pLoopPlot->getX(),pLoopPlot->getY(),getX(),getY()) > iWorkPlotDistance)
                       {
                           iInfluenceCost += iPLOT_INFLUENCE_RING_COST*2;
                       }
    
                       // avoid barbarian camps
                       ImprovementTypes thisImprovement = pLoopPlot->getImprovementType();
                       if (thisImprovement == eBarbCamptype)
                       {
                           iInfluenceCost += iPLOT_INFLUENCE_RING_COST;
                       }
    
                       // while we're at it grab Natural Wonders quickly also
                       if (pLoopPlot->IsNaturalWonder())
                       {
                           iInfluenceCost += iPLOT_INFLUENCE_NW_COST;
                       }
    
                       if (pLoopPlot->isLake())
                       {
                           iInfluenceCost += (iPLOT_INFLUENCE_NW_COST / 2);
                       }
    
                       // More Yield == more desirable
                       for (iYieldLoop = 0; iYieldLoop < NUM_YIELD_TYPES; iYieldLoop++)
                       {
                           //Simplification - errata yields not worth considering.
                           if ((YieldTypes)iYieldLoop > YIELD_GOLDEN_AGE_POINTS && !MOD_BALANCE_CORE_JFD)
                               break;
    
                           int iWeight = (iYieldLoop == GetCityStrategyAI()->GetMostDeficientYield()) ? 3 : 1;
    
                           iInfluenceCost += (iPLOT_INFLUENCE_YIELD_POINT_COST * pLoopPlot->getYield((YieldTypes) iYieldLoop) * iWeight);
                       }
    
                       // all other things being equal move towards unclaimed resources
                       bool bUnownedNaturalWonderAdjacentCount = false;
                       bool bEnemyPlotAdjacent = false;
                       for (int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)
                       {
                           CvPlot* pAdjacentPlot = plotDirection(pLoopPlot->getX(), pLoopPlot->getY(), ((DirectionTypes)iI));
    
                           if (pAdjacentPlot != NULL)
                           {
                               if (pAdjacentPlot->getOwner() == NO_PLAYER)
                               {
                                   int iPlotDistance = plotDistance(getX(), getY(), pAdjacentPlot->getX(), pAdjacentPlot->getY());
                                   ResourceTypes eAdjacentResource = pAdjacentPlot->getResourceType(thisTeam);
                                   if (eAdjacentResource != NO_RESOURCE)
                                   {
                                       // if we are close enough to work, or this is not a bonus resource
                                       if (iPlotDistance <= iWorkPlotDistance || GC.getResourceInfo(eAdjacentResource)->getResourceUsage() != RESOURCEUSAGE_BONUS)
                                       {
                                           iInfluenceCost += iPLOT_INFLUENCE_ADJACENT_RESOURCE_COST;
                                       }
                                   }
    
                                   if (iPlotDistance <= iWorkPlotDistance) // grab for this city
                                   {
                                       if (pAdjacentPlot->IsNaturalWonder())
                                           bUnownedNaturalWonderAdjacentCount = true;
    
                                       if (pAdjacentPlot->getOwner() != NO_PLAYER && pAdjacentPlot->getTeam() != getTeam())
                                           bEnemyPlotAdjacent = true;
                                   }
                               }
                           }
                       }
    
                       // move towards unclaimed NW
                       if (bUnownedNaturalWonderAdjacentCount)
                           iInfluenceCost += iPLOT_INFLUENCE_ADJACENT_NW_COST;
    
                       // move towards enemy
                       if (bEnemyPlotAdjacent)
                           iInfluenceCost += iPLOT_INFLUENCE_ADJACENT_ENEMY_COST;
    
                       // Plots not adjacent to another Plot acquired by this City are pretty much impossible to get
                       bFoundAdjacentOwnedByCity = false;
                       for (iDirectionLoop = 0; iDirectionLoop < NUM_DIRECTION_TYPES; iDirectionLoop++)
                       {
                           CvPlot* pAdjacentPlot = plotDirection(pLoopPlot->getX(), pLoopPlot->getY(), (DirectionTypes) iDirectionLoop);
    
                           if (pAdjacentPlot != NULL)
                           {
                               // Have to check plot ownership first because the City IDs match between different players!!!
                               if (pAdjacentPlot->getOwner() == getOwner() && pAdjacentPlot->GetCityPurchaseID() == GetID())
                               {
                                   bFoundAdjacentOwnedByCity = true;
                                   break;
                               }
                           }
                       }
    
                       if (!bFoundAdjacentOwnedByCity)
                       {
                           iInfluenceCost += iPLOT_INFLUENCE_NO_ADJACENT_OWNED_COST;
                       }
    
                       resultList.push_back( std::make_pair(iInfluenceCost,pLoopPlot->GetPlotIndex()) );
                   }
               }
           }
       }
    
       //we want only the best
       std::sort( resultList.begin(), resultList.end() );
       if (resultList.size()>(size_t)nChoices)
           resultList.erase( resultList.begin()+nChoices, resultList.end() );
    
       //throw away the cost, return the plot index only
       for (size_t i=0; i<resultList.size(); i++)
           //if there's a clear favorite, don't bother with the rest
           if (resultList[i].first - resultList[0].first <= 100)
               aiPlotList.push_back( resultList[i].second );
    }
    
     
    JamesNinelives likes this.
  12. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    OK. Thanks for the details.
    I have to wonder what's going on then, if there's something else that is over-riding it later on or something. At face value, lakes being relatively high priority doesn't jive with what I've been experiencing (see screenshots).
     
  13. Gidoza

    Gidoza Emperor

    Joined:
    Jul 26, 2013
    Messages:
    1,160
    I didn't mean that tiles should only be manually picked, but that the option should be there. I have luxury resources that often aren't picked over normal tiles. I'd be happy if this never happened.
     
  14. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    That's unusual. Cities usually do prioritize luxury and strategic resources in their expansion. Do you have a screenshot? The only situation I've seen where normal tiles are picked first is when the luxuries are in the third ring and have few adjacent tiles, and there are unclaimed road/city-connection tiles - or that kind of thing.
     
  15. Gidoza

    Gidoza Emperor

    Joined:
    Jul 26, 2013
    Messages:
    1,160
    I'll pay attention for it and take some the next time I have a really annoying situation like it.

    BTW can you remind me how to take screenshots? I take them so infrequently that I actually don't remember how. :o Or perhaps because I'm using a Mac keyboard on a Windows computer and the way it's supposed to work never works...
     
    JamesNinelives likes this.
  16. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    When playing a game through Steam (which is how I play Civ) press F12 :).
     
  17. Gidoza

    Gidoza Emperor

    Joined:
    Jul 26, 2013
    Messages:
    1,160
    Thanks!
     
    JamesNinelives likes this.
  18. azum4roll

    azum4roll King

    Joined:
    Jul 17, 2018
    Messages:
    612
    Gender:
    Male
    I use Lightshot. Just press PrintScreen whenever you want and you can select any area on the screen to be captured. It also automatically goes into your clipboard so you can just Ctrl+V to upload to imgur (I don't like the bundled upload site - it has no image url).
     
  19. JamesNinelives

    JamesNinelives King

    Joined:
    Mar 16, 2019
    Messages:
    901
    Gender:
    Male
    Location:
    Australia
    What are considered the faith-heavy pantheons at the moment? Something like Ancestor Worship? I haven't really kept up, and it might help me make sense of who is founding (and in what order) in my games.

    Edit:
    God of the sea does seem good for faith, huh? IMO yields on fishing boats and per city are about as useful long term as a lot of other pantheons. Depending on the situation of course. I tend to only take it when I get sea-luxury starts. Spirit of the Desert, and Stars and Sky certainly seem good for faith to me too, kinda as a balance to the specific terrain. Open Sky seems good in general. I like that it encourages working tiles rather than specialists in a meaningful way, but yeah it might be too strong.
     
    Last edited: Apr 18, 2020
  20. crdvis16

    crdvis16 Emperor

    Joined:
    May 2, 2013
    Messages:
    1,072
    Does anyone use God-King? I'm attempting to use it as Spain (which seems like it might be the ideal civ to try it with) and it's actually really difficult to found. I'm set to found at ~t100 which is risky on Immortal and have been beaten out in a few games now. I'm going Progress and getting 5 cities up ASAP with shrines first in them all and it's just not enough. Maybe it's supposed to be used by a Tradition civ where you get 3 faith from your early policy and get to 5 pantheon followers quicker? Someone like India perhaps?

    It's kind of a weird pantheon. It's pretty low faith (like god of all creation or something) but also pretty weak in early yields so you're just banking on taking advantage mid/late game I guess if you can found anyway? Even with Spain it seems like you need a faith CS friend or a faith lux/monopoly to be sure you'll found.
     
    JamesNinelives likes this.

Share This Page