Hooks
static bool BeforeCvUnit_GetAirCombatDamage(const CvUnit* self, const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage, int& result);static void AfterCvUnit_GetAirCombatDamage(const CvUnit* self, const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage, int& result);static int ReplaceCvUnit_GetAirCombatDamage(int (*original)(const CvUnit*, const CvUnit*, CvCity*, bool, int), const CvUnit* self, const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage);CivRegisterBefore<CivHooks::CvUnit_GetAirCombatDamage>(host, &BeforeCvUnit_GetAirCombatDamage);CivRegisterAfter<CivHooks::CvUnit_GetAirCombatDamage>(host, &AfterCvUnit_GetAirCombatDamage);CivRegisterReplace<CivHooks::CvUnit_GetAirCombatDamage>(host, &ReplaceCvUnit_GetAirCombatDamage);
Code
13102int CvUnit::GetAirCombatDamage(const CvUnit* pDefender, CvCity* pCity, bool bIncludeRand, int iAssumeExtraDamage) const13103{13104 VALIDATE_OBJECT1310513106 int iAttackerStrength = GetMaxRangedCombatStrength(pDefender, pCity, /*bAttacking*/ true, /*bForRangedAttack*/ true);13107 int iDefenderStrength;1310813109 // Unit is Defender13110 if(pCity == NULL)13111 {13112 // Use Ranged combat value for defender, UNLESS it's a boat13113 if(pDefender->GetMaxRangedCombatStrength(this, /*pCity*/ NULL, false, /*bForRangedAttack*/ false) > 0 && !pDefender->getDomainType() == DOMAIN_SEA)13114 {13115 iDefenderStrength = pDefender->GetMaxRangedCombatStrength(this, /*pCity*/ NULL, false, /*bForRangedAttack*/ false);13116 }13117 else13118 {13119 iDefenderStrength = pDefender->GetMaxDefenseStrength(pDefender->plot(), this, /*bFromRangedAttack*/ true);13120 }13121 }13122 // City is Defender13123 else13124 {13125 iDefenderStrength = pCity->getStrengthValue();13126 }1312713128 // The roll will vary damage between 30 and 40 (out of 100) for two units of identical strength1312913130 // Note, 0 is valid - means we don't do anything13131#if defined(MOD_UNITS_MAX_HP)13132 int iAttackerDamageRatio = GetMaxHitPoints() - getDamage() - iAssumeExtraDamage;13133#else13134 int iAttackerDamageRatio = GC.getMAX_HIT_POINTS() - getDamage() - iAssumeExtraDamage;13135#endif13136 if(iAttackerDamageRatio < 0)13137 iAttackerDamageRatio = 0;1313813139 int iAttackerDamage = /*250*/ GC.getRANGE_ATTACK_SAME_STRENGTH_MIN_DAMAGE();13140 iAttackerDamage *= iAttackerDamageRatio;13141#if defined(MOD_UNITS_MAX_HP)13142 iAttackerDamage /= GetMaxHitPoints();13143#else13144 iAttackerDamage /= GC.getMAX_HIT_POINTS();13145#endif1314613147 int iAttackerRoll = 0;13148 if(bIncludeRand)13149 {13150 iAttackerRoll = /*300*/ GC.getGame().getJonRandNum(GC.getRANGE_ATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE(), "Unit Ranged Combat Damage");13151 iAttackerRoll *= iAttackerDamageRatio;13152#if defined(MOD_UNITS_MAX_HP)13153 iAttackerRoll /= GetMaxHitPoints();13154#else13155 iAttackerRoll /= GC.getMAX_HIT_POINTS();13156#endif13157 }13158 else13159 {13160 iAttackerRoll = /*300*/ GC.getRANGE_ATTACK_SAME_STRENGTH_POSSIBLE_EXTRA_DAMAGE();13161 iAttackerRoll -= 1; // Subtract 1 here, because this is the amount normally "lost" when doing a rand roll13162 iAttackerRoll *= iAttackerDamageRatio;13163#if defined(MOD_UNITS_MAX_HP)13164 iAttackerRoll /= GetMaxHitPoints();13165#else13166 iAttackerRoll /= GC.getMAX_HIT_POINTS();13167#endif13168 iAttackerRoll /= 2; // The divide by 2 is to provide the average damage13169 }13170 iAttackerDamage += iAttackerRoll;1317113172 double fStrengthRatio = ((iDefenderStrength > 0)?(double(iAttackerStrength) / iDefenderStrength):double(iAttackerStrength));1317313174 // In case our strength is less than the other guy's, we'll do things in reverse then make the ratio 1 over the result13175 if(iDefenderStrength > iAttackerStrength)13176 {13177 fStrengthRatio = (double(iDefenderStrength) / iAttackerStrength);13178 }1317913180 fStrengthRatio = (fStrengthRatio + 3) / 4;13181 fStrengthRatio = pow(fStrengthRatio, 4.0);13182 fStrengthRatio = (fStrengthRatio + 1) / 2;1318313184 if(iDefenderStrength > iAttackerStrength)13185 {13186 fStrengthRatio = 1 / fStrengthRatio;13187 }1318813189 double fAttackerDamage = (double)iAttackerDamage * fStrengthRatio;13190 // Protect against it overflowing an int13191 if(fAttackerDamage > INT_MAX)13192 iAttackerDamage = INT_MAX;13193 else13194 iAttackerDamage = int(fAttackerDamage);1319513196 // Bring it back out of hundreds13197 iAttackerDamage /= 100;1319813199 iAttackerDamage = max(1,iAttackerDamage);1320013201 return iAttackerDamage;13202}