Find Damage Calculation in CvGameCore.dll

Tiramisu

Warlord
Joined
Aug 16, 2013
Messages
148
Location
Leonberg (BW, Germany)
Hopefully it is worth opening a thread for this issue. :D

I recently found the class function CvUnit::getCombatDamage in CvUnit.cpp and it seems to calculate the damage made in a combat. But I think it calculates the wrong damage value. Maybe it is calculating the damage in the vanilla version of Civ5, where units only got 10 hitpoints.

Now I am looking for the right damage function (for BNW). Can someone help me, please?
 
I think the function you mentioned works well, it takes some parameters from the game defines, so there are no hardcoded things in it that would be dependent on the amount of hit points that units have.

(Of course you should look at the BNW version of the DLL code, in the CvGameCoreDLL_Expansion2 folder.)
 
Ok, I solved the problem myself. :mischief:

I should not have trusted in the values of things like ATTACK_SAME_STRENGTH_MIN_DAMAGE written in CvGlobals.cpp. Instead I had to look up the values in the XML datas in the Expansion2 folder to get the values for BNW.
E.g. WOUNDED_DAMAGE_MULTIPLIER equals 50 in the vanilla version, but in BNW it equals 33.


Btw. I could enter the XML values for BNW in a C++ function. So you can use this function, if you want to calculate any damage: :goodjob:

Spoiler :
Code:
int getCombatDamage(int iStrength, int iOpponentStrength, int iCurrentDamage, bool bIncludeRand, bool bAttackerIsCity, bool bDefenderIsCity) 
{
	
	// The roll will vary damage between 40 and 60 (out of 100) for two units of identical strength

	int iDamageRatio;

	int iWoundedDamageMultiplier = 33;  //GC.getWOUNDED_DAMAGE_MULTIPLIER();

	if(bAttackerIsCity)
	{
		iDamageRatio = 100; //GC.getMAX_HIT_POINTS();		// JON: Cities don't do less damage when wounded
	}
	else
	{
		// Mod (Policies, etc.)
		iWoundedDamageMultiplier += 0; // GET_PLAYER(getOwner()).GetWoundedUnitDamageMod();

		iDamageRatio = /*GC.getMAX_HIT_POINTS()*/ 100 - (iCurrentDamage * iWoundedDamageMultiplier / 100);
	}

	int iDamage = 0;

	iDamage = /*GC.getATTACK_SAME_STRENGTH_MIN_DAMAGE()*/ 2400 * iDamageRatio / 100; //GC.getMAX_HIT_POINTS();

	// Don't use rand when calculating projected combat results
	int iRoll = 0;
	if(bIncludeRand)
	{
		iRoll = 1200; //GC.getGame().getJonRandNum(GC.getATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE(), "Unit Combat Damage");
		iRoll *= iDamageRatio;
		iRoll /= 100; //GC.getMAX_HIT_POINTS();
	}
	else
	{
		iRoll = 1200; //GC.getATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE();
		iRoll -= 1;	// Subtract 1 here, because this is the amount normally "lost" when doing a rand roll
		iRoll *= iDamageRatio;
		iRoll /= 100; //GC.getMAX_HIT_POINTS();
		iRoll /= 2;	// The divide by 2 is to provide the average damage
	}
	iDamage += iRoll;

	// Calculations performed to dampen amount of damage by units that are close in strength
	// RATIO = (((((ME / OPP) + 3) / 4) ^ 4) + 1) / 2
	// Examples:
	// 1.301 = (((((9 / 6) + 3) / 4) ^ 4) + 1 / 2
	// 17.5 = (((((40 / 6) + 3) / 4) ^ 4) + 1 / 2

	double fStrengthRatio = (double(iStrength) / iOpponentStrength);

	// 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)
	if(iOpponentStrength > iStrength)
	{
		fStrengthRatio = (double(iOpponentStrength) / iStrength);
	}

	fStrengthRatio = (fStrengthRatio + 3) / 4;
	fStrengthRatio = pow(fStrengthRatio, 4.0);
	fStrengthRatio = (fStrengthRatio + 1) / 2;

	if(iOpponentStrength > iStrength)
	{
		fStrengthRatio = 1 / fStrengthRatio;
	}

	iDamage = int(iDamage * fStrengthRatio);

	// Modify damage for when a city "attacks" a unit
	if(bAttackerIsCity)
	{
		iDamage *= 100; //GC.getCITY_ATTACKING_DAMAGE_MOD();
		iDamage /= 100;
	}

	// Modify damage for when unit is attacking a city
	if(bDefenderIsCity)
	{
		iDamage *= 100; //GC.getATTACKING_CITY_MELEE_DAMAGE_MOD();
		iDamage /= 100;
	}

	// Bring it back out of hundreds
	iDamage /= 100;

	iDamage = iDamage > 0 ? iDamage : 1;

	return iDamage;
}

Edit: Oh, PawelS crossposted me a few minutes ago. :D
 
Top Bottom