Bazaar developer reference

CvUnit::GetRangeCombatDamage(const CvUnit *, CvCity *, bool, int) const

Defined in
CvUnit.cpp, line 13206
Class
CvUnit
Hook name
CivHooks::CvUnit_GetRangeCombatDamage

Hooks

static bool BeforeCvUnit_GetRangeCombatDamage(const CvUnit* self, const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage, int& result);static void AfterCvUnit_GetRangeCombatDamage(const CvUnit* self, const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage, int& result);static int ReplaceCvUnit_GetRangeCombatDamage(int (*original)(const CvUnit*, const CvUnit*, CvCity*, bool, int), const CvUnit* self, const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage);CivRegisterBefore<CivHooks::CvUnit_GetRangeCombatDamage>(host, &BeforeCvUnit_GetRangeCombatDamage);CivRegisterAfter<CivHooks::CvUnit_GetRangeCombatDamage>(host, &AfterCvUnit_GetRangeCombatDamage);CivRegisterReplace<CivHooks::CvUnit_GetRangeCombatDamage>(host, &ReplaceCvUnit_GetRangeCombatDamage);

Code

13206int CvUnit::GetRangeCombatDamage(const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage) const13207{13208	VALIDATE_OBJECT1320913210	int iAttackerStrength = GetMaxRangedCombatStrength(pDefender, pCity, true, /*bForRangedAttack*/ true);13211	int iDefenderStrength;1321213213	CvPlayerAI& kPlayer = GET_PLAYER(getOwner());1321413215	// Unit is Defender13216	if(pCity == NULL)13217	{13218		// If this is a defenseless unit, do a fixed amount of damage13219		if(!pDefender->IsCanDefend())13220			return /*4*/ GC.getNONCOMBAT_UNIT_RANGED_DAMAGE();1322113222		if (pDefender->isEmbarked())13223		{13224			iDefenderStrength = pDefender->GetEmbarkedUnitDefense();;13225		}1322613227		// Use Ranged combat value for defender, UNLESS it's a boat or an Impi (ranged support)13228		else if(!pDefender->isRangedSupportFire() && pDefender->getDomainType() != DOMAIN_SEA && pDefender->GetMaxRangedCombatStrength(this, /*pCity*/ NULL, false, false) > 0)13229		{13230			iDefenderStrength = pDefender->GetMaxRangedCombatStrength(this, /*pCity*/ NULL, false, /*bForRangedAttack*/ false);1323113232			// Ranged units take less damage from one another13233			iDefenderStrength *= /*125*/ GC.getRANGE_ATTACK_RANGED_DEFENDER_MOD();13234			iDefenderStrength /= 100;13235		}13236		else13237		{13238			iDefenderStrength = pDefender->GetMaxDefenseStrength(pDefender->plot(), this, /*bFromRangedAttack*/ true);13239		}13240	}13241	// City is Defender13242	else13243	{13244		iDefenderStrength = pCity->getStrengthValue();13245	}1324613247	// The roll will vary damage between 30 and 40 (out of 100) for two units of identical strength1324813249	// Note, 0 is valid - means we don't do anything13250	int iWoundedDamageMultiplier = /*50*/ GC.getWOUNDED_DAMAGE_MULTIPLIER();13251	iWoundedDamageMultiplier += kPlayer.GetWoundedUnitDamageMod();132521325313254#if defined(MOD_UNITS_MAX_HP)13255	int iAttackerDamageRatio = GetMaxHitPoints() - ((getDamage() - iAssumeExtraDamage) * iWoundedDamageMultiplier / 100);13256#else13257	int iAttackerDamageRatio = GC.getMAX_HIT_POINTS() - ((getDamage() - iAssumeExtraDamage) * iWoundedDamageMultiplier / 100);13258#endif13259	if(iAttackerDamageRatio < 0)13260		iAttackerDamageRatio = 0;1326113262	int iAttackerDamage = /*250*/ GC.getRANGE_ATTACK_SAME_STRENGTH_MIN_DAMAGE();13263	iAttackerDamage *= iAttackerDamageRatio;13264#if defined(MOD_UNITS_MAX_HP)13265	iAttackerDamage /= GetMaxHitPoints();13266#else13267	iAttackerDamage /= GC.getMAX_HIT_POINTS();13268#endif1326913270	int iAttackerRoll = 0;13271	if(bIncludeRand)13272	{13273		iAttackerRoll = /*300*/ GC.getGame().getJonRandNum(GC.getRANGE_ATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE(), "Unit Ranged Combat Damage");13274		iAttackerRoll *= iAttackerDamageRatio;13275#if defined(MOD_UNITS_MAX_HP)13276		iAttackerRoll /= GetMaxHitPoints();13277#else13278		iAttackerRoll /= GC.getMAX_HIT_POINTS();13279#endif13280	}13281	else13282	{13283		iAttackerRoll = /*300*/ GC.getRANGE_ATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE();13284		iAttackerRoll -= 1;	// Subtract 1 here, because this is the amount normally "lost" when doing a rand roll13285		iAttackerRoll *= iAttackerDamageRatio;13286#if defined(MOD_UNITS_MAX_HP)13287		iAttackerRoll /= GetMaxHitPoints();13288#else13289		iAttackerRoll /= GC.getMAX_HIT_POINTS();13290#endif13291		iAttackerRoll /= 2;	// The divide by 2 is to provide the average damage13292	}13293	iAttackerDamage += iAttackerRoll;1329413295	double fStrengthRatio = (iDefenderStrength > 0)?(double(iAttackerStrength) / iDefenderStrength):double(iAttackerStrength);1329613297	// In case our strength is less than the other guy's, we'll do things in reverse then make the ratio 1 over the result13298	if(iDefenderStrength > iAttackerStrength)13299	{13300		fStrengthRatio = (double(iDefenderStrength) / iAttackerStrength);13301	}1330213303	fStrengthRatio = (fStrengthRatio + 3) / 4;13304	fStrengthRatio = pow(fStrengthRatio, 4.0);13305	fStrengthRatio = (fStrengthRatio + 1) / 2;1330613307	if(iDefenderStrength > iAttackerStrength)13308	{13309		fStrengthRatio = 1 / fStrengthRatio;13310	}1331113312	double fAttackerDamage = (double)iAttackerDamage * fStrengthRatio;13313	// Protect against it overflowing an int13314	if(fAttackerDamage > INT_MAX)13315		iAttackerDamage = INT_MAX;13316	else13317		iAttackerDamage = int(fAttackerDamage);1331813319	// Bring it back out of hundreds13320	iAttackerDamage /= 100;1332113322	iAttackerDamage = max(1,iAttackerDamage);1332313324	return iAttackerDamage;13325}

Calls

Called by