mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
350 lines
7.5 KiB
Lua
350 lines
7.5 KiB
Lua
|
|
--[[
|
||
|
|
| This file was obtained through the combined efforts
|
||
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
||
|
|
|
|
||
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
||
|
|
|
|
||
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||
|
|
--]]
|
||
|
|
|
||
|
|
local Angle = Angle
|
||
|
|
local RealTime = RealTime
|
||
|
|
local NULL = NULL
|
||
|
|
|
||
|
|
function pac.GenerateNewUniqueID(part_data, base)
|
||
|
|
local part_data = table.Copy(part_data)
|
||
|
|
base = base or tostring(part_data)
|
||
|
|
|
||
|
|
local function fixpart(part)
|
||
|
|
for key, val in pairs(part.self) do
|
||
|
|
if val ~= "" and (key == "UniqueID" or key:sub(-3) == "UID") then
|
||
|
|
part.self[key] = pac.Hash(base .. val)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for _, part in pairs(part.children) do
|
||
|
|
fixpart(part)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return part_data
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
do
|
||
|
|
local force_draw_localplayer = false
|
||
|
|
|
||
|
|
hook.Add("ShouldDrawLocalPlayer", "pac_draw_2d_entity", function()
|
||
|
|
if force_draw_localplayer == true then
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
function pac.DrawEntity2D(ent, x, y, w, h, cam_pos, cam_ang, cam_fov, cam_nearz, cam_farz)
|
||
|
|
|
||
|
|
pac.ShowEntityParts(ent)
|
||
|
|
pac.ForceRendering(true)
|
||
|
|
|
||
|
|
ent = ent or pac.LocalPlayer
|
||
|
|
x = x or 0
|
||
|
|
y = y or 0
|
||
|
|
w = w or 64
|
||
|
|
h = h or 64
|
||
|
|
cam_ang = cam_ang or Angle(0, RealTime() * 25, 0)
|
||
|
|
cam_pos = cam_pos or ent:LocalToWorld(ent:OBBCenter()) - cam_ang:Forward() * ent:BoundingRadius() * 2
|
||
|
|
cam_fov = cam_fov or 90
|
||
|
|
|
||
|
|
pac.SetupBones(ent)
|
||
|
|
|
||
|
|
cam.Start2D()
|
||
|
|
cam.Start3D(cam_pos, cam_ang, cam_fov, x, y, w, h, cam_nearz or 5, cam_farz or 4096)
|
||
|
|
pac.FlashlightDisable(true)
|
||
|
|
|
||
|
|
force_draw_localplayer = true
|
||
|
|
ent:DrawModel()
|
||
|
|
pac.RenderOverride(ent, "opaque")
|
||
|
|
pac.RenderOverride(ent, "translucent")
|
||
|
|
force_draw_localplayer = false
|
||
|
|
|
||
|
|
pac.FlashlightDisable(false)
|
||
|
|
cam.End3D()
|
||
|
|
cam.End2D()
|
||
|
|
|
||
|
|
pac.ForceRendering(false)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function pac.SetupENT(ENT, owner)
|
||
|
|
ENT.pac_owner = ENT.pac_owner or owner or "self"
|
||
|
|
|
||
|
|
local function find(parent, name)
|
||
|
|
for _, part in ipairs(parent:GetChildren()) do
|
||
|
|
|
||
|
|
if part:GetName():lower():find(name) then
|
||
|
|
return part
|
||
|
|
end
|
||
|
|
|
||
|
|
local part = find(part, name)
|
||
|
|
if part then return part end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:FindPACPart(outfit, name)
|
||
|
|
|
||
|
|
name = name:lower()
|
||
|
|
|
||
|
|
if not outfit.self then
|
||
|
|
for _, val in pairs(outfit) do
|
||
|
|
local part = self:FindPACPart(val, name)
|
||
|
|
if part:IsValid() then
|
||
|
|
return part
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return NULL
|
||
|
|
end
|
||
|
|
|
||
|
|
self.pac_part_find_cache = self.pac_part_find_cache or {}
|
||
|
|
|
||
|
|
local part = self.pac_outfits[outfit.self.UniqueID] or NULL
|
||
|
|
|
||
|
|
if part:IsValid() then
|
||
|
|
local cached = self.pac_part_find_cache[name] or NULL
|
||
|
|
|
||
|
|
if cached:IsValid() then return cached end
|
||
|
|
|
||
|
|
part = find(part, name)
|
||
|
|
|
||
|
|
|
||
|
|
if part then
|
||
|
|
self.pac_part_find_cache[name] = part
|
||
|
|
|
||
|
|
return part
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return NULL
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:AttachPACPart(outfit, owner, keep_uniqueid)
|
||
|
|
|
||
|
|
if not outfit.self then
|
||
|
|
return self:AttachPACSession(outfit, owner)
|
||
|
|
end
|
||
|
|
|
||
|
|
if
|
||
|
|
(outfit.self.OwnerName == "viewmodel" or outfit.self.OwnerName == "hands") and
|
||
|
|
self:IsWeapon() and
|
||
|
|
self.Owner:IsValid() and
|
||
|
|
self.Owner:IsPlayer() and
|
||
|
|
self.Owner ~= pac.LocalPlayer
|
||
|
|
then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if not keep_uniqueid then
|
||
|
|
outfit = pac.GenerateNewUniqueID(outfit, self:EntIndex())
|
||
|
|
end
|
||
|
|
|
||
|
|
owner = owner or self.pac_owner or self.Owner
|
||
|
|
|
||
|
|
if self.pac_owner == "self" then
|
||
|
|
owner = self
|
||
|
|
elseif self[self.pac_owner] then
|
||
|
|
owner = self[self.pac_owner]
|
||
|
|
end
|
||
|
|
|
||
|
|
self.pac_outfits = self.pac_outfits or {}
|
||
|
|
|
||
|
|
local part = self.pac_outfits[outfit.self.UniqueID] or NULL
|
||
|
|
|
||
|
|
if part:IsValid() then
|
||
|
|
part:Remove()
|
||
|
|
end
|
||
|
|
|
||
|
|
part = pac.CreatePart(outfit.self.ClassName, owner, outfit)
|
||
|
|
|
||
|
|
self.pac_outfits[outfit.self.UniqueID] = part
|
||
|
|
|
||
|
|
self.pac_part_find_cache = {}
|
||
|
|
|
||
|
|
if self.pac_show_in_editor == nil then
|
||
|
|
self:SetShowPACPartsInEditor(false)
|
||
|
|
self.pac_show_in_editor = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
return part
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:RemovePACPart(outfit, keep_uniqueid)
|
||
|
|
if not outfit.self then
|
||
|
|
return self:RemovePACSession(outfit)
|
||
|
|
end
|
||
|
|
|
||
|
|
if not keep_uniqueid then
|
||
|
|
outfit = pac.GenerateNewUniqueID(outfit, self:EntIndex())
|
||
|
|
end
|
||
|
|
|
||
|
|
self.pac_outfits = self.pac_outfits or {}
|
||
|
|
|
||
|
|
local part = self.pac_outfits[outfit.self.UniqueID] or NULL
|
||
|
|
|
||
|
|
if part:IsValid() then
|
||
|
|
part:Remove()
|
||
|
|
end
|
||
|
|
|
||
|
|
self.pac_part_find_cache = {}
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:GetPACPartPosAng(outfit, name)
|
||
|
|
local part = self:FindPACPart(outfit, name)
|
||
|
|
|
||
|
|
if part:IsValid() and part.GetWorldPosition then
|
||
|
|
return part:GetWorldPosition(), part:GetWorldAngles()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:AttachPACSession(session)
|
||
|
|
for _, part in pairs(session) do
|
||
|
|
self:AttachPACPart(part)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:RemovePACSession(session)
|
||
|
|
for _, part in pairs(session) do
|
||
|
|
self:RemovePACPart(part)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:SetPACDrawDistance(dist)
|
||
|
|
self.pac_draw_distance = dist
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:GetPACDrawDistance()
|
||
|
|
return self.pac_draw_distance
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:SetShowPACPartsInEditor(b)
|
||
|
|
self.pac_outfits = self.pac_outfits or {}
|
||
|
|
|
||
|
|
for _, part in pairs(self.pac_outfits) do
|
||
|
|
part:SetShowInEditor(b)
|
||
|
|
end
|
||
|
|
|
||
|
|
self.pac_show_in_editor = b
|
||
|
|
end
|
||
|
|
|
||
|
|
function ENT:GetShowPACPartsInEditor()
|
||
|
|
return self.pac_show_in_editor
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function pac.SetupSWEP(SWEP, owner)
|
||
|
|
SWEP.pac_owner = owner or "Owner"
|
||
|
|
pac.SetupENT(SWEP, owner)
|
||
|
|
end
|
||
|
|
|
||
|
|
function pac.AddEntityClassListener(class, session, check_func, draw_dist)
|
||
|
|
|
||
|
|
if session.self then
|
||
|
|
session = {session}
|
||
|
|
end
|
||
|
|
|
||
|
|
draw_dist = 0
|
||
|
|
check_func = check_func or function(ent) return ent:GetClass() == class end
|
||
|
|
|
||
|
|
local id = "pac_auto_attach_" .. class
|
||
|
|
|
||
|
|
local weapons = {}
|
||
|
|
local function weapon_think()
|
||
|
|
for _, ent in pairs(weapons) do
|
||
|
|
if ent:IsValid() then
|
||
|
|
if ent.Owner and ent.Owner:IsValid() then
|
||
|
|
if not ent.AttachPACSession then
|
||
|
|
pac.SetupSWEP(ent)
|
||
|
|
end
|
||
|
|
|
||
|
|
if ent.Owner:GetActiveWeapon() == ent then
|
||
|
|
if not ent.pac_deployed then
|
||
|
|
ent:AttachPACSession(session)
|
||
|
|
ent.pac_deployed = true
|
||
|
|
end
|
||
|
|
|
||
|
|
ent.pac_last_owner = ent.Owner
|
||
|
|
else
|
||
|
|
if ent.pac_deployed then
|
||
|
|
ent:RemovePACSession(session)
|
||
|
|
ent.pac_deployed = false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
elseif (ent.pac_last_owner or NULL):IsValid() and not ent.pac_last_owner:Alive() then
|
||
|
|
if ent.pac_deployed then
|
||
|
|
ent:RemovePACSession(session)
|
||
|
|
ent.pac_deployed = false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function created(ent)
|
||
|
|
if ent:IsValid() and check_func(ent) then
|
||
|
|
if ent:IsWeapon() then
|
||
|
|
weapons[ent:EntIndex()] = ent
|
||
|
|
hook.Add("Think", id, weapon_think)
|
||
|
|
else
|
||
|
|
pac.SetupENT(ent)
|
||
|
|
ent:AttachPACSession(session)
|
||
|
|
ent:SetPACDrawDistance(draw_dist)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function removed(ent)
|
||
|
|
if ent:IsValid() and check_func(ent) and ent.pac_outfits then
|
||
|
|
ent:RemovePACSession(session)
|
||
|
|
weapons[ent:EntIndex()] = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for _, ent in pairs(ents.GetAll()) do
|
||
|
|
created(ent)
|
||
|
|
end
|
||
|
|
|
||
|
|
hook.Add("EntityRemoved", id, removed)
|
||
|
|
hook.Add("OnEntityCreated", id, created)
|
||
|
|
end
|
||
|
|
|
||
|
|
function pac.RemoveEntityClassListener(class, session, check_func)
|
||
|
|
if session.self then
|
||
|
|
session = {session}
|
||
|
|
end
|
||
|
|
|
||
|
|
check_func = check_func or function(ent) return ent:GetClass() == class end
|
||
|
|
|
||
|
|
for _, ent in pairs(ents.GetAll()) do
|
||
|
|
if check_func(ent) and ent.pac_outfits then
|
||
|
|
ent:RemovePACSession(session)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local id = "pac_auto_attach_" .. class
|
||
|
|
|
||
|
|
hook.Remove("Think", id)
|
||
|
|
hook.Remove("EntityRemoved", id)
|
||
|
|
hook.Remove("OnEntityCreated", id)
|
||
|
|
end
|
||
|
|
|
||
|
|
timer.Simple(0, function()
|
||
|
|
if easylua and luadev then
|
||
|
|
function easylua.PACSetClassListener(class_name, name, b)
|
||
|
|
if b == nil then
|
||
|
|
b = true
|
||
|
|
end
|
||
|
|
|
||
|
|
luadev.RunOnClients(("pac.%s(%q, {%s})"):format(b and "AddEntityClassListener" or "RemoveEntityClassListener", class_name, file.Read("pac3/".. name .. ".txt", "DATA")))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|