Bazaar developer reference

CvUnit::getCombatDamage(int, int, int, bool, bool, bool) const

Defined in
CvUnit.cpp, line 3419
Class
CvUnit
Hook name
CivHooks::CvUnit_getCombatDamage

Hooks

static bool BeforeCvUnit_getCombatDamage(const CvUnit* self, int iStrength, int iOpponentStrength, int iCurrentDamage, bool bIncludeRand, bool bAttackerIsCity, bool bDefenderIsCity, int& result);static void AfterCvUnit_getCombatDamage(const CvUnit* self, int iStrength, int iOpponentStrength, int iCurrentDamage, bool bIncludeRand, bool bAttackerIsCity, bool bDefenderIsCity, int& result);static int ReplaceCvUnit_getCombatDamage(int (*original)(const CvUnit*, int, int, int, bool, bool, bool), const CvUnit* self, int iStrength, int iOpponentStrength, int iCurrentDamage, bool bIncludeRand, bool bAttackerIsCity, bool bDefenderIsCity);CivRegisterBefore<CivHooks::CvUnit_getCombatDamage>(host, &BeforeCvUnit_getCombatDamage);CivRegisterAfter<CivHooks::CvUnit_getCombatDamage>(host, &AfterCvUnit_getCombatDamage);CivRegisterReplace<CivHooks::CvUnit_getCombatDamage>(host, &ReplaceCvUnit_getCombatDamage);

Code

3419int CvUnit::getCombatDamage(int iStrength, int iOpponentStrength, int iCurrentDamage, bool bIncludeRand, bool bAttackerIsCity, bool bDefenderIsCity) const3420{3421	VALIDATE_OBJECT3422	// The roll will vary damage between 40 and 60 (out of 100) for two units of identical strength34233424	int iDamageRatio;34253426	int iWoundedDamageMultiplier = /*50*/ GC.getWOUNDED_DAMAGE_MULTIPLIER();34273428	if(bAttackerIsCity)3429	{3430#if defined(MOD_UNITS_MAX_HP)3431		// Yeah, given the comment on the line below it looks weird, but the max HP of cities isn't GC.getMAX_HIT_POINTS() but pCity->GetMaxHitPoints(), so this works3432		iDamageRatio = GetMaxHitPoints();		// JON: Cities don't do less damage when wounded3433#else3434		iDamageRatio = GC.getMAX_HIT_POINTS();		// JON: Cities don't do less damage when wounded3435#endif3436	}3437	else3438	{3439		// Mod (Policies, etc.)3440		iWoundedDamageMultiplier += GET_PLAYER(getOwner()).GetWoundedUnitDamageMod();34413442#if defined(MOD_UNITS_MAX_HP)3443		iDamageRatio = GetMaxHitPoints() - (iCurrentDamage * iWoundedDamageMultiplier / 100);3444#else3445		iDamageRatio = GC.getMAX_HIT_POINTS() - (iCurrentDamage * iWoundedDamageMultiplier / 100);3446#endif3447	}34483449	int iDamage = 0;34503451#if defined(MOD_UNITS_MAX_HP)3452	iDamage = /*400*/ GC.getATTACK_SAME_STRENGTH_MIN_DAMAGE() * iDamageRatio / GetMaxHitPoints();3453#else3454	iDamage = /*400*/ GC.getATTACK_SAME_STRENGTH_MIN_DAMAGE() * iDamageRatio / GC.getMAX_HIT_POINTS();3455#endif34563457	// Don't use rand when calculating projected combat results3458	int iRoll = 0;3459	if(bIncludeRand)3460	{3461		iRoll = /*400*/ GC.getGame().getJonRandNum(GC.getATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE(), "Unit Combat Damage");3462		iRoll *= iDamageRatio;3463#if defined(MOD_UNITS_MAX_HP)3464		iRoll /= GetMaxHitPoints();3465#else3466		iRoll /= GC.getMAX_HIT_POINTS();3467#endif3468	}3469	else3470	{3471		iRoll = /*400*/ GC.getATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE();3472		iRoll -= 1;	// Subtract 1 here, because this is the amount normally "lost" when doing a rand roll3473		iRoll *= iDamageRatio;3474#if defined(MOD_UNITS_MAX_HP)3475		iRoll /= GetMaxHitPoints();3476#else3477		iRoll /= GC.getMAX_HIT_POINTS();3478#endif3479		iRoll /= 2;	// The divide by 2 is to provide the average damage3480	}3481	iDamage += iRoll;34823483	// Calculations performed to dampen amount of damage by units that are close in strength3484	// RATIO = (((((ME / OPP) + 3) / 4) ^ 4) + 1) / 23485	// Examples:3486	// 1.301 = (((((9 / 6) + 3) / 4) ^ 4) + 1 / 23487	// 17.5 = (((((40 / 6) + 3) / 4) ^ 4) + 1 / 234883489	double fStrengthRatio = (double(iStrength) / iOpponentStrength);34903491	// In case our strength is less than the other guy's, we'll do things in reverse then make the ratio 1 over the result (we need a # above 1.0)3492	if(iOpponentStrength > iStrength)3493	{3494		fStrengthRatio = (double(iOpponentStrength) / iStrength);3495	}34963497	fStrengthRatio = (fStrengthRatio + 3) / 4;3498	fStrengthRatio = pow(fStrengthRatio, 4.0);3499	fStrengthRatio = (fStrengthRatio + 1) / 2;35003501	if(iOpponentStrength > iStrength)3502	{3503		fStrengthRatio = 1 / fStrengthRatio;3504	}35053506	iDamage = int(iDamage * fStrengthRatio);35073508	// Modify damage for when a city "attacks" a unit3509	if(bAttackerIsCity)3510	{3511		iDamage *= /*50*/ GC.getCITY_ATTACKING_DAMAGE_MOD();3512		iDamage /= 100;3513	}35143515	// Modify damage for when unit is attacking a city3516	if(bDefenderIsCity)3517	{3518		iDamage *= /*100*/ GC.getATTACKING_CITY_MELEE_DAMAGE_MOD();3519		iDamage /= 100;3520	}35213522	// Bring it back out of hundreds3523	iDamage /= 100;35243525	iDamage = iDamage > 0 ? iDamage : 1;35263527	return iDamage;3528}

Calls

Called by