Separate Headshot Damage Multipliers for Head and Body

  • Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Entangler

FNG / Fresh Meat
Jul 12, 2009
474
216
0
34
Sydney, Australia
"Wut?"

No, seriously.

The way the headshot damage multiplier works currently, it's applied to the raw damage amount before damage is dealt to either the head or the body. Consequently, the multiplier affects the damage dealt to both. Apart from the silliness of having a multiplier always be applied to damage to the head (though granted, changing this by having a separate damage amount for heads, while perhaps the better solution on paper, would break backwards compatibility with all existing weapon mutators), this approach suffers from a lack of flexibility that I feel has become a sticking point in the quest for balanced weapons. What if you want a weapon to be particularly good at removing heads without doing insane amounts of damage to the body at the same time? Or, what if you want a weapon to be particularly bad at removing heads, without suffering a damage penalty? (Chainsaw, I'm looking at you.) Under the current system, neither is possible.

There is a solution to this problem: Adding another damage multiplier property to KFWeaponDamageType, called HeadShotDamageMultHead, and having the original HeadShotDamageMult property apply only to damage to the body. The appropriately altered section of KFMonster.TakeDamage() would look like this:

Code:
    if ( (bDecapitated || bIsHeadShot) && class<DamTypeBurned>(DamageType) == none && class<DamTypeFlamethrower>(DamageType) == none )
    {
        [COLOR=yellow]HeadDamage = Damage;[/COLOR]

        if(class<KFWeaponDamageType>(damageType)!=none)
        [COLOR=yellow]{
            HeadDamageMultBody = class<KFWeaponDamageType>(damageType).default.HeadShotDamageMult;
            HeadDamageMultHead = class<KFWeaponDamageType>(damageType).default.HeadShotDamageMultHead;[/COLOR]

            Damage = Damage * HeadDamageMultBody;
            [COLOR=yellow]// Set -1 as the default value in KFWeaponDamageType, to be inherited by weapons that don't set it to anything else,
            // and have it mimic the current behaviour
            if ( HeadDamageMultHead == -1 )
                HeadDamage = HeadDamage * HeadDamageMultBody;
            else
                HeadDamage = HeadDamage * HeadDamageMultHead;
        }[/COLOR]

        if ( class<DamTypeMelee>(damageType) == none && KFPRI != none &&
             KFPRI.ClientVeteranSkill != none )
        {
            [COLOR=yellow]PerkHeadDamageMult = KFPRI.ClientVeteranSkill.Static.GetHeadShotDamMulti(KFPRI);[/COLOR]
            Damage = float(Damage) * [COLOR=yellow]PerkHeadDamageMult;
            HeadDamage = float(HeadDamage) * PerkHeadDamageMult;[/COLOR]
        }

        LastDamageAmount = Damage;

        if( !bDecapitated )
        {
            if( bIsHeadShot )
            {

                // Play a sound when someone gets a headshot TODO: Put in the real sound here
                if( bIsHeadShot )
                {
                    PlaySound(sound'KF_EnemyGlobalSndTwo.Impact_Skull', SLOT_None,2.0,true,500);
                }

                HeadHealth -= [COLOR=yellow]HeadDamage[/COLOR];

                if( HeadHealth <= 0 || Damage > Health )
                {
                    // Award headshot here, not when zombie died.
                    if( Class<KFWeaponDamageType>(damageType)!=None && instigatedBy!=None && KFPlayerController(instigatedBy.Controller)!=None )
                    {
                        bLaserSightedEBRM14Headshotted = M14EBRBattleRifle(instigatedBy.Weapon) != none && M14EBRBattleRifle(instigatedBy.Weapon).bLaserActive;
                        Class<KFWeaponDamageType>(damageType).Static.ScoredHeadshot(KFSteamStatsAndAchievements(PlayerController(instigatedBy.Controller).SteamStatsAndAchievements), bLaserSightedEBRM14Headshotted);
                    }

                       RemoveHead();
                }
            }
        }
    }
