mirror of
https://github.com/wiremod/wire.git
synced 2025-03-04 03:03:04 -05:00
138 lines
4.3 KiB
Lua
138 lines
4.3 KiB
Lua
AddCSLuaFile()
|
|
DEFINE_BASECLASS( "base_wire_entity" )
|
|
ENT.PrintName = "Wire Forcer"
|
|
ENT.RenderGroup = RENDERGROUP_BOTH
|
|
ENT.WireDebugName = "Forcer"
|
|
|
|
function ENT:SetupDataTables()
|
|
self:NetworkVar( "Float", 0, "BeamLength" )
|
|
self:NetworkVar( "Bool", 0, "ShowBeam" )
|
|
self:NetworkVar( "Bool", 1, "BeamHighlight" )
|
|
end
|
|
|
|
if CLIENT then return end -- No more client
|
|
|
|
local wire_forcer_permissions = CreateConVar( "wire_forcer_permissions", 1, FCVAR_ARCHIVE, "0 = no check for forcers, 1 = GravGunPunt, 2 = GravGunPickupAllowed", 0, 2)
|
|
|
|
function ENT:Initialize()
|
|
self:PhysicsInit( SOLID_VPHYSICS )
|
|
self:SetMoveType( MOVETYPE_VPHYSICS )
|
|
self:SetSolid( SOLID_VPHYSICS )
|
|
|
|
self.Force = 0
|
|
self.OffsetForce = 0
|
|
self.Velocity = 0
|
|
|
|
self.Inputs = WireLib.CreateInputs( self, { "Force", "OffsetForce", "Velocity", "Length" } )
|
|
|
|
self:Setup(0, 100, true, false)
|
|
end
|
|
|
|
function ENT:Setup( Force, Length, ShowBeam, Reaction )
|
|
self.ForceMul = Force or 1
|
|
self.Reaction = Reaction or false
|
|
if Length then self:SetBeamLength(Length) end
|
|
if ShowBeam ~= nil then self:SetShowBeam(ShowBeam) end
|
|
self:ShowOutput()
|
|
end
|
|
|
|
function ENT:TriggerInput( name, value )
|
|
if (name == "Force") then
|
|
self.Force = value
|
|
self:SetBeamHighlight(value ~= 0)
|
|
self:ShowOutput()
|
|
elseif (name == "OffsetForce") then
|
|
self.OffsetForce = value
|
|
self:SetBeamHighlight(value ~= 0)
|
|
self:ShowOutput()
|
|
elseif (name == "Velocity") then
|
|
self.Velocity = math.Clamp(value,-100000,100000)
|
|
self:SetBeamHighlight(value ~= 0)
|
|
self:ShowOutput()
|
|
elseif (name == "Length") then
|
|
self:SetBeamLength(math.Round(value))
|
|
self:ShowOutput()
|
|
end
|
|
end
|
|
|
|
local clamp = WireLib.clampForce
|
|
|
|
function ENT:Think()
|
|
if self.Force == 0 and self.OffsetForce == 0 and self.Velocity == 0 then return end
|
|
|
|
local Forward = self:GetUp()
|
|
local BeamOrigin = self:GetPos() + Forward * self:OBBMaxs().z
|
|
|
|
local trace = util.TraceLine {
|
|
start = BeamOrigin,
|
|
endpos = BeamOrigin + self:GetBeamLength() * Forward,
|
|
filter = self
|
|
}
|
|
local ent = trace.Entity
|
|
|
|
if not IsValid(ent) then return end
|
|
|
|
if ent:GetMoveType() == MOVETYPE_PUSH then return end
|
|
|
|
local convar_value = wire_forcer_permissions:GetInt()
|
|
if convar_value==1 then
|
|
if not IsValid(self:GetPlayer()) or gamemode.Call( "GravGunPunt", self:GetPlayer(), ent )==false then return end
|
|
elseif convar_value==2 then
|
|
if not IsValid(self:GetPlayer()) or gamemode.Call( "GravGunPickupAllowed", self:GetPlayer(), ent )==false then return end
|
|
end
|
|
|
|
if hook.Run( "Wire_ForcerCanUse", self:GetPlayer(), ent, self ) == false then return end
|
|
|
|
if ent:GetMoveType() == MOVETYPE_VPHYSICS then
|
|
local phys = ent:GetPhysicsObject()
|
|
if not IsValid(phys) then return end
|
|
|
|
local force = clamp(Forward * self.Force * self.ForceMul)
|
|
local offsetForce = clamp(Forward * self.OffsetForce * self.ForceMul)
|
|
local velocity = clamp(Forward * self.Velocity)
|
|
|
|
if self.Force ~= 0 then phys:ApplyForceCenter( force ) end
|
|
if self.OffsetForce ~= 0 then phys:ApplyForceOffset( offsetForce, trace.HitPos ) end
|
|
if self.Velocity ~= 0 then phys:SetVelocityInstantaneous( velocity ) end
|
|
else
|
|
local velocity = clamp(Forward * self.Velocity)
|
|
if self.Velocity ~= 0 then ent:SetVelocity( velocity ) end
|
|
end
|
|
|
|
if self.Reaction and IsValid(self:GetPhysicsObject()) and (self.Force + self.OffsetForce ~= 0) then
|
|
local reactionForce = clamp(Forward * -(self.Force + self.OffsetForce) * self.ForceMul)
|
|
self:GetPhysicsObject():ApplyForceCenter( reactionForce )
|
|
end
|
|
|
|
self:NextThink( CurTime() )
|
|
return true
|
|
end
|
|
|
|
function ENT:ShowOutput()
|
|
self:SetOverlayText(
|
|
"Center Force = "..math.Round(self.ForceMul * self.Force)..
|
|
"\nOffset Force = "..math.Round(self.ForceMul * self.OffsetForce)..
|
|
"\nVelocity = "..math.Round(self.Velocity)..
|
|
"\nLength = " .. math.Round(self:GetBeamLength())
|
|
)
|
|
end
|
|
|
|
function ENT:BuildDupeInfo()
|
|
local info = BaseClass.BuildDupeInfo(self) or {}
|
|
info.ForceMul = self.ForceMul
|
|
info.Reaction = self.Reaction
|
|
return info
|
|
end
|
|
|
|
|
|
function ENT:ApplyDupeInfo(ply, ent, info, GetEntByID)
|
|
self:Setup( info.ForceMul, info.Length, info.ShowBeam, info.Reaction )
|
|
|
|
BaseClass.ApplyDupeInfo(self, ply, ent, info, GetEntByID)
|
|
end
|
|
|
|
--Moves old "A" input to new "Force" input for older saves
|
|
WireLib.AddInputAlias( "A", "Force" )
|
|
|
|
duplicator.RegisterEntityClass("gmod_wire_forcer", WireLib.MakeWireEnt, "Data", "Force", "Length", "ShowBeam", "Reaction")
|