From weapons.cpp:
/**
* Return a scale factor for damage which should be applied for 2 collisions
*/
float weapon_get_damage_scale(weapon_info *wip, object *wep, object *target)
{
weapon *wp;
int from_player = 0;
float total_scale = 1.0f;
float hull_pct;
int is_big_damage_ship = 0;
// Goober5000 - additional sanity (target can be NULL)
Assert(wip);
Assert(wep);
// sanity
if((wip == NULL) || (wep == NULL) || (target == NULL)){
return 1.0f;
}
// don't scale any damage if its not a weapon
if((wep->type != OBJ_WEAPON) || (wep->instance < 0) || (wep->instance >= MAX_WEAPONS)){
return 1.0f;
}
wp = &Weapons[wep->instance];
// was the weapon fired by the player
from_player = 0;
if((wep->parent >= 0) && (wep->parent < MAX_OBJECTS) && (Objects[wep->parent].flags & OF_PLAYER_SHIP)){
from_player = 1;
}
// if this is a lockarm weapon, and it was fired unlocked
if((wip->wi_flags & WIF_LOCKARM) && !(wp->weapon_flags & WF_LOCKED_WHEN_FIRED)){
total_scale *= 0.1f;
}
// if the hit object was a ship and we're doing damage scaling
if ( (target->type == OBJ_SHIP) &&
!(The_mission.ai_profile->flags & AIPF_DISABLE_WEAPON_DAMAGE_SCALING) &&
!(Ship_info[Ships[target->instance].ship_info_index].flags2 & SIF2_DISABLE_WEAPON_DAMAGE_SCALING)
) {
ship_info *sip;
// get some info on the ship
Assert((target->instance >= 0) && (target->instance < MAX_SHIPS));
if((target->instance < 0) || (target->instance >= MAX_SHIPS)){
return total_scale;
}
sip = &Ship_info[Ships[target->instance].ship_info_index];
// get hull pct of the ship currently
hull_pct = get_hull_pct(target);
// if it has hit a supercap ship and is not a supercap class weapon
if((sip->flags & SIF_SUPERCAP) && !(wip->wi_flags & WIF_SUPERCAP)){
// if the supercap is around 3/4 damage, apply nothing
if(hull_pct <= 0.75f){
return 0.0f;
} else {
total_scale *= SUPERCAP_DAMAGE_SCALE;
}
}
// determine if this is a big damage ship
is_big_damage_ship = (sip->flags & SIF_BIG_DAMAGE);
// if this is a large ship, and is being hit by flak
if(is_big_damage_ship && (wip->wi_flags & WIF_FLAK)){
total_scale *= FLAK_DAMAGE_SCALE;
}
// if the weapon is a small weapon being fired at a big ship
if( is_big_damage_ship && !(wip->wi_flags & (WIF_HURTS_BIG_SHIPS)) ){
// if the player is firing it
if ( from_player && !(The_mission.ai_profile->flags2 & AIPF2_PLAYER_WEAPON_SCALE_FIX)) {
// if it's a laser weapon
if(wip->subtype == WP_LASER){
total_scale *= 0.01f;
} else {
total_scale *= 0.05f;
}
}
// scale based on hull
if(hull_pct > 0.1f){
total_scale *= hull_pct;
} else {
return 0.0f;
}
}
}
return total_scale;
}
For supercaps, it uses a constant scaling factor (SUPERCAP_DAMAGE_SCALE) unless the hull is below 75%, in which case it's 0.
For "big damage" ships, the multiplier for a small weapon is the ship's hull percent unless the hull is below 10%, in which case it's 0.
Also for "big damage" ships, there's a constant multiplier against all flak weapons (FLAK_DAMAGE_SCALE). Again, idk what the constant is but I can look for it. Probably in weapon.h.
Also for big damage ships, only if the "player weapon scale fix" is not applied (it probably is in BP because this is very silly):
if the player's weapon here is a laser, the factor is 1%, else it's 5%. This is multiplied to the hull percent as well.
None of this happens if AIPF_DISABLE_WEAPON_DAMAGE_SCALING or SIF2_DISABLE_WEAPON_DAMAGE_SCALING have disabled damage scaling entirely.
edit: SUPERCAP_DAMAGE_SCALE is 25% and FLAK_DAMAGE_SCALE is 5%. I should clarify that all these values are multipliers so 5% means that damage is 5% of normal, not nerfed by 5%.