For those who might be wondering, the LastDamageAmount variable is used by RemoveHead, which deals that amount of damage, plus 25% of the specimen's maximum health, to the body. Given that the TakeDamage function itself also applies that damage amount further down, the net result is that the decapitating attack deals double damage to the body. Personally that strikes me as rather strange, and I'd be tempted to call it an oversight if not for the line that sets LastDamageAmount's value specifically for that purpose. Still, I think it should probably be removed (leaving just the 25% part).

Also - though this should hopefully go without saying - the various new local variables would have to be declared as well. No challenges there.

Now, you're probably hoping for some practical examples here. Unfortunately I'm going to have to disappoint you, as I'm deliberately omitting any such examples from this thread - they belong in threads about their respective perks instead. I'm really just posting this thread so that I can link to it in the others without explaining it several times over. Further, as it's an implementation detail that, in its own right, doesn't affect gameplay at all, there isn't a whole lot of room for community debate. Sorry.

Still, if you do have any comments about it, even if only to point out bugs in the code, then by all means.
 

Temstar

FNG / Fresh Meat
May 21, 2009
343
3
0
Are you sure? So that 0.25 multiplier for chainsaw is a flat 75% damage nerf when it was implemented?
 

Undedd Jester

FNG / Fresh Meat
Oct 31, 2009
3,059
881
0
Sheffield, England
Ok I have to admit although I don't glaze over when reading code I am having a little difficulty understanding the principle so bear with me :)

If I understand rightly the issue your bringing forward is that a headshots damage multiplyer is always added to head damage as well as body damage, meaning a weapon weak at headshots would also deal weak damage to the body as well, and vice versa.

Altering it would mean that normal damage to the body would be applied regardless of if it was a headshot or not, and then damage to head would increase that damage by a percentage of the standard body damage. (As opposed to the Chainsaws current state where it actually does less damage for a headshot for example). This would allow the Devs to set up weapons to excel at headshots or be poor at them without effecting the normal damage the weapon should do to the body.

If I have misunderstood I apologise in advance, I'm having difficulty with the sudo code for some reason... but I wouldn't expect you to have to teach me Unreal Script in order to show me how it would work. So assuming I've got the right end of the stick, sure I'm down for some of that ;P
 

Entangler

FNG / Fresh Meat
Jul 12, 2009
474
216
0
34
Sydney, Australia
Ok I have to admit although I don't glaze over when reading code I am having a little difficulty understanding the principle so bear with me :)

If I understand rightly the issue your bringing forward is that a headshots damage multiplyer is always added to head damage as well as body damage, meaning a weapon weak at headshots would also deal weak damage to the body as well, and vice versa.

Altering it would mean that normal damage to the body would be applied regardless of if it was a headshot or not, and then damage to head would increase that damage by a percentage of the standard body damage. (As opposed to the Chainsaws current state where it actually does less damage for a headshot for example). This would allow the Devs to set up weapons to excel at headshots or be poor at them without effecting the normal damage the weapon should do to the body.

If I have misunderstood I apologise in advance, I'm having difficulty with the sudo code for some reason... but I wouldn't expect you to have to teach me Unreal Script in order to show me how it would work. So assuming I've got the right end of the stick, sure I'm down for some of that ;P
That's exactly right, except that you could still give them some bonus damage to the body too - they'd be set individually.
 

Temstar

FNG / Fresh Meat
May 21, 2009
343
3
0
I don't think your reading of the code is correct Entangler, it clearly says:

if ( HeadDamageMultHead == -1 )
HeadDamage = HeadDamage * HeadDamageMultBody;
else
HeadDamage = HeadDamage * HeadDamageMultHead;


To put that in english:

IF you hit the specimen in the head AND IF the weapon you're you using do not have a headshot multiplier (-1, not a valid value, they're using it as a flag), then apply normal body shot damage multiplier to headshot damage.

If you hit the specimen in the head AND the weapon DOES have a headshot multiplier, then apply the headshot multiplier to headshot damage.

