Ragdoll hitgroups?

I know this has been asked here http://forum.facepunch.com/showthread.php?t=1449199
but well… the solution wasn’t provided.
So I am asking is there a way to get a hitgroup of a ragdoll?
I know they are used in “GM:ScalePlayerDamage, GM:ScaleNPCDamage and Player:LastHitGroup”
but the wiki doesn’t say anything about ragdolls.

What’re you doing with the hitgroup, once you have it?

An advanced healing/damage system for the gamemode I am working on. And btw why do you need to know that?

Because what you’re actually trying to accomplish matters.

TraceResult.HitGroup doesn’t work with ragdolls, but you can use TraceResult.PhysicsBone and translate bones to hitgroups. Only works serverside, though, because ragdolls don’t have physics on the client as far as I know.
[lua]
– bone name -> HITGROUP_*
local translate

– translate a ragdoll’s bone to the appropriate hitgroup
function util.BoneToHitGroup(ent, bone)
return translate[ent:GetBoneName(bone)] or HITGROUP_GENERIC
end

– translate a ragdoll’s physics bone (e.g. TraceResults.PhysicsBone) to the appropriate hitgroup
function util.PhysBoneToHitGroup(ent, physbone)
return util.BoneToHitGroup(ent, ent:TranslatePhysBoneToBone(physbone))
end

