117 lines
No EOL
2.7 KiB
Lua
117 lines
No EOL
2.7 KiB
Lua
fedhoria = {}
|
|
|
|
local modules = {}
|
|
|
|
function fedhoria.GetModule(name)
|
|
if modules[name] then
|
|
return modules[name]
|
|
end
|
|
local path = "fedhoria/modules/"..name..".lua"
|
|
if !file.Exists(path, "LUA") then
|
|
print("fedhoria.GetModule failed, couldn't find module '"..name.."'")
|
|
return
|
|
end
|
|
local MODULE_old = MODULE
|
|
MODULE = {}
|
|
include(path)
|
|
modules[name] = MODULE
|
|
MODULE = MODULE_old
|
|
|
|
return modules[name]
|
|
end
|
|
|
|
function fedhoria.GetModuleList()
|
|
return modules
|
|
end
|
|
|
|
function fedhoria.StartModule(ent, name, ...)
|
|
if (!modules[name] and !fedhoria.GetModule(name)) then
|
|
return false
|
|
end
|
|
local contr = ents.Create("active_ragdoll_controller")
|
|
contr:SetTarget(ent)
|
|
contr:SetModule(modules[name])
|
|
contr:SetInitParams(...)
|
|
contr:Spawn()
|
|
|
|
return contr
|
|
end
|
|
|
|
--preload modules
|
|
for _, file_name in pairs(file.Find("fedhoria/modules/*.lua", "LUA")) do
|
|
fedhoria.GetModule(file_name:sub(1, -5))
|
|
end
|
|
|
|
local ENTITY = FindMetaTable("Entity")
|
|
|
|
--TODO: make this actually take mass into account
|
|
function ENTITY:GetMassCenter()
|
|
local center = Vector(0, 0, 0)
|
|
local mass = 0
|
|
local count = self:GetPhysicsObjectCount()
|
|
for phys_bone = 0, count - 1 do
|
|
local phys = self:GetPhysicsObjectNum(phys_bone)
|
|
local m = phys:GetMass()
|
|
mass = mass * m
|
|
--center:Add(phys:LocalToWorld(phys:GetMassCenter()) * m)
|
|
center:Add(phys:LocalToWorld(phys:GetMassCenter()))
|
|
end
|
|
--center:Div(mass)
|
|
center:Div(count)
|
|
return center
|
|
end
|
|
|
|
local PCOLLIDE_CACHE = {}
|
|
|
|
local vec_max = Vector(1, 1, 1) * 4
|
|
local vec_min = -vec_max
|
|
|
|
function ENTITY:GetClosestPhysBone(pos)
|
|
local mdl = self:GetModel()
|
|
local collides = PCOLLIDE_CACHE[mdl]
|
|
if !collides then
|
|
PCOLLIDE_CACHE[mdl] = CreatePhysCollidesFromModel(mdl)
|
|
collides = PCOLLIDE_CACHE[mdl]
|
|
end
|
|
|
|
if !collides then return end
|
|
|
|
local closest_bone
|
|
local dist = math.huge
|
|
|
|
for phys_bone = 0, self:GetPhysicsObjectCount() - 1 do
|
|
local phys = self:GetPhysicsObjectNum(phys_bone)
|
|
local collide = collides[phys_bone + 1]
|
|
if IsValid(collide) then
|
|
local phys_pos = phys:GetPos()
|
|
local phys_ang = phys:GetAngles()
|
|
local lpos = phys:WorldToLocal(pos)
|
|
local hitpos, _, d = collide:TraceBox(phys_pos, phys_ang, pos, pos, vec_min, vec_max)
|
|
if hitpos then
|
|
if (d < dist) then
|
|
dist = d
|
|
closest_bone = phys_bone
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return closest_bone
|
|
end
|
|
|
|
local PHYS = FindMetaTable("PhysObj")
|
|
|
|
function PHYS:GetID()
|
|
local ent = self:GetEntity()
|
|
for phys_bone = 0, ent:GetPhysicsObjectCount() - 1 do
|
|
if (ent:GetPhysicsObjectNum(phys_bone) == self) then
|
|
return phys_bone
|
|
end
|
|
end
|
|
return -1
|
|
end
|
|
|
|
function PHYS:GetAABBCenter()
|
|
local min, max = self:GetAABB()
|
|
return (min + max) / 2
|
|
end |