What's the formula for "Military near City-State"?

MIS

Prince
Joined
Dec 19, 2013
Messages
494
Location
Philly,
Thanks. A quote of the code would be fine, and I can work it out from there.

Thanks,
M
 
Thanks. A quote of the code would be fine, and I can work it out from there.

Thanks,
M

Okay, here are the relevant functions.

Code:
    // **************************
   // Local military power comparison
   //
   // +0 ~ +125
   // **************************
   CvCity* pMinorCapital = GetPlayer()->getCapitalCity();
   if(pMinorCapital == NULL)
       return iFailScore;

   pair<int, int> localPower = TacticalAIHelpers::EstimateLocalUnitPower( GetBullyRelevantPlots(), GetPlayer()->getTeam(), GET_PLAYER(eBullyPlayer).getTeam(), false);
   //don't forget the city itself
   int iLocalPowerRatio = int((localPower.second * 100.f) / (localPower.first + pMinorCapital->GetPower()));
   iScore += iLocalPowerRatio;

   if (sTooltipSink)
   {
       Localization::String strPositiveFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_POSITIVE");
       strPositiveFactor << iLocalPowerRatio;
       strPositiveFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_MILITARY_PRESENCE";
       sFactors += strPositiveFactor.toUTF8();
   }
Code:
pair<int, int> TacticalAIHelpers::EstimateLocalUnitPower(const ReachablePlots& plotsToCheck, TeamTypes eTeamA, TeamTypes eTeamB, bool bMustBeVisibleToBoth)
{
   if (plotsToCheck.empty())
       return make_pair(0, 0);

   int iTeamAPower = 0;
   int iTeamBPower = 0;

   for (ReachablePlots::const_iterator it = plotsToCheck.begin(); it != plotsToCheck.end(); ++it)
   {
       CvPlot* pLoopPlot = GC.getMap().plotByIndexUnchecked(it->iPlotIndex);
       if (!pLoopPlot)
           continue;

       if (bMustBeVisibleToBoth && !(pLoopPlot->isVisible(eTeamA) && pLoopPlot->isVisible(eTeamB)))
           continue;

       // If there are Units here, loop through them
       if (pLoopPlot->getNumUnits() > 0)
       {
           IDInfo* pUnitNode = pLoopPlot->headUnitNode();
           while (pUnitNode != NULL)
           {
               CvUnit* pLoopUnit = ::getUnit(*pUnitNode);
               pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);

               // Is a combat unit
               if (pLoopUnit && (pLoopUnit->IsCombatUnit() || pLoopUnit->getDomainType() == DOMAIN_AIR))
               {
                   int iScale = pLoopUnit->isNativeDomain(pLoopPlot) ? 1 : 2;

                   if (pLoopUnit->getTeam() == eTeamA)
                       iTeamAPower += pLoopUnit->GetPower() / iScale;
                   if (pLoopUnit->getTeam() == eTeamB)
                       iTeamBPower += pLoopUnit->GetPower() / iScale;
               }
           }
       }
   }

   return pair<int, int>(iTeamAPower,iTeamBPower);
}
Code:
#define MINOR_POWER_COMPARISON_RADIUS (6)

const ReachablePlots & CvMinorCivAI::GetBullyRelevantPlots()
{
   if (m_iBullyPlotsBuilt != GC.getGame().getGameTurn())
   {
       if (GetPlayer()->getCapitalCity())
       {
           //do not set a player - that way we can traverse unrevealed plots and foreign territory
           SPathFinderUserData data(NO_PLAYER, PT_GENERIC_REACHABLE_PLOTS, -1, MINOR_POWER_COMPARISON_RADIUS);
           m_bullyRelevantPlots = GC.GetStepFinder().GetPlotsInReach(GetPlayer()->getCapitalCity()->plot(), data);
           m_iBullyPlotsBuilt = GC.getGame().getGameTurn();
       }
       else
           m_bullyRelevantPlots.clear();
   }

   return m_bullyRelevantPlots;
}
Code:
WOUNDED_DAMAGE_MULTIPLIER = 50