– to find bones for the ragdoll you’re looking at:
– lua_run local e = Entity(1):GetEyeTrace().Entity for i=0, e:GetPhysicsObjectCount()-1 do print(’ ["’ … e:GetBoneName(e:TranslatePhysBoneToBone(i)) … ‘"] = HITGROUP_’) end
translate = {
– standard valve biped
– works for NPCs and GMod playermodels
[“ValveBiped.Bip01_Head1”] = HITGROUP_HEAD,
[“ValveBiped.Bip01_Neck1”] = HITGROUP_CHEST,
[“ValveBiped.Bip01_Spine”] = HITGROUP_CHEST,
[“ValveBiped.Bip01_Spine1”] = HITGROUP_CHEST,
[“ValveBiped.Bip01_Spine2”] = HITGROUP_CHEST,
[“ValveBiped.Bip01_Spine4”] = HITGROUP_CHEST,
[“ValveBiped.Bip01_Pelvis”] = HITGROUP_STOMACH,
– this is the pelvis on some models, because reasons.
[“ValveBiped.Bip01”] = HITGROUP_STOMACH,
[“ValveBiped.Bip01_L_Clavicle”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_UpperArm”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Forearm”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Ulna”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Wrist”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Hand”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger2”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger21”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger22”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger1”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger11”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger12”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger0”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger01”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_L_Finger02”] = HITGROUP_LEFTARM,
[“ValveBiped.Bip01_R_Clavicle”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_UpperArm”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Forearm”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Ulna”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Wrist”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Hand”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger2”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger21”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger22”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger1”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger11”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger12”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger0”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger01”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_R_Finger02”] = HITGROUP_RIGHTARM,
[“ValveBiped.Bip01_L_Thigh”] = HITGROUP_LEFTLEG,
[“ValveBiped.Bip01_L_Calf”] = HITGROUP_LEFTLEG,
[“ValveBiped.Bip01_L_Foot”] = HITGROUP_LEFTLEG,
[“ValveBiped.Bip01_L_Toe0”] = HITGROUP_LEFTLEG,
[“ValveBiped.Bip01_R_Thigh”] = HITGROUP_RIGHTLEG,
[“ValveBiped.Bip01_R_Calf”] = HITGROUP_RIGHTLEG,
[“ValveBiped.Bip01_R_Foot”] = HITGROUP_RIGHTLEG,
[“ValveBiped.Bip01_R_Toe0”] = HITGROUP_RIGHTLEG,

-- vortigaunt
-- "look at me, i'm DIFFERENT!"
["ValveBiped.head"]			= HITGROUP_HEAD,
["ValveBiped.neck2"]		= HITGROUP_CHEST,
["ValveBiped.spine2"]		= HITGROUP_CHEST,
["ValveBiped.hips"]			= HITGROUP_STOMACH,
["ValveBiped.arm1_L"]		= HITGROUP_LEFTARM,
["ValveBiped.arm2_L"]		= HITGROUP_LEFTARM,
["ValveBiped.hand1_L"]		= HITGROUP_LEFTARM,
["ValveBiped.arm1_R"]		= HITGROUP_RIGHTARM,
["ValveBiped.arm2_R"]		= HITGROUP_RIGHTARM,
["ValveBiped.hand1_R"]		= HITGROUP_RIGHTARM,
["ValveBiped.leg_bone1_L"]	= HITGROUP_LEFTLEG,
["ValveBiped.leg_bone2_L"]	= HITGROUP_LEFTLEG,
["ValveBiped.leg_bone3_L"]	= HITGROUP_LEFTLEG,
["ValveBiped.leg_bone1_R"]	= HITGROUP_RIGHTLEG,
["ValveBiped.leg_bone2_R"]	= HITGROUP_RIGHTLEG,
["ValveBiped.leg_bone3_R"]	= HITGROUP_RIGHTLEG,

-- dog
["Dog_Model.Neck2"]		= HITGROUP_HEAD,
["Dog_Model.Spine3"]	= HITGROUP_CHEST,
["Dog_Model.Spine1"]	= HITGROUP_STOMACH,
["Dog_Model.Pelvis"]	= HITGROUP_STOMACH,
["Dog_Model.Arm1_L"]	= HITGROUP_LEFTARM,
["Dog_Model.Arm2_L"]	= HITGROUP_LEFTARM,
["Dog_Model.Hand_L"]	= HITGROUP_LEFTARM,
["Dog_Model.Arm1_R"]	= HITGROUP_RIGHTARM,
["Dog_Model.Arm2_R"]	= HITGROUP_RIGHTARM,
["Dog_Model.Hand_R"]	= HITGROUP_RIGHTARM,
["Dog_Model.Leg1_L"]	= HITGROUP_LEFTLEG,
["Dog_Model.Leg2_L"]	= HITGROUP_LEFTLEG,
["Dog_Model.Foot_L"]	= HITGROUP_LEFTLEG,
["Dog_Model.Leg1_R"]	= HITGROUP_RIGHTLEG,
["Dog_Model.Leg2_R"]	= HITGROUP_RIGHTLEG,
["Dog_Model.Foot_R"]	= HITGROUP_RIGHTLEG,

-- headcrab
["HeadcrabClassic.BodyControl"]		= HITGROUP_CHEST,
["HeadcrabClassic.UpperArmL_Bone"]	= HITGROUP_LEFTARM,
["HeadcrabClassic.ForeArmL_Bone"]	= HITGROUP_LEFTARM,
["HeadcrabClassic.UpperArmR_Bone"]	= HITGROUP_RIGHTARM,
["HeadcrabClassic.ForeArmR_Bone"]	= HITGROUP_RIGHTARM,
["HeadcrabClassic.ThighL_Bone"]		= HITGROUP_LEFTLEG,
["HeadcrabClassic.CalfL_Bone"]		= HITGROUP_LEFTLEG,
["HeadcrabClassic.ThighR_Bone"]		= HITGROUP_RIGHTLEG,
["HeadcrabClassic.CalfR_Bone"]		= HITGROUP_RIGHTLEG,
-- fast headcrab
["HCfast.body"]			= HITGROUP_CHEST,
["HCfast.arm_bone1_L"]	= HITGROUP_LEFTARM,
["HCfast.arm_bone2_L"]	= HITGROUP_LEFTARM,
["HCfast.arm_bone1_R"]	= HITGROUP_RIGHTARM,
["HCfast.arm_bone2_R"]	= HITGROUP_RIGHTARM,
["HCfast.leg_bone1_L"]	= HITGROUP_LEFTLEG,
["HCfast.leg_bone2_L"]	= HITGROUP_LEFTLEG,
["HCfast.leg_bone1_R"]	= HITGROUP_RIGHTLEG,
["HCfast.leg_bone2_R"]	= HITGROUP_RIGHTLEG,
-- poison headcrab
["HCblack.body"]		= HITGROUP_CHEST,
["HCblack.arm_bone1_L"]	= HITGROUP_LEFTARM,
["HCblack.arm_bone2_L"]	= HITGROUP_LEFTARM,
["HCblack.arm_bone1_R"]	= HITGROUP_RIGHTARM,
["HCblack.arm_bone2_R"]	= HITGROUP_RIGHTARM,
["HCblack.leg_bone1_L"]	= HITGROUP_LEFTLEG,
["HCblack.leg_bone2_L"]	= HITGROUP_LEFTLEG,
["HCblack.leg_bone1_R"]	= HITGROUP_RIGHTLEG,
["HCblack.leg_bone2_R"]	= HITGROUP_RIGHTLEG,

-- antlion
["Antlion.Head_Bone"]		= HITGROUP_HEAD,
["Antlion.Body_Bone"]		= HITGROUP_CHEST,
["Antlion.Back_Bone"]		= HITGROUP_CHEST,
["Antlion.WingL_Bone"]		= HITGROUP_CHEST,
["Antlion.WingR_Bone"]		= HITGROUP_CHEST,
["Antlion.LegMidL1_Bone"]	= HITGROUP_LEFTARM,
["Antlion.LegMidL2_Bone"]	= HITGROUP_LEFTARM,
["Antlion.LegMidL3_Bone"]	= HITGROUP_LEFTARM,
["Antlion.LegMidR1_Bone"]	= HITGROUP_RIGHTARM,
["Antlion.LegMidR2_Bone"]	= HITGROUP_RIGHTARM,
["Antlion.LegMidR3_Bone"]	= HITGROUP_RIGHTARM,
["Antlion.LegL1_Bone"]		= HITGROUP_LEFTLEG,
["Antlion.LegL2_Bone"]		= HITGROUP_LEFTLEG,
["Antlion.LegL3_Bone"]		= HITGROUP_LEFTLEG,
["Antlion.LegR1_Bone"]		= HITGROUP_RIGHTLEG,
["Antlion.LegR2_Bone"]		= HITGROUP_RIGHTLEG,
["Antlion.LegR3_Bone"]		= HITGROUP_RIGHTLEG,

-- antlion guard
-- seriously fuck this model
["Antlion_Guard.head"]		= HITGROUP_HEAD,
["Antlion_Guard.body"]		= HITGROUP_CHEST,
["Antlion_Guard.spine3"]	= HITGROUP_CHEST,
["Antlion_Guard.spine1"]	= HITGROUP_CHEST,
["Antlion_Guard.pelvis"]	= HITGROUP_STOMACH,
-- front legs
["Antlion_Guard.arm1_L"]	= HITGROUP_LEFTARM,
["Antlion_Guard.finger1_L"]	= HITGROUP_LEFTARM,
["Antlion_Guard.arm1_R"]	= HITGROUP_RIGHTARM,
["Antlion_Guard.finger1_R"]	= HITGROUP_RIGHTARM,
-- hind legs
["Antlion_Guard.leg1_L"]	= HITGROUP_LEFTLEG,
["Antlion_Guard.leg2_L"]	= HITGROUP_LEFTLEG,
["Antlion_Guard.leg1_R"]	= HITGROUP_RIGHTLEG,
["Antlion_Guard.leg2_R"]	= HITGROUP_RIGHTLEG,
-- tiny claws
["Antlion_Guard.claw1_L"]	= HITGROUP_LEFTARM,
["Antlion_Guard.claw2_L"]	= HITGROUP_LEFTARM,
["Antlion_Guard.claw3_L"]	= HITGROUP_LEFTARM,
["Antlion_Guard.claw1_R"]	= HITGROUP_RIGHTARM,
["Antlion_Guard.claw2_R"]	= HITGROUP_RIGHTARM,
["Antlion_Guard.claw3_R"]	= HITGROUP_RIGHTARM,

-- skinny charple
-- hey valve, fuck you!
["Charple1.Head"]		= HITGROUP_HEAD,
["Charple1.Spine"]		= HITGROUP_CHEST,
["Charple1.Lumbar"]		= HITGROUP_CHEST,
["Charple1.Pelvis"]		= HITGROUP_STOMACH,
["Charple1.Humerus_L"]	= HITGROUP_LEFTARM,
["Charple1.Radius_L"]	= HITGROUP_LEFTARM,
["Charple1.Carpus_L"]	= HITGROUP_LEFTARM,
["Charple1.Humerus_R"]	= HITGROUP_RIGHTARM,
["Charple1.Radius_R"]	= HITGROUP_RIGHTARM,
["Charple1.Carpus_R"]	= HITGROUP_RIGHTARM,
["Charple1.Femur_L"]	= HITGROUP_LEFTLEG,
["Charple1.Tibia_L"]	= HITGROUP_LEFTLEG,
["Charple1.Tarsus_L"]	= HITGROUP_LEFTLEG,
["Charple1.Tarsus_R"]	= HITGROUP_RIGHTLEG,
["Charple1.Femur_R"]	= HITGROUP_RIGHTLEG,
["Charple1.Tibia_R"]	= HITGROUP_RIGHTLEG,
-- charple with missing limbs
["Charple2.Head"]		= HITGROUP_HEAD,
["Charple2.Spine"]		= HITGROUP_CHEST,
["Charple2.Lumbar"]		= HITGROUP_CHEST,
["Charple2.Pelvis"]		= HITGROUP_STOMACH,
["Charple2.Humerus_L"]	= HITGROUP_LEFTARM,
["Charple2.Radius_L"]	= HITGROUP_LEFTARM,
["Charple2.Humerus_R"]	= HITGROUP_RIGHTARM,
["Charple2.Radius_R"]	= HITGROUP_RIGHTARM,
["Charple2.Carpus_R"]	= HITGROUP_RIGHTARM,
["Charple2.Femur_L"]	= HITGROUP_LEFTLEG,
["Charple2.Tibia_L"]	= HITGROUP_LEFTLEG,
["Charple2.Femur_R"]	= HITGROUP_RIGHTLEG,
["Charple2.Tibia_R"]	= HITGROUP_RIGHTLEG,
-- limbless charple
["Charple3.Head"]	= HITGROUP_HEAD,
["Charple3.Lumbar"]	= HITGROUP_CHEST,
["Charple3.Spine"]	= HITGROUP_CHEST,
["Charple3.Pelvis"]	= HITGROUP_STOMACH,
-- almost-limbless charple
["Charple4.Head"]		= HITGROUP_HEAD,
["Charple4.Spine"]		= HITGROUP_CHEST,
["Charple4.Lumbar"]		= HITGROUP_CHEST,
["Charple4.Pelvis"]		= HITGROUP_STOMACH,
["Charple4.Humerus_L"]	= HITGROUP_LEFTARM,
["Charple4.Humerus_R"]	= HITGROUP_RIGHTARM,
["Charple4.Femur_L"]	= HITGROUP_LEFTLEG,
["Charple4.Femur_R"]	= HITGROUP_RIGHTLEG,
["Charple4.Tibia_R"]	= HITGROUP_RIGHTLEG,
-- charple5 (the clothed one) uses ValveBiped, because fuck you i guess

}
[/lua]
[lua]
local tr = ply:GetEyeTrace()
if tr.Entity:IsRagdoll() then
local hitgroup = util.PhysBoneToHitGroup(tr.Entity, tr.PhysicsBone)
end
[/lua]
e: and if you say “no i can’t use traces i actually wanna do [other thing that’s completely different from what my post suggested]” i will slap you

