191 lines
5.3 KiB
Lua
191 lines
5.3 KiB
Lua
AddCSLuaFile()
|
|
DEFINE_BASECLASS( "base_wire_entity" )
|
|
ENT.PrintName = "Wire Grabber"
|
|
ENT.RenderGroup = RENDERGROUP_BOTH
|
|
ENT.WireDebugName = "Grabber"
|
|
|
|
function ENT:SetupDataTables()
|
|
self:NetworkVar( "Float", 0, "BeamLength" )
|
|
end
|
|
|
|
if CLIENT then return end -- No more client
|
|
|
|
function ENT:Initialize()
|
|
self:PhysicsInit( SOLID_VPHYSICS )
|
|
self:SetMoveType( MOVETYPE_VPHYSICS )
|
|
self:SetSolid( SOLID_VPHYSICS )
|
|
self.Inputs = Wire_CreateInputs(self, { "Grab","Strength","Range" })
|
|
self.Outputs = Wire_CreateOutputs(self, {"Holding", "Grabbed Entity [ENTITY]"})
|
|
self.WeldStrength = 0
|
|
self.Weld = nil
|
|
self.WeldEntity = nil
|
|
self.ExtraProp = nil
|
|
self.ExtraPropWeld = nil
|
|
self:GetPhysicsObject():SetMass(10)
|
|
|
|
self:Setup(100, true)
|
|
end
|
|
|
|
function ENT:OnRemove()
|
|
if self.Weld then
|
|
self:ResetGrab()
|
|
end
|
|
Wire_Remove(self)
|
|
end
|
|
|
|
function ENT:Setup(Range, Gravity)
|
|
if Range then self:SetBeamLength(Range) end
|
|
self.Gravity = Gravity
|
|
end
|
|
|
|
function ENT:LinkEnt( prop )
|
|
if not IsValid(prop) then return false, "Not a valid entity!" end
|
|
self.ExtraProp = prop
|
|
WireLib.SendMarks(self, {prop})
|
|
return true
|
|
end
|
|
function ENT:UnlinkEnt()
|
|
if IsValid(self.ExtraPropWeld) then
|
|
self.ExtraPropWeld:Remove()
|
|
self.ExtraPropWeld = nil
|
|
end
|
|
self.ExtraProp = nil
|
|
WireLib.SendMarks(self, {})
|
|
return true
|
|
end
|
|
|
|
function ENT:ResetGrab()
|
|
if IsValid(self.Weld) then
|
|
self.Weld:Remove()
|
|
if IsValid(self.WeldEntity) and IsValid(self.WeldEntity:GetPhysicsObject()) and self.Gravity then
|
|
self.WeldEntity:GetPhysicsObject():EnableGravity(true)
|
|
end
|
|
end
|
|
if IsValid(self.ExtraPropWeld) then
|
|
self.ExtraPropWeld:Remove()
|
|
end
|
|
|
|
self.Weld = nil
|
|
self.WeldEntity = nil
|
|
self.ExtraPropWeld = nil
|
|
|
|
self:SetColor(Color(255, 255, 255, self:GetColor().a))
|
|
Wire_TriggerOutput(self, "Holding", 0)
|
|
Wire_TriggerOutput(self, "Grabbed Entity", self.WeldEntity)
|
|
end
|
|
|
|
function ENT:CanGrab(trace)
|
|
if not trace.Entity or not isentity(trace.Entity) then return false end
|
|
if (not trace.Entity:IsValid() and not trace.Entity:IsWorld()) or trace.Entity:IsPlayer() then return false end
|
|
-- If there's no physics object then we can't constraint it!
|
|
if not util.IsValidPhysicsObject(trace.Entity, trace.PhysicsBone) then return false end
|
|
|
|
if not gamemode.Call( "CanTool", self:GetPlayer(), trace, "weld" ) then return false end
|
|
|
|
return true
|
|
end
|
|
|
|
function ENT:TriggerInput(iname, value)
|
|
if iname == "Grab" then
|
|
if value ~= 0 and self.Weld == nil then
|
|
local vStart = self:GetPos()
|
|
local vForward = self:GetUp()
|
|
|
|
local filter = ents.FindByClass( "gmod_wire_spawner" ) -- for prop spawning contraptions that grab spawned props
|
|
table.insert( filter, self )
|
|
|
|
local trace = util.TraceLine {
|
|
start = vStart,
|
|
endpos = vStart + (vForward * self:GetBeamLength()),
|
|
filter = filter
|
|
}
|
|
if not self:CanGrab(trace) then return end
|
|
|
|
-- Weld them!
|
|
local const = constraint.Weld(self, trace.Entity, 0, 0, self.WeldStrength)
|
|
if const then
|
|
const.Type = "" --prevents the duplicator from making this weld
|
|
end
|
|
|
|
local const2
|
|
--Msg("+Weld1\n")
|
|
if self.ExtraProp then
|
|
if self.ExtraProp:IsValid() then
|
|
const2 = constraint.Weld(self.ExtraProp, trace.Entity, 0, 0, self.WeldStrength)
|
|
if const2 then
|
|
const2.Type = "" --prevents the duplicator from making this weld
|
|
end
|
|
--Msg("+Weld2\n")
|
|
end
|
|
end
|
|
if self.Gravity then
|
|
trace.Entity:GetPhysicsObject():EnableGravity(false)
|
|
end
|
|
|
|
self.WeldEntity = trace.Entity
|
|
self.Weld = const
|
|
self.ExtraPropWeld = const2
|
|
|
|
self:SetColor(Color(255, 0, 0, self:GetColor().a))
|
|
Wire_TriggerOutput(self, "Holding", 1)
|
|
Wire_TriggerOutput(self, "Grabbed Entity", self.WeldEntity)
|
|
elseif value == 0 then
|
|
if self.Weld ~= nil or self.ExtraPropWeld ~= nil then
|
|
self:ResetGrab()
|
|
end
|
|
end
|
|
elseif iname == "Strength" then
|
|
self.WeldStrength = math.max(value,0)
|
|
elseif iname == "Range" then
|
|
self:SetBeamLength(math.Clamp(value,0,32000))
|
|
end
|
|
end
|
|
|
|
--duplicator support (TAD2020)
|
|
function ENT:BuildDupeInfo()
|
|
local info = BaseClass.BuildDupeInfo(self) or {}
|
|
|
|
if self.WeldEntity and self.WeldEntity:IsValid() then
|
|
info.WeldEntity = self.WeldEntity:EntIndex()
|
|
end
|
|
|
|
if self.ExtraProp and self.ExtraProp:IsValid() then
|
|
info.ExtraProp = self.ExtraProp:EntIndex()
|
|
end
|
|
|
|
return info
|
|
end
|
|
|
|
function ENT:ApplyDupeInfo(ply, ent, info, GetEntByID)
|
|
BaseClass.ApplyDupeInfo(self, ply, ent, info, GetEntByID)
|
|
|
|
self.WeldEntity = GetEntByID(info.WeldEntity)
|
|
|
|
self.ExtraProp = GetEntByID(info.ExtraProp)
|
|
|
|
if self.WeldEntity and self.Inputs.Grab.Value ~= 0 then
|
|
|
|
if not self.Weld and self.trace~=nil then
|
|
self.Weld = constraint.Weld(self, self.trace, 0, 0, self.WeldStrength)
|
|
self.Weld.Type = "" --prevents the duplicator from making this weld
|
|
end
|
|
|
|
if IsValid(self.ExtraProp) then
|
|
self.ExtraPropWeld = constraint.Weld(self.ExtraProp, self.WeldEntity, 0, 0, self.WeldStrength)
|
|
self.ExtraPropWeld.Type = "" --prevents the duplicator from making this weld
|
|
end
|
|
|
|
if self.Gravity then
|
|
self.WeldEntity:GetPhysicsObject():EnableGravity(false)
|
|
end
|
|
if self.Weld then
|
|
self:SetColor(Color(255, 0, 0, self:GetColor().a))
|
|
Wire_TriggerOutput(self, "Holding", 1)
|
|
Wire_TriggerOutput(self, "Grabbed Entity", self.WeldEntity)
|
|
else
|
|
self:ResetGrab()
|
|
end
|
|
end
|
|
end
|
|
|
|
duplicator.RegisterEntityClass("gmod_wire_grabber", WireLib.MakeWireEnt, "Data", "Range", "Gravity")
|