TOOL.Category = "Wire - Data" TOOL.Name = "Keycard" TOOL.Command = nil TOOL.ConfigName = "" if ( CLIENT ) then language.Add( "Tool_wire_keycard_name", "Keycard Tool (Wire)" ) language.Add( "Tool_wire_keycard_desc", "Create portable media for use with the wire system." ) language.Add( "Tool_wire_keycard_0", "Primary: Create/Update Spawner Secondary: Create/Update Reader" ) language.Add( "sboxlimit_wire_keycardspawners", "You've hit keycard spawner limit!" ) language.Add( "sboxlimit_wire_keycardreaders", "You've hit keycard reader limit!" ) language.Add( "undone_wirekeycardspawner", "Undone Wire Keycard Spawner" ) language.Add( "undone_wirekeycardreader", "Undone Wire Keycard Reader" ) language.Add( "WireKeycardTool_GeneralOpt", "General Options" ) language.Add( "WireKeycardTool_LockCode", "Lock Code Modifier" ) language.Add( "WireKeycardTool_ReaderOpt", "Reader Options" ) language.Add( "WireKeycardTool_ReadMode", "Read Mode" ) language.Add( "WireKeycardTool_LCMode", "Lock Code Matching" ) language.Add( "WireKeycardTool_BeamLength", "Range" ) CreateClientConVar("wire_keycardtool_lockcode", "0", true, true) CreateClientConVar("wire_keycardtool_beamlength", "100", true, true) CreateClientConVar("wire_keycardtool_readmode", "0", true, true) CreateClientConVar("wire_keycardtool_lcmode", "0", true, true) end if (SERVER) then CreateConVar('sbox_maxwire_keycardspawners', 10) CreateConVar('sbox_maxwire_keycardreaders', 10) end // TOOL.ClientConVar[ "z_only" ] = "1" TOOL.Model = "models/keycardspawner/keycardspawner.mdl" cleanup.Register( "wire_keycardspawners" ) cleanup.Register( "wire_keycardreaders" ) function TOOL:LeftClick( trace ) if trace.Entity && trace.Entity:IsPlayer() then return false end // If there's no physics object then we can't constraint it! if ( SERVER && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) ) then return false end if (CLIENT) then return true end local ply = self:GetOwner() // local z_only = (self:GetClientNumber("z_only") ~= 0) // If we shot a wire_keycardspawner or wire_keycardreader do nothing if ( trace.Entity:IsValid() && trace.Entity.pl == ply ) then if (trace.Entity:GetClass() == "gmod_wire_keycardspawner") then // trace.Entity:Setup(z_only) // trace.Entity.z_only = z_only return true elseif (trace.Entity:GetClass() == "gmod_wire_keycardreader") then // Handle card reader stuff on right-click. return true end end if ( !self:GetSWEP():CheckLimit( "wire_keycardspawners" ) ) then return false end if (not util.IsValidModel(self.Model)) then return false end if (not util.IsValidProp(self.Model)) then return false end // Allow ragdolls to be used? local Ang = trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 wire_keycardspawner = MakeWireKeycardSpawner( ply, Ang, trace.HitPos ) // TODO: pass configs as parameters to this fn (eg. z_only) local min = wire_keycardspawner:OBBMins() wire_keycardspawner:SetPos( trace.HitPos - trace.HitNormal * min.z ) local const = WireLib.Weld(wire_keycardspawner, trace.Entity, trace.PhysicsBone, true) undo.Create("WireKeycardSpawner") undo.AddEntity( wire_keycardspawner ) undo.AddEntity( const ) undo.SetPlayer( ply ) undo.Finish() ply:AddCleanup( "wire_keycardspawner", wire_keycardspawner ) ply:AddCleanup( "wire_keycardspawner", const ) return true end function TOOL:RightClick( trace ) if trace.Entity && trace.Entity:IsPlayer() then return false end // If there's no physics object then we can't constraint it! if ( SERVER && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) ) then return false end if (CLIENT) then return true end local ply = self:GetOwner() // local z_only = (self:GetClientNumber("z_only") ~= 0) // If we shot a wire_keycardspawner or wire_keycardreader do nothing if ( trace.Entity:IsValid() && trace.Entity.pl == ply ) then if (trace.Entity:GetClass() == "gmod_wire_keycardspawner") then // Handle card spawner stuff on right-click. return true elseif (trace.Entity:GetClass() == "gmod_wire_keycardreader") then // trace.Entity:Setup(z_only) // trace.Entity.z_only = z_only return true end end if ( !self:GetSWEP():CheckLimit( "wire_keycardreaders" ) ) then return false end if (not util.IsValidModel(self.Model)) then return false end if (not util.IsValidProp(self.Model)) then return false end // Allow ragdolls to be used? local Ang = trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 wire_keycardreader = MakeWireKeycardReader( ply, Ang, trace.HitPos ) // TODO: pass configs as parameters to this fn (eg. z_only) local min = wire_keycardreader:OBBMins() wire_keycardreader:SetPos( trace.HitPos - trace.HitNormal * min.z ) wire_keycardreader:SetRange(math.Max(0, ply:GetInfoNum("wire_keycardtool_beamlength"))) wire_keycardreader:SetReadMode(ply:GetInfoNum("wire_keycardtool_readmode")) wire_keycardreader:SetLCMatchMode(ply:GetInfoNum("wire_keycardtool_lcmode")) local const = WireLib.Weld(wire_keycardreader, trace.Entity, trace.PhysicsBone, true) undo.Create("WireKeycardReader") undo.AddEntity( wire_keycardreader ) undo.AddEntity( const ) undo.SetPlayer( ply ) undo.Finish() ply:AddCleanup( "wire_keycardreader", wire_keycardreader ) ply:AddCleanup( "wire_keycardreader", const ) return true end if (SERVER) then function MakeWireKeycardSpawner( pl, Ang, Pos ) if ( !pl:CheckLimit( "wire_keycardspawners" ) ) then return false end local wire_keycardspawner = ents.Create( "gmod_wire_keycardspawner" ) if (!wire_keycardspawner:IsValid()) then return false end wire_keycardspawner:SetAngles( Ang ) wire_keycardspawner:SetPos( Pos ) wire_keycardspawner:SetModel( Model("models/keycardspawner/keycardspawner.mdl") ) wire_keycardspawner:SetLockCode((pl:UserID() + 1) * 100 + math.Clamp(math.Round(pl:GetInfoNum("wire_keycardtool_lockcode")), 0, 99)) wire_keycardspawner:Spawn() pl:AddCount( "wire_keycardspawners", wire_keycardspawner ) return wire_keycardspawner end function MakeWireKeycardReader( pl, Ang, Pos ) if ( !pl:CheckLimit( "wire_keycardreaders" ) ) then return false end local wire_keycardreader = ents.Create( "gmod_wire_keycardreader" ) if (!wire_keycardreader:IsValid()) then return false end wire_keycardreader:SetAngles( Ang ) wire_keycardreader:SetPos( Pos ) wire_keycardreader:SetModel( Model("models/jaanus/wiretool/wiretool_range.mdl") ) wire_keycardreader:SetLockCode((pl:UserID() + 1) * 100 + math.Clamp(math.Round(pl:GetInfoNum("wire_keycardtool_lockcode")), 0, 99)) wire_keycardreader:SetRange(math.Max(0, pl:GetInfoNum("wire_keycardtool_beamlength"))) wire_keycardreader:SetReadMode(pl:GetInfoNum("wire_keycardtool_readmode")) wire_keycardreader:SetLCMatchMode(pl:GetInfoNum("wire_keycardtool_lcmode")) wire_keycardreader:Spawn() pl:AddCount( "wire_keycardreaders", wire_keycardreader ) return wire_keycardreader end // TODO: Examine this. Keycards need to be Duplicator compatible. // duplicator.RegisterEntityClass("gmod_wire_keycardspawner", MakeWireKeycardSpawner, "Ang", "Pos", "z_only", "nocollide", "Vel", "aVel", "frozen") // duplicator.RegisterEntityClass("gmod_wire_keycardreader", MakeWireKeycardReader, "Ang", "Pos", "z_only", "nocollide", "Vel", "aVel", "frozen") end function TOOL:UpdateGhostWireKeycardSpawner( ent, player ) if ( !ent ) then return end if ( !ent:IsValid() ) then return end local tr = utilx.GetPlayerTrace( player, player:GetCursorAimVector() ) local trace = util.TraceLine( tr ) if (!trace.Hit) then return end if (trace.Entity && trace.Entity:GetClass() == "gmod_wire_keycardspawner" || trace.Entity:IsPlayer()) then ent:SetNoDraw( true ) return end local Ang = trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 local min = ent:OBBMins() ent:SetPos( trace.HitPos - trace.HitNormal * min.z ) ent:SetAngles( Ang ) ent:SetNoDraw( false ) end function TOOL:Think() if (!self.GhostEntity || !self.GhostEntity:IsValid() || self.GhostEntity:GetModel() != self.Model ) then self:MakeGhostEntity( self.Model, Vector(0,0,0), Angle(0,0,0) ) end self:UpdateGhostWireKeycardSpawner( self.GhostEntity, self:GetOwner() ) end function TOOL.BuildCPanel(panel) panel:AddControl("Header", { Text = "#Tool_wire_keycard_name", Description = "#Tool_wire_keycard_desc" }) panel:AddControl("Header", { Text = "#WireKeycardTool_GeneralOpt" } ) panel:AddControl("Slider", { Label = "#WireKeycardTool_LockCode", Description = "", Type = "Integer", Min = "0", Max = "99", Command = "wire_keycardtool_lockcode"}) panel:AddControl("Header", { Text = "#WireKeycardTool_ReaderOpt" } ) local combobox = {} combobox.Label = "#WireKeycardTool_ReadMode" combobox.MenuButton = 0 combobox.Options = {} combobox.Options["Read with a beam"] = {wire_keycardtool_readmode = 0} combobox.Options["Read nearest keycard"] = {wire_keycardtool_readmode = 1} panel:AddControl("ComboBox", combobox) local combobox = {} combobox.Label = "#WireKeycardTool_LCMode" combobox.MenuButton = 0 combobox.Options = {} combobox.Options["Inclusive (read even if lock code is different)"] = {wire_keycardtool_lcmode = 0} combobox.Options["Exclusive (ignore if lock code is different)"] = {wire_keycardtool_lcmode = 1} panel:AddControl("ComboBox", combobox) panel:AddControl("Slider", { Label = "#WireKeycardTool_BeamLength", Description = "", Type = "Float", Min = "1", Max = "1000", Command = "wire_keycardtool_beamlength"}) end