Hitgroups

hey guys, im working on a dynamic health system that deals with the player’s abilities and actions depending on the health statuses of each of their limbs. (head, arms, legs, torso) And im currently working on the section that deals with the actual damaging of the limbs. I’ve been using hitboxes for this as of late, and found that they were useless for what i was trying to achieve, because all of the damage would either go to the body, or it would be equally spread out among the limbs, Such as this example:
http://www.dumpt.com/img/files/lpfebrtibsvw1t8ykoup_thumb.png
note how all the limbs are of the same color, but the body is its own. I did some poking around about this and found that this was due to hitgroups being absolute rubbish.
But, I may just be doing it wrong.
Reveiw this code, Please tell me if you see any errors/reasons why it would not correctly work
(Please excuse any messy code, this is my first attempt at a system like this)
[lua]local HeadHP
local TorsoHP
local RarmHP
local LarmHP
local LlegHP
local RlegHP
function UpdateHeadDamage()
umsg.Start( “DmgupdateHead” );
umsg.Float(HeadHP);
umsg.End();
end
function UpdateTorsoDamage()
umsg.Start( “DmgupdateTorso” );
umsg.Float(TorsoHP);
umsg.End();
end
function UpdateRarmDamage()
umsg.Start( “DmgupdateRarm” );
umsg.Float(RarmHP);
umsg.End();
end
function UpdateLarmDamage()
umsg.Start( “DmgupdateLarm” );
umsg.Float(LarmHP);
umsg.End();
end
function UpdateLlegDamage()
umsg.Start( “DmgupdateLleg” );
umsg.Float(LlegHP);
umsg.End();
end
function UpdateRlegDamage()
umsg.Start( “DmgupdateRleg” );
umsg.Float(RlegHP);
umsg.End();
end
function PlayerLoadShit( pl )
HeadHP = 100
TorsoHP = 100
RarmHP = 100
LarmHP = 100
LlegHP = 100
RlegHP = 100
UpdateHeadDamage()
UpdateTorsoDamage()
UpdateRlegDamage()
UpdateLlegDamage()
UpdateRarmDamage()
UpdateLarmDamage()
pl.hitgroups = {}
for group = 0,10 do
if group ~= HITGROUP_GENERIC and group ~= HITGROUP_GEAR then
pl.hitgroups[group] = 50
end
end
end
hook.Add( “PlayerLoadout”, “testload”, PlayerLoadShit )
groupNames = {“head”,“chest”,“stomach”,“left arm”,“right arm”,“left leg”,“right leg”}
function SkalePlayerDamage( pl, hitgroup, dmginfo, dmg )
if (pl.hitgroups and pl.hitgroups[hitgroup]) then
local groupName = groupNames[hitgroup]
pl.hitgroups[hitgroup] = pl.hitgroups[hitgroup] - dmginfo:GetBaseDamage()
local speed = 20
if pl.hitgroups[HITGROUP_RIGHTLEG] > 0 then
RlegHP = RlegHP - dmginfo:GetDamage()
end
if pl.hitgroups[HITGROUP_LEFTLEG] > 0 then
LlegHP = LlegHP - dmginfo:GetDamage()
end
if pl.hitgroups[HITGROUP_LEFTARM] > 0 then
LarmHP = LarmHP - dmginfo:GetDamage()
end
if pl.hitgroups[HITGROUP_RIGHTARM] > 0 then
RarmHP = RarmHP - dmginfo:GetDamage()
end
if pl.hitgroups[HITGROUP_CHEST] > 0 then
TorsoHP = TorsoHP - dmginfo:GetDamage()
end
if pl.hitgroups[HITGROUP_STOMACH] > 0 then
TorsoHP = TorsoHP - dmginfo:GetDamage()
end
if pl.hitgroups[HITGROUP_HEAD] > 0 then
HeadHP = HeadHP - dmginfo:GetDamage()
end
end
UpdateHeadDamage()
UpdateTorsoDamage()
UpdateRlegDamage()
UpdateLlegDamage()
UpdateRarmDamage()
UpdateLarmDamage()
end
hook.Add( “ScalePlayerDamage”, “testscale”, SkalePlayerDamage )
[/lua]
If i am doing it correctly and there are no problems, Then the only fix that i know of to help the problem would be to custom assign certain hit regions by linking the regions VIA Valve Bipeds. Problem is, im not super acquainted with them and im not absolutely sure how i would go about it.
This is the closest line of code that i could conjure up that might define certain areas.

[lua]
–Example, Left arm (Forearm, Shoulder, Hand)
local Larmbones = pl:LookupBone(“ValveBiped.Bip01_L_Hand”, “ValveBiped.Bip01_L_Forearm”, “ValveBiped.Bip01_L_Shoulder” )
Larmshot = dmginfo:IsBulletDamage() and dmginfo:GetDamagePosition():Distance(pl:GetBonePosition( Larmbones )) < 15
[/lua]

Could you guys help me out with this? I dont know how or where to start with Valve bipeds, Could someone give me an example of how it could be used in my script?
TIA,
Archemyde

Instead of doing all of the calculations on the server, you could just send the client which hitgroup was affected and the amount of damage done. From there you could calculate the amount of damage done to a certain hitgroup out of the total damage done and apply that ratio to the damage color on the HUD.

Here’s some code I just wrote which may help you get the idea. It should work, but I haven’t tested it. I decided to use the players max health instead of total damage done so the color would be more accurate.

[lua]-- SERVER
hook.Add(“ScalePlayerDamage”, “SendHitgroupDmg”, function(ply, hitgroup, dmginfo, dmg)

umsg.Start("HitgroupDmg", ply)
	umsg.Short(hitgroup)
	umsg.Short(dmg)
umsg.End()

end)

– CLIENT
local DamagePerHitgroup = {
[HITGROUP_GENERIC] = 0,
[HITGROUP_HEAD] = 0,
[HITGROUP_CHEST] = 0,
[HITGROUP_STOMACH] = 0,
[HITGROUP_LEFTARM] = 0,
[HITGROUP_RIGHTARM] = 0,
[HITGROUP_LEFTLEG] = 0,
[HITGROUP_RIGHTLEG] = 0,
[HITGROUP_GEAR] = 0,
}

usermessage.Hook(“HitgroupDmg”, function(um)

local hitgroup = um:ReadShort()
local dmg = um:ReadShort()

-- Add damage to hitgroup
DamagePerHitgroup[hitgroup] = DamagePerHitgroup[hitgroup] + dmg

end)

hook.Add(“HUDPaint”, “PaintHitgroupDamage”, function()

if !LocalPlayer():Alive() then return end -- Don't render if the player isn't alive

-- Loop through hitgroups and draw each texture
for _, hitgroupDmg in pairs(DamagePerHitgroup) do
	local percentdmg = (hitgroupDmg / LocalPlayer():GetMaxHealth()) * 255
	-- Color will become more red as more damage is done to the hitgroup
	surface.SetDrawColor( 0 + percentdmg, 255 - percentdmg, 0, 255 )
	-- Draw hitgroup texture
end

end)[/lua]