Nothing in there that I can see says anything about damage to the body, but we all know head damage is always applied to both head and body. So it's perfectly possible for a weapon to have high body damage but low head damage (ie, the chainsaw). It does seem like any weapon that does a lot of head damage will also do a lot of body damage on a headshot, but that seems pretty intended to me.

I take it you want the ability for weapons to do high head damage AND ONLY high head damage, with low body damage on a headshot? I guess I can see some use for a weapon like that, something good for decapitation (and by that I mean just decapitation + bleed out, not 1-2 hit kill on headshot) but bad for actually killing stuff. But that seems pretty counter intuitive to me - you would think something that can easily blow off a specimen's head is going to actually hurt, instead of blow off head but doing bugger all read damage to body HP.
 

Entangler

FNG / Fresh Meat
Jul 12, 2009
474
216
0
34
Sydney, Australia
I don't think your reading of the code is correct Entangler, it clearly says:

if ( HeadDamageMultHead == -1 )
HeadDamage = HeadDamage * HeadDamageMultBody;
else
HeadDamage = HeadDamage * HeadDamageMultHead;


To put that in english:

IF you hit the specimen in the head AND IF the weapon you're you using do not have a headshot multiplier (-1, not a valid value, they're using it as a flag), then apply normal body shot damage multiplier to headshot damage.

If you hit the specimen in the head AND the weapon DOES have a headshot multiplier, then apply the headshot multiplier to headshot damage.

Nothing in there that I can see says anything about damage to the body, but we all know head damage is always applied to both head and body. So it's perfectly possible for a weapon to have high body damage but low head damage (ie, the chainsaw). It does seem like any weapon that does a lot of head damage will also do a lot of body damage on a headshot, but that seems pretty intended to me.

I take it you want the ability for weapons to do high head damage AND ONLY high head damage, with low body damage on a headshot? I guess I can see some use for a weapon like that, something good for decapitation (and by that I mean just decapitation + bleed out, not 1-2 hit kill on headshot) but bad for actually killing stuff. But that seems pretty counter intuitive to me - you would think something that can easily blow off a specimen's head is going to actually hurt, instead of blow off head but doing bugger all read damage to body HP.
You've misinterpreted it.

Firstly, the yellow parts are the ones I've changed - the original has only a single multiplier for headshot damage, which is applied to the head and body alike. So that "using it as a flag" business (and its expository comment) is something I've added, not something that's already there. Also, the names "HeadDamageMultHead" and "HeadDamageMultBody" are those of the local variables, read from the damage type's properties once and then stored there, mostly because of the sheer ugliness of the expressions that retrieve them.

What it all actually means is this: If the damage type has separate multipliers for headshot damage to head and headshot damage to body, then use the correct one; otherwise, use the single original multiplier instead. It's only there for backwards compatibility purposes, as I assume that, were the change to be implemented, all of the official damage types that set HeadShotDamageMult would be modified to set HeadShotDamageMultHead too.

When you talk about "high damage to the body but low damage to the head", I think you're confusing yourself. This is how it works currently: When an attack hits the body, no multiplier from the damage type is applied; it's just the base damage, the perk bonus, and the specimen's own modifiers (e.g. Flesh Pound bullet resistance). When an attack hits the head, the damage type's HeadShotDamageMult property is applied to the single damage value, so it will do the same amount of damage to both the head and the body, be it high or low. In the Chainsaw's case, that means that headshots, with their 75% reduction, deal 75% less damage to the body too. But when the Chainsaw hits the body, that 0.25 multiplier isn't used at all.

I suggest that you examine the code in KFMonster.TakeDamage() for yourself. From Killing Floor's base directory, locate the file KFChar/Classes/KFMonster.uc, open it in your favourite text editor, then find the second occurrence of the phrase "function TakeDamage". There you will find the original code, which is just as I have described.

You misunderstand the purpose of the suggestion, too. I suspect you will find the practical examples more informative than any description I might give here, so I'll leave you to figure that one out for yourself once they appear.