//   --------------------------------------------------------------------------------
/// Current power of unit (raw unit type power adjusted for health)
int CvUnit::GetPower() const
{
   VALIDATE_OBJECT
   int iPower = getUnitInfo().GetPower();

#if defined(MOD_API_EXTENSIONS) && defined(MOD_BUGFIX_UNIT_POWER_CALC)
   if (getUnitInfo().GetRangedCombat() > getUnitInfo().GetCombat()) {
       iPower = iPower * GetBaseRangedCombatStrength() / getUnitInfo().GetRangedCombat();
   }
#endif
#if defined(MOD_BUGFIX_UNIT_POWER_CALC)
   else if (getUnitInfo().GetCombat() > 0) {
       iPower = iPower * GetBaseCombatStrength() / getUnitInfo().GetCombat();
   }
#endif
   
   //Take promotions into account: unit with 4 promotions worth ~50% more
   int iPowerMod = getLevel() * 125;
   iPower = (iPower * (1000 + iPowerMod)) / 1000;

   //Reduce power for damaged units
   int iDamageMod = m_iDamage * GC.getWOUNDED_DAMAGE_MULTIPLIER() / 100;
   iPower -= (iPower * iDamageMod / GetMaxHitPoints());

   return iPower;
}
 
That's great @HeathcliffWarriors , thanks:
Units need to be within 6 tiles, and visible to CS. No advantage to be closer.
Depends on units' base strength, #Promotions (+12.5% each), and health (1-%wounded/2) (e.g. 80% healthy counts 90%).
Compared to City State's City + Units' Strength, affected by level (e.g. Deity)
Between 0-125%.
 
That's great @HeathcliffWarriors , thanks:
Units need to be within 6 tiles, and visible to CS. No advantage to be closer.
Depends on units' base strength, #Promotions (+12.5% each), and health (1-%wounded/2) (e.g. 80% healthy counts 90%).
Compared to City State's City + Units' Strength, affected by level (e.g. Deity)
Between 0-125%.

Level means how many times the unit has been promoted, not the difficulty level. Also bMustBeVisibleToBoth is false, thus it does not need to be visible to the CS.

The 0-125 range is a comment in the code and may be outdated.
 
Level means how many times the unit has been promoted, not the difficulty level. Also bMustBeVisibleToBoth is false, thus it does not need to be visible to the CS.

The 0-125 range is a comment in the code and may be outdated.

Thanks. On Level, there is a modifier "TacticalAIHelpers" which I assumed was related to the game level. Was that wrong?

I also assumed that the City States units' strengths was calculated in a similar way to the human players (Base Strength, #Promotions, %Health); I should have been clearer on that.

Thanks again,
M
 
Thanks. On Level, there is a modifier "TacticalAIHelpers" which I assumed was related to the game level. Was that wrong?

I also assumed that the City States units' strengths was calculated in a similar way to the human players (Base Strength, #Promotions, %Health); I should have been clearer on that.

Thanks again,
M

TacticalAIHelpers refers to a function tied to the Tactical AI (which governs the lowest level of AI civ/CS unit movement). In the code, the keyword anything to do with difficulty levels uses is "handicap".

Human, AI and CS units all use the same power calculation.
 
TacticalAIHelpers refers to a function tied to the Tactical AI (which governs the lowest level of AI civ/CS unit movement). In the code, the keyword anything to do with difficulty levels uses is "handicap".

Human, AI and CS units all use the same power calculation.
Got it, thanks. So, the corrected version is:
MajorCiv Units need to be within 6 tiles
Units' power (MajorCiv and City-State) = Base Power * (1+ 12.5% *#Promotions) * (1-%Wounded/2)
Compare MajorCiv Units to City-State City+Units.

Thanks,
M
 
The 6 tiles distance requirement is a thing of the past, now it is based on units movement/terrain roughness, basically you have to be in 3 turns of movement from the CS (roads help, distance at sea is still bugged - you don't need to know fishing to count as embarked/in cs range afaik).
 
Top Bottom