wow… that’s a lotttt of bones… and well is there another way than using player trace as there can be multiple damage types…?
Is there a function to get a bone of an entity closest to the exact position?

plz don’t slap me imma nub at bonez kek

pls explain how this ‘advanced healing and damage system’ works and why you need to get hitgroups on ragdolls, because evidently trying to guess what you actually want to do is not working

are you beginning to understand why i always ask for a full description of what you’re trying to do? because “how do i get the hitgroup of a ragdoll” is a pretty vague question with multiple different answers

that’s like asking “how do i get someone’s name”, which could mean any of the following

  • how to get a player’s roleplay name in darkrp
  • how to get a person’s real name from their ip address
  • how to ask someone’s name in real life
  • how to find out the name of the driver of a bus you took yesterday
  • how to find out who just called your cell phone
    all of these things involve “getting someone’s name” but they are accomplished in completely different ways

Oh, I am sorry… I thought that hitgroups were used only in functions that are related with damage like “GM:ScalePlayerDamage, GM:ScaleNPCDamage and Player:LastHitGroup”. So I am trying to do something like this (I’ll skip some steps before) 1. A ragdoll is created 2. If a ragdoll is damaged deal a damage modified by the place it was hit on.

Ah, so you’re hurting a player when his ragdoll is attacked, but you want to retain hitgroup info.

Your best bet is probably to hook EntityTakeDamage, find the nearest physics bone to the damage location, and get the hitgroup from the associated skeleton bone:
[lua]
local function getNearestPhysicsBonePos(ent, target)
local near, neardist = ent:GetPos(), math.huge
for i = 0, ent:GetPhysicsObjectCount() - 1 do
local phys = ent:GetPhysicsObjectNum(i)
if phys:IsValid() then
local pos = phys:GetPos()
local dist = (target - pos):LengthSqr()
if dist < neardist then
near, neardist = pos, dist
end
end
end
return near
end

local groups = {
“head”,
“chest”,
“stomach”,
“left arm”,
“right arm”,
“left leg”,
“right leg”,
“gear”,
[0] = “somewhere”
}

hook.Add(“EntityTakeDamage”, “RagdollDamage”, function(ent, dmg)
if not ent:IsRagdoll() then
– add your own condition here, however you determine whether a ragdoll is an “unconscious player” or whatever
return
end

local dmgpos = dmg:GetDamagePosition()
local tr = util.TraceLine({
	start = dmgpos,
	endpos = dmgpos
})

-- trace doesn't hit the entity for grazing shots.
-- there may be a better/more efficient way to solve this.
if tr.Entity ~= ent then
	local nearpos = getNearestPhysicsBonePos(ent, dmgpos)
	tr = util.TraceLine({
		start = dmgpos,
		endpos = nearpos,
	})
end
local hitgroup = util.PhysBoneToHitGroup(ent, tr.PhysicsBone)
print("Ragdoll " .. ent:GetModel() .. " took " .. dmg:GetDamage() .. " damage (" .. (groups[hitgroup] or "nowhere") .. ")")

end)
[/lua]

It gives this error




[ERROR] gamemodes/mrp/gamemode/modules/death/sv_death.lua:126: attempt to call field 'PhysBoneToHitGroup' (a nil value)
  1. unknown - gamemodes/mrp/gamemode/modules/death/sv_death.lua:126




  • what I saw there isn’t such a function like util.PhysBoneToHitGroup()

I posted util.PhysBoneToHitGroup() a few messages back. Edited so it isn’t hidden by the scrollbar though

oh I see it now, sorry.

[editline]3rd September 2017[/editline]

Now it’s always returning somewhere…

I kinda edited the code and now it works! Do you allow me to send your edited code as a solution?

Sure, do whatever you want with it.