Archid
Warlord
Just had a CTD in my current game that I have traced back to a K-Mod update. CvGameCoreUtils::getEspionageModifier() will return 0 if neither the spy owner nor the target have any espionage points. This is used as a multiplier in CvPlayer::getEspionageMissionCostModifier() which eventually ends up as a denominator in CvUnityAI::AI_getEspionageTargetValue() causing a divide by 0 error.
Looking at the code if neither side has any espionage points the value of ESPIONAGE_SPENDING_MULTIPLIER from the global defines should be used. The fix is very simple by wrapping the numerator values in a std::max in a similar way that the denominator already is:
Looking at the code if neither side has any espionage points the value of ESPIONAGE_SPENDING_MULTIPLIER from the global defines should be used. The fix is very simple by wrapping the numerator values in a std::max in a similar way that the denominator already is:
Spoiler :
Code:
int getEspionageModifier(TeamTypes eOurTeam, TeamTypes eTargetTeam)
{
FAssert(eOurTeam != eTargetTeam);
FAssert(eOurTeam != BARBARIAN_TEAM);
// FAssert(eTargetTeam != BARBARIAN_TEAM); // K-Mod note. This is possible for legitimate reasons (although, the result is never important...)
// K-Mod. Scale the points modifier based on the teams' population. (Note ESPIONAGE_SPENDING_MULTIPLIER is 100 in the default xml.)
const CvTeam& kOurTeam = GET_TEAM(eOurTeam);
const CvTeam& kTargetTeam = GET_TEAM(eTargetTeam);
int iPopScale = 5 * GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getTargetNumCities();
int iTargetPoints = 10 * kTargetTeam.getEspionagePointsEver() / std::max(1, iPopScale + kTargetTeam.getTotalPopulation(false));
int iOurPoints = 10 * kOurTeam.getEspionagePointsEver() / std::max(1, iPopScale + kOurTeam.getTotalPopulation(false));
return GC.getDefineINT("ESPIONAGE_SPENDING_MULTIPLIER") * [COLOR="Red"][B]std::max(1, [/B][/COLOR](2 * iTargetPoints + iOurPoints)[COLOR="Red"][B])[/B][/COLOR] / std::max(1, iTargetPoints + 2 * iOurPoints);
// K-Mod end
}