Thanks. A quote of the code would be fine, and I can work it out from there.
Thanks,
M
// **************************
// 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();
}
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);
}
#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;
}
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;
}
Well, you did give him what he asked for...Okay, here are the relevant functions
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.
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
Got it, thanks. So, the corrected version is: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.