```lua
-- Файл: lua/autorun/server/realistic_corpse.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

    -- Проверяем, является ли повреждаемая сущность игроком или NPC
    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: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 * 400 + Vector(0, 0, 200)
    elseif bit.band(dmgType, DAMAGE_TYPE.FIRE) ~= 0 or bit.band(dmgType, DAMAGE_TYPE.CHEMICAL) ~= 0 then
        -- Огонь или химический урон: слегка поднимаем рэгдолл
        forceVector = Vector(0, 0, 200)
    elseif bit.band(dmgType, DAMAGE_TYPE.SLASH) ~= 0 then
        -- Режущий урон: небольшое отбрасывание
        forceVector = forceDir * 300 + Vector(0, 0, 100)
    else
        -- Общий урон: стандартное падение с легким отталкиванием вверх
        forceVector = Vector(0, 0, 150)
    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
                phys:ApplyForceCenter(forceVector)
            end
        end
    end)

    -- Добавляем таймер для автоматического удаления рэгдолла через 5 минут
    timer.Simple(300, function()
        if IsValid(rag) then
            rag:Remove()
        end
    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)

    -- Удаляем стандартный рэгдолл, созданный Garry's Mod
    timer.Simple(0.1, function()
        if not IsValid(victim) then return end

        -- Поиск ближайшего рэгдолла к позиции смерти
        local closestRagdoll = nil
        local minDistance = 100 -- Максимальное расстояние для поиска

        for _, ent in ipairs(ents.FindByClass("prop_ragdoll")) do
            local distance = ent:GetPos():Distance(pos)
            if distance < minDistance then
                closestRagdoll = ent
                minDistance = distance
            end
        end

        -- Удаляем ближайший рэгдолл, считая его стандартным
        if IsValid(closestRagdoll) then
            closestRagdoll:Remove()
        end
    end)
end)

-- Хук для создания рэгдолла при смерти NPC
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)

    -- Удаляем стандартный рэгдолл, созданный Garry's Mod
    timer.Simple(0.1, function()
        if not IsValid(npc) then return end

        -- Поиск ближайшего рэгдолла к позиции смерти
        local closestRagdoll = nil
        local minDistance = 100 -- Максимальное расстояние для поиска

        for _, ent in ipairs(ents.FindByClass("prop_ragdoll")) do
            local distance = ent:GetPos():Distance(pos)
            if distance < minDistance then
                closestRagdoll = ent
                minDistance = distance
            end
        end

        -- Удаляем ближайший рэгдолл, считая его стандартным
        if IsValid(closestRagdoll) then
            closestRagdoll:Remove()
        end
    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)
```
Сделай чтобы рэгдоллы после смерти немного двигались, так же сделай их физику реалистичнее, исправь баги