TOOL.Category = "Conna's Tools" TOOL.Name = "#Sensor Tool" TOOL.Command = nil TOOL.ConfigName = "" TOOL.ClientConVar["Model"] = "models/props_lab/jar01a.mdl" TOOL.ClientConVar["Description"] = "" TOOL.ClientConVar["Length"] = "100" TOOL.ClientConVar["Key"] = "5" TOOL.ClientConVar["Inversed"] = "0" TOOL.ClientConVar["Once"] = "0" TOOL.ClientConVar["Water"] = "0" // Register cleanup.Register("sensors") // Console CreateConVar("sbox_maxsensors", 10, FCVAR_NOTIFY) // Client if (CLIENT) then // Tool language.Add("Tool_sensor_name", "Sensor Tool") language.Add("Tool_sensor_desc", "Sensor which holds key when an object blocks it") language.Add("Tool_sensor_0", "Left click to spawn a Sensor") // Other language.Add("Undone_sensor", "Undone Sensor") language.Add("SBoxLimit_sensors", "You've hit the Sensors limit!") language.Add("Cleanup_sensors", "Sensors") language.Add("Cleaned_sensors", "Cleaned up all Sensors") end // Message function TOOL:Message(Text) if SERVER then self:GetOwner():SendLua("GAMEMODE:AddNotify('"..Text.."', NOTIFY_GENERIC, 10)") self:GetOwner():SendLua("surface.PlaySound('ambient/water/drip"..math.random(1, 4)..".wav')") end end // Left click function TOOL:LeftClick(Trace) if(CLIENT) then return true end // Locals local Player = self:GetOwner() local Key = self:GetClientNumber("Key") local Once = self:GetClientNumber("Once") local Water = self:GetClientNumber("Water") local Len = self:GetClientNumber("Length") local Inversed = self:GetClientNumber("Inversed") local Description = self:GetClientInfo("Description") local Model = self:GetClientInfo("Model") // Keep it nice and whole Len = math.floor(Len) if (Trace.Entity and Trace.Entity:IsValid() and Trace.Entity:GetClass() == "gmod_sensor") then local Entity = Trace.Entity // Merge local Table = { Key = Key, Once = Once, Water = Water, Inversed = Inversed, Len = Len, Description = Description } table.Merge(Entity:GetTable(), Table) // Other Entity:GetTable():SetEntityLength(Len) Entity:GetTable():SetEntityKey(Key) Entity:GetTable():SetEntityLabel(Description) self:Message("Properties changed for Sensor!") return true end local Ang = Trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 local Sensor = CreateSensor(Player, Ang, Trace.HitPos, Model, Once, Inversed, Water, Len, Key, Description) if not (Sensor) then return false end local Minimum = Sensor:OBBMins() Sensor:SetPos(Trace.HitPos - Trace.HitNormal * Minimum.z) undo.Create("sensor") if (Trace.Entity and not Trace.Entity:IsWorld()) then local Weld = constraint.Weld(Sensor, Trace.Entity, 0, Trace.PhysicsBone, 0, true, true) undo.AddEntity(Weld) Player:AddCleanup("sensors", Weld) Sensor:GetPhysicsObject():EnableCollisions(false) end undo.AddEntity(Sensor) undo.SetPlayer(Player) undo.Finish() Player:AddCount("sensors", Sensor) Player:AddCleanup("sensors", Sensor) self:Message("Sensor has been created!") return true, Sensor end // Make it if (SERVER) then function CreateSensor(Player, Ang, Pos, Model, Once, Inversed, Water, Len, Key, Description, Nocollide, Vel, Avel, Frozen) if (!Player:CheckLimit("sensors")) then return false end local Sensor = ents.Create("gmod_sensor") util.PrecacheModel(Model) Sensor:SetModel(Model) Sensor:SetAngles(Ang) Sensor:SetPos(Pos) Sensor:Spawn() // Merge local Table = { Key = Key, Once, Once, Water = Water, Inversed = Inversed, Len = Len, Description = Description } table.Merge(Sensor:GetTable(), Table) // Set the entities owner Sensor:GetTable():SetPlayer(Player) // Other Sensor:GetTable():SetEntityLength(Len) Sensor:GetTable():SetEntityKey(Key) Sensor:GetTable():SetEntityLabel(Description) if Frozen then Sensor:GetPhysicsObject():EnableMotion(false) end if Nocollide then Sensor:GetPhysicsObject():EnableCollisions(false) end return Sensor end duplicator.RegisterEntityClass("gmod_sensor", CreateSensor, "Ang", "Pos", "Model", "Once", "Inversed", "Water", "Len", "Key", "Description", "Nocollide", "Vel", "Avel", "Frozen") end // Control panel function TOOL.BuildCPanel(Panel) Panel:AddControl("Header", {Text = "#Tool_sensor_name", Description = "#Tool_sensor_desc"}) local Models = {} Models["Jar"] = {} Models["Jar"]["sensor_Model"] = "models/props_lab/jar01a.mdl" Models["Doll"] = {} Models["Doll"]["sensor_Model"] = "models/props_lab/huladoll.mdl" Panel:AddControl("ComboBox", {Label = "Model", Options = Models, MenuButton = 0}) Panel:AddControl("Slider", {Label = "Length", Type = "Integer", Min = 0, Max = 5000, Command = "sensor_Length"}) Panel:AddControl("Numpad", {Label = "Key", Command = "sensor_Key", ButtonSize = 22}) Panel:AddControl("CheckBox", {Label = "Inversed", Command = "sensor_Inversed"}) Panel:AddControl("CheckBox", {Label = "Just press once don't continue to hold", Command = "sensor_Once"}) Panel:AddControl("CheckBox", {Label = "Just detect water and nothing else", Command = "sensor_Water"}) Panel:AddControl("TextBox", {Label = "Description", MaxLength = "100", Command = "sensor_Description"}) end // Ghost function TOOL:UpdateGhostSensor(Entity, Player) if (!Entity) then return end if (!Entity: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_sensor" || Trace.Entity:IsPlayer()) then Entity:SetNoDraw(true) return end local Ang = Trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 local Minimum = Entity:OBBMins() Entity:SetPos(Trace.HitPos - Trace.HitNormal * Minimum.z) Entity:SetAngles(Ang) Entity:SetNoDraw(false) end // Think function TOOL:Think() if not (self.Precached) then util.PrecacheModel("models/props_lab/jar01a.mdl") self.Precached = true end if (self:GetOwner() and self:GetOwner():IsPlayer()) then if (!self.GhostEntity || !self.GhostEntity:IsValid() || self.GhostEntity:GetModel() != self:GetClientInfo("Model")) then self:MakeGhostEntity(self:GetClientInfo("Model"), Vector(0, 0, 0), Angle(0, 0, 0) ) end self:UpdateGhostSensor(self.GhostEntity, self:GetOwner()) end end