```lua
local EntityLastDamage = {}
local DAMAGE_TYPE = {
    BULLET = DMG_BULLET,
    BLAST = DMG_BLAST,
    SLASH = DMG_SLASH,
    FIRE = DMG_BURN,
    CHEMICAL = DMG_ACID,
    EXPLOSION = DMG_BLAST_SURFACE,
    FALL = DMG_FALL,
    GENERIC = DMG_GENERIC,
}

local CreatedRagdolls = {}
hook.Add("EntityTakeDamage", "StoreEntityLastDamageType", function(target, dmginfo)
    if not IsValid(target) then return end
    if target:IsPlayer() or target:IsNPC() then
        EntityLastDamage[target:EntIndex()] = dmginfo:GetDamageType()
        EntityLastDamage[target:EntIndex() .. "_attacker"] = dmginfo:GetAttacker()
    end
end)

local function CreateRealisticRagdoll(victim, position, angles, model, dmgType, attacker)
    if not IsValid(victim) then return end
    local rag = ents.Create("prop_ragdoll")
    if not IsValid(rag) then return end
    rag:SetModel(model)
    rag:SetPos(position)
    rag:SetAngles(angles)
    rag:SetNWBool("IsCustomRagdoll", true)
    rag:Spawn()
    local forceDir = Vector(0, 0, 0)
    if bit.band(dmgType, DAMAGE_TYPE.BULLET) ~= 0 then
        if IsValid(attacker) then
            forceDir = (rag:GetPos() - attacker:GetPos()):GetNormalized()
        else
            forceDir = Vector(0, 0, 1)
        end
    end

    local forceVector = Vector(0, 0, 0)
    if bit.band(dmgType, DAMAGE_TYPE.BLAST) ~= 0 or bit.band(dmgType, DAMAGE_TYPE.EXPLOSION) ~= 0 then
        forceVector = forceDir * 500 + Vector(0, 0, 300)
    elseif bit.band(dmgType, DAMAGE_TYPE.BULLET) ~= 0 then
        forceVector = forceDir * 600 + Vector(0, 0, 400)
    elseif bit.band(dmgType, DAMAGE_TYPE.FIRE) ~= 0 or bit.band(dmgType, DAMAGE_TYPE.CHEMICAL) ~= 0 then
        forceVector = Vector(0, 0, 250)
    elseif bit.band(dmgType, DAMAGE_TYPE.SLASH) ~= 0 then
        forceVector = forceDir * 400 + Vector(0, 0, 150)
    else
        forceVector = Vector(0, 0, 200)
    end

    timer.Simple(0.05, function()
        if not IsValid(rag) then return end
        for i = 0, rag:GetPhysicsObjectCount() - 1 do
            local phys = rag:GetPhysicsObjectNum(i)
            if IsValid(phys) then
                local variation = Vector(math.Rand(-50, 50), math.Rand(-50, 50), math.Rand(-50, 50))
                phys:ApplyForceCenter(forceVector + variation)
            end
        end
    end)

    timer.Simple(300, function() if IsValid(rag) then rag:Remove() end end)
end

local function RemoveDefaultRagdoll(pos)
    local closestRagdoll = nil
    local minDistance = 100
    for _, ent in ipairs(ents.FindByClass("prop_ragdoll")) do
        if not ent:GetNWBool("IsCustomRagdoll", false) then
            local distance = ent:GetPos():Distance(pos)
            if distance < minDistance then
                closestRagdoll = ent
                minDistance = distance
            end
        end
    end

    if IsValid(closestRagdoll) then closestRagdoll:Remove() end
end

hook.Add("PlayerDeath", "CreateRealisticCorpse_Player", function(victim, infl, attacker)
    if not IsValid(victim) then return end
    if CreatedRagdolls[victim:EntIndex()] then return end
    CreatedRagdolls[victim:EntIndex()] = true
    local model = victim:GetModel()
    local pos = victim:GetPos()
    local ang = victim:EyeAngles()
    local dmgType = EntityLastDamage[victim:EntIndex()] or DAMAGE_TYPE.GENERIC
    local lastAttacker = EntityLastDamage[victim:EntIndex() .. "_attacker"]
    CreateRealisticRagdoll(victim, pos, ang, model, dmgType, lastAttacker)
    timer.Simple(0.1, function()
        if not IsValid(victim) then return end
        RemoveDefaultRagdoll(pos)
    end)
end)

hook.Add("OnNPCKilled", "CreateRealisticCorpse_NPC", function(npc, attacker, inflictor)
    if not IsValid(npc) then return end
    if CreatedRagdolls[npc:EntIndex()] then return end
    CreatedRagdolls[npc:EntIndex()] = true
    local model = npc:GetModel()
    local pos = npc:GetPos()
    local ang = npc:GetAngles()
    local dmgType = EntityLastDamage[npc:EntIndex()] or DAMAGE_TYPE.GENERIC
    local lastAttacker = EntityLastDamage[npc:EntIndex() .. "_attacker"]
    CreateRealisticRagdoll(npc, pos, ang, model, dmgType, lastAttacker)
    timer.Simple(0.1, function()
        if not IsValid(npc) then return end
        RemoveDefaultRagdoll(pos)
    end)
end)

hook.Add("OnEntityRemoved", "CleanUpEntityDamageData", function(ent)
    if not IsValid(ent) then return end
    EntityLastDamage[ent:EntIndex()] = nil
    EntityLastDamage[ent:EntIndex() .. "_attacker"] = nil
    CreatedRagdolls[ent:EntIndex()] = nil
end)

hook.Add("PlayerDisconnected", "CleanUpPlayerDamageData", function(ply)
    if not IsValid(ply) then return end
    EntityLastDamage[ply:EntIndex()] = nil
    EntityLastDamage[ply:EntIndex() .. "_attacker"] = nil
    CreatedRagdolls[ply:EntIndex()] = nil
end)
```
Улучши физику рэгдоллов, чтобы они были иммерсивнее  и лучше.