2026-06-04 02:55:35 +00:00
|
|
|
AddCSLuaFile()
|
|
|
|
|
|
|
|
|
|
ENT.Type = "anim"
|
|
|
|
|
ENT.Base = "base_anim"
|
|
|
|
|
ENT.AutomaticFrameAdvance = true
|
|
|
|
|
|
|
|
|
|
local bones_to_animate = {
|
|
|
|
|
"ValveBiped.Bip01_Pelvis",
|
|
|
|
|
"ValveBiped.Bip01_Spine2",
|
|
|
|
|
"ValveBiped.Bip01_Head1",
|
|
|
|
|
"ValveBiped.Bip01_R_Thigh",
|
|
|
|
|
"ValveBiped.Bip01_L_Thigh",
|
|
|
|
|
"ValveBiped.Bip01_L_Calf",
|
|
|
|
|
"ValveBiped.Bip01_R_Calf",
|
|
|
|
|
"ValveBiped.Bip01_R_Foot",
|
|
|
|
|
"ValveBiped.Bip01_L_Foot",
|
|
|
|
|
"ValveBiped.Bip01_R_Upperarm",
|
|
|
|
|
"ValveBiped.Bip01_L_Upperarm",
|
|
|
|
|
"ValveBiped.Bip01_R_Forearm",
|
|
|
|
|
"ValveBiped.Bip01_L_Forearm",
|
|
|
|
|
"ValveBiped.Bip01_R_Hand",
|
|
|
|
|
"ValveBiped.Bip01_L_Hand",
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
-- Copy pasted directly from the GMOD wiki with small edits
|
|
|
|
|
local function SetRagdollPos(ragdoll, pos)
|
|
|
|
|
for i = 0, ragdoll:GetPhysicsObjectCount() - 1 do
|
|
|
|
|
local phys = ragdoll:GetPhysicsObjectNum(i)
|
|
|
|
|
local localPos = ragdoll:WorldToLocal( phys:GetPos() )
|
|
|
|
|
phys:SetPos(pos + localPos)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2026-06-04 02:55:35 +00:00
|
|
|
function ENT:Initialize()
|
|
|
|
|
if SERVER then
|
|
|
|
|
print("I AM SERVERSIDE")
|
|
|
|
|
self:SetModel("models/dav0r/hoverball.mdl")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if CLIENT then
|
|
|
|
|
print("I AM CLIENTSIDE")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
function ENT:Think()
|
2026-06-04 02:55:35 +00:00
|
|
|
if CLIENT then
|
2026-06-04 17:03:20 +00:00
|
|
|
|
|
|
|
|
hook.Add("physics")
|
2026-06-04 02:55:35 +00:00
|
|
|
local old_ragdoll = self:GetNWEntity("parent")
|
|
|
|
|
local old_npc = self:GetNWEntity("parent_npc")
|
|
|
|
|
if IsValid(old_ragdoll) and IsValid(old_npc) then
|
2026-06-04 17:03:20 +00:00
|
|
|
local ragdoll = self.ragdoll
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
if !self.ready_to_animate then
|
|
|
|
|
self.ragdoll = ClientsideRagdoll(old_ragdoll:GetModel())
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
ragdoll = self.ragdoll
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
self.ragdoll:SetNoDraw(false)
|
|
|
|
|
self.ragdoll:DrawShadow(true)
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
SetRagdollPos(self.ragdoll, old_ragdoll:GetPos())
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
print(self.ragdoll)
|
|
|
|
|
print("SHOW UP YOU PIECE OF SHIT")
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
for i, name in pairs(bones_to_animate) do
|
|
|
|
|
local object = ragdoll:GetPhysicsObjectNum(ragdoll:TranslateBoneToPhysBone(ragdoll:LookupBone(name)))
|
|
|
|
|
local parent_object = old_ragdoll:GetBoneMatrix(old_ragdoll:LookupBone(name))
|
2026-06-04 19:28:40 +00:00
|
|
|
print(parent_object)
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 19:28:40 +00:00
|
|
|
if parent_object == nil then continue end
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
object:SetPos(parent_object:GetTranslation())
|
|
|
|
|
object:SetAngles(parent_object:GetAngles())
|
2026-06-04 02:55:35 +00:00
|
|
|
end
|
|
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
self.ready_to_animate = true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local fake_start = self:GetNWFloat("fake_start")
|
|
|
|
|
local fake_end = self:GetNWFloat("fake_end")
|
|
|
|
|
|
|
|
|
|
local progress = (CurTime() - fake_start) / (fake_end - fake_start)
|
|
|
|
|
|
|
|
|
|
for i, name in pairs(bones_to_animate) do
|
|
|
|
|
local object = ragdoll:GetPhysicsObjectNum(ragdoll:TranslateBoneToPhysBone(ragdoll:LookupBone(name)))
|
|
|
|
|
local parent_bone = old_npc:LookupBone(name)
|
|
|
|
|
|
|
|
|
|
if parent_bone == -1 then continue end
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
local parent_bone_matrix = old_npc:GetBoneMatrix(parent_bone)
|
|
|
|
|
if !parent_bone_matrix then continue end
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
local parent_bone_pos, parent_bone_angle = parent_bone_matrix:GetTranslation(), parent_bone_matrix:GetAngles()
|
|
|
|
|
local old_bone_pos, old_bone_angle = object:GetPos(), object:GetAngles()
|
|
|
|
|
--parent_bone_angle.y = parent_bone_angle.y + 90
|
2026-06-04 02:55:35 +00:00
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
local shadow_data = {
|
|
|
|
|
secondstoarrive = 0.01,
|
|
|
|
|
pos = LerpVector(progress, old_bone_pos, parent_bone_pos),
|
|
|
|
|
angle = LerpAngle(progress, old_bone_angle, parent_bone_angle),
|
|
|
|
|
maxspeed = 400 * 4,
|
|
|
|
|
maxangular = 2000 * 4,
|
|
|
|
|
maxspeeddamp = 120 * 4,
|
|
|
|
|
maxangularspeeddamp = 600 * 4,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-- Can't set position inside physics tick, crashes the game instantly.
|
|
|
|
|
-- Instead, send a shadow for it to follow (I think? I don't know GMod is kinda funky)
|
|
|
|
|
object:ComputeShadowControl(shadow_data)
|
|
|
|
|
|
|
|
|
|
object:Wake()
|
|
|
|
|
|
|
|
|
|
--i = i + 1
|
2026-06-04 02:55:35 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2026-06-04 17:03:20 +00:00
|
|
|
self:NextThink(CurTime() + 0.1)
|
2026-06-04 02:55:35 +00:00
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function ENT:OnRemove()
|
|
|
|
|
if CLIENT then
|
2026-06-04 17:03:20 +00:00
|
|
|
if self.ragdoll then
|
|
|
|
|
self.ragdoll:Remove()
|
|
|
|
|
end
|
2026-06-04 02:55:35 +00:00
|
|
|
end
|
2026-06-04 17:03:20 +00:00
|
|
|
end
|