mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
238 lines
4.8 KiB
Lua
238 lines
4.8 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 BUILDER, PART = pac.PartTemplate("base")
|
||
|
|
|
||
|
|
PART.ThinkTime = 0
|
||
|
|
PART.ClassName = "physics"
|
||
|
|
|
||
|
|
PART.Group = 'model'
|
||
|
|
PART.Icon = 'icon16/shape_handles.png'
|
||
|
|
|
||
|
|
BUILDER:StartStorableVars()
|
||
|
|
BUILDER:GetSet("Box", true)
|
||
|
|
BUILDER:GetSet("Radius", 1)
|
||
|
|
BUILDER:GetSet("SelfCollision", false)
|
||
|
|
BUILDER:GetSet("Gravity", true)
|
||
|
|
BUILDER:GetSet("Collisions", true)
|
||
|
|
BUILDER:GetSet("Mass", 100)
|
||
|
|
|
||
|
|
BUILDER:GetSet("Follow", false)
|
||
|
|
|
||
|
|
BUILDER:GetSet("SecondsToArrive", 0.1)
|
||
|
|
|
||
|
|
BUILDER:GetSet("MaxSpeed", 10000)
|
||
|
|
BUILDER:GetSet("MaxAngular", 3600)
|
||
|
|
|
||
|
|
BUILDER:GetSet("MaxSpeedDamp", 1000)
|
||
|
|
BUILDER:GetSet("MaxAngularDamp", 1000)
|
||
|
|
BUILDER:GetSet("DampFactor", 1)
|
||
|
|
|
||
|
|
BUILDER:GetSet("ConstrainSphere", 0)
|
||
|
|
BUILDER:EndStorableVars()
|
||
|
|
|
||
|
|
local function IsInvalidParent(self)
|
||
|
|
return self.Parent.ClassName ~= "model" and self.Parent.ClassName ~= "model2"
|
||
|
|
end
|
||
|
|
|
||
|
|
PART.phys = NULL
|
||
|
|
|
||
|
|
function PART:SetBox(b)
|
||
|
|
self.Box = b
|
||
|
|
self:SetRadius(self.Radius)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetCollisions(b)
|
||
|
|
self.Collisions = b
|
||
|
|
|
||
|
|
if self.phys:IsValid() then
|
||
|
|
self.phys:EnableCollisions(b)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetMass(n)
|
||
|
|
self.Mass = n
|
||
|
|
|
||
|
|
if self.phys:IsValid() then
|
||
|
|
self.phys:SetMass(math.Clamp(n, 0.001, 50000))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetRadius(n)
|
||
|
|
self.Radius = n
|
||
|
|
|
||
|
|
if IsInvalidParent(self) then return end
|
||
|
|
|
||
|
|
local ent = self.Parent:GetOwner()
|
||
|
|
|
||
|
|
if n <= 0 then n = ent:BoundingRadius()/2 end
|
||
|
|
|
||
|
|
ent:SetNoDraw(false)
|
||
|
|
|
||
|
|
if self.Box then
|
||
|
|
ent:PhysicsInitBox(Vector(1,1,1) * -n, Vector(1,1,1) * n)
|
||
|
|
else
|
||
|
|
ent:PhysicsInitSphere(n)
|
||
|
|
end
|
||
|
|
|
||
|
|
self.phys = ent:GetPhysicsObject()
|
||
|
|
|
||
|
|
if self.Gravity ~= nil then
|
||
|
|
self.phys:EnableGravity(self.Gravity)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetGravity(b)
|
||
|
|
self.Gravity = b
|
||
|
|
|
||
|
|
if self.phys:IsValid() then
|
||
|
|
self.phys:EnableGravity(b)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetSelfCollision(b)
|
||
|
|
self.SelfCollision = b
|
||
|
|
|
||
|
|
if IsInvalidParent(self) then return end
|
||
|
|
|
||
|
|
local ent = self.Parent:GetOwner()
|
||
|
|
|
||
|
|
if b then
|
||
|
|
ent:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||
|
|
else
|
||
|
|
ent:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local params = {}
|
||
|
|
|
||
|
|
function PART:OnThink()
|
||
|
|
|
||
|
|
if self.Parent.GetWorldPosition then
|
||
|
|
if self.disabled then
|
||
|
|
self:Enable()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if not self.disabled then
|
||
|
|
self:Disable()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
local phys = self.phys
|
||
|
|
|
||
|
|
if phys:IsValid() then
|
||
|
|
phys:Wake()
|
||
|
|
|
||
|
|
if self.Follow then
|
||
|
|
params.pos = self.Parent:GetWorldPosition()
|
||
|
|
params.angle = self.Parent:GetWorldAngles()
|
||
|
|
|
||
|
|
params.secondstoarrive = math.max(self.SecondsToArrive, 0.0001)
|
||
|
|
params.maxangular = self.MaxAngular
|
||
|
|
params.maxangulardamp = self.MaxAngularDamp
|
||
|
|
params.maxspeed = self.MaxSpeed
|
||
|
|
params.maxspeeddamp = self.MaxSpeedDamp
|
||
|
|
params.dampfactor = self.DampFactor
|
||
|
|
|
||
|
|
params.teleportdistance = 0
|
||
|
|
|
||
|
|
phys:ComputeShadowControl(params)
|
||
|
|
|
||
|
|
|
||
|
|
-- this is nicer i think
|
||
|
|
if self.ConstrainSphere ~= 0 and phys:GetPos():Distance(self.Parent:GetWorldPosition()) > self.ConstrainSphere then
|
||
|
|
phys:SetPos(self.Parent:GetWorldPosition() + (self.Parent:GetWorldPosition() - phys:GetPos()):GetNormalized() * -self.ConstrainSphere)
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if self.ConstrainSphere ~= 0 then
|
||
|
|
local offset = self.Parent:GetWorldPosition() - phys:GetPos()
|
||
|
|
|
||
|
|
if offset:Length() > self.ConstrainSphere then
|
||
|
|
phys:SetPos(self.Parent:GetWorldPosition() - offset:GetNormalized() * self.ConstrainSphere)
|
||
|
|
phys:SetVelocity(Vector())
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnParent(part)
|
||
|
|
timer.Simple(0, function() self:Enable() end)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnUnParent(part)
|
||
|
|
timer.Simple(0, function() self:Disable() end)
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
function PART:OnShow()
|
||
|
|
timer.Simple(0, function() self:Enable() end)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnHide()
|
||
|
|
timer.Simple(0, function() self:Disable() end)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:Enable()
|
||
|
|
if IsInvalidParent(self) then return end
|
||
|
|
|
||
|
|
local part = self:GetParent()
|
||
|
|
|
||
|
|
part.skip_orient = true
|
||
|
|
|
||
|
|
local ent = part:GetOwner()
|
||
|
|
ent:SetNoDraw(false)
|
||
|
|
|
||
|
|
self:SetRadius(self.Radius)
|
||
|
|
|
||
|
|
for key, val in pairs(self.StorableVars) do
|
||
|
|
if pac.registered_parts.base.StorableVars[key] then goto CONTINUE end
|
||
|
|
self["Set" .. key](self, self[key])
|
||
|
|
::CONTINUE::
|
||
|
|
end
|
||
|
|
|
||
|
|
self.disabled = false
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:Disable()
|
||
|
|
if IsInvalidParent(self) then return end
|
||
|
|
|
||
|
|
local part = self:GetParent()
|
||
|
|
|
||
|
|
local ent = part:GetOwner()
|
||
|
|
if ent:IsValid() then
|
||
|
|
-- SetNoDraw does not care of validity but PhysicsInit does?
|
||
|
|
ent:SetNoDraw(true)
|
||
|
|
ent:PhysicsInit(SOLID_NONE)
|
||
|
|
end
|
||
|
|
part.skip_orient = false
|
||
|
|
|
||
|
|
self.disabled = true
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetPositionDamping(num)
|
||
|
|
self.PositionDamping = num
|
||
|
|
|
||
|
|
if self.phys:IsValid() then
|
||
|
|
self.phys:SetDamping(self.PositionDamping, self.AngleDamping)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetAngleDamping(num)
|
||
|
|
self.AngleDamping = num
|
||
|
|
|
||
|
|
if self.phys:IsValid() then
|
||
|
|
self.phys:SetDamping(self.PositionDamping, self.AngleDamping)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
BUILDER:Register()
|