TOOL.Category = "Render" TOOL.Name = "#Dynamic Light" TOOL.Command = nil TOOL.ConfigName = "" TOOL.ClientConVar["r"] = "255" TOOL.ClientConVar["g"] = "255" TOOL.ClientConVar["b"] = "255" TOOL.ClientConVar["a"] = "255" TOOL.ClientConVar["fx"] = "0" TOOL.ClientConVar["distance"] = "50" TOOL.ClientConVar["brightness"] = "5" TOOL.ClientConVar["key"] = "5" cleanup.Register( "dynlight" ) if SERVER then CreateConVar( "sbox_maxdynlights", 5 ) //This function is called by the number pad to turn a light on and off function dynlight_toggle( ply, ent ) if not ent:IsValid() then return end ent:Fire("toggle","","0") end numpad.Register( "dynlighttoggle", dynlight_toggle ) function lightsouteverybody( the_light ) the_light:Fire("turnoff","","0") the_light:Remove() end //3 entities are now used, dynlightw is welded to dynlightp, dynlightp is the parent of the dynamic light entity. function makedynlight( ply, trace, Ang, r, g, b, a, fx, distance, brightness, key ) local dynlightw = ents.Create( "prop_physics" ) dynlightw:SetPos( trace.HitPos ) local dynlightwpos = dynlightw:GetPos()+Vector( 0, 0, 3 ) dynlightw:SetPos( dynlightwpos ) dynlightw:SetModel( "models/props_junk/PopCan01a.mdl" ) dynlightw:SetKeyValue( "disableshadows", "1" ) dynlightw:Spawn() dynlightw:CallOnRemove( "dynlightfix", lightsouteverybody, dynlight ) local dynlightp = ents.Create( "prop_physics" ) dynlightp:SetPos( trace.HitPos ) dynlightp:SetModel( "models/items/combine_rifle_ammo01.mdl" ) dynlightp:SetKeyValue( "disableshadows", "1" ) dynlightp:Spawn() //Double weld and no collide to keep dynlightw and dynlightp together const = constraint.Weld( dynlightw, dynlightp, 0, 0, 0, systemmanager ) const = constraint.Weld( dynlightp, dynlightw, 0, 0, 0, systemmanager ) nocollide = constraint.NoCollide( dynlightw, dynlightp, 0, 0 ) local dynlight = ents.Create( "light_dynamic" ) dynlight:SetPos( trace.HitPos ) local dynlightpos = dynlight:GetPos()+Vector( 0, 0, 7 ) dynlight:SetPos( dynlightpos ) dynlight:SetKeyValue( "_light", r .. " " .. g .. " " .. b .. " " .. a ) dynlight:SetKeyValue( "style", fx ) dynlight:SetKeyValue( "distance", distance ) dynlight:SetKeyValue( "brightness", brightness ) dynlight:SetParent( dynlightp ) dynlight:Spawn() dynlightw:SetAngles( Ang ) //more welding code, executed if the player is aiming at a prop when firing the stool if ( trace.Entity:IsValid() ) then const = constraint.Weld( dynlightw, trace.Entity,0, trace.PhysicsBone, 0, systemmanager ) nocollide = constraint.NoCollide( dynlightw, trace.Entity, 0, trace.PhysicsBone ) trace.Entity:DeleteOnRemove( dynlightw ) end //numpad register numpad.OnDown( ply, key, "dynlighttoggle", dynlight ) //undo and clean up, dynlightw is the only ent that is cleaned up/undone. undo.Create( "DynamicLight" ) undo.AddEntity( dynlightw ) undo.SetPlayer( ply ) undo.Finish() cleanup.Add( ply, "dynlights", dynlightw ) ply:AddCount( "dynlights", dynlightw ) ply:AddCleanup( "dynlight", dynlightw ) return true end end //language file stuff //so you dont need a text file for the stool if ( CLIENT ) then language.Add( "Tool_dynlight_name", "Dynamic Light" ) language.Add( "Tool_dynlight_desc", "Creates lights that dynamically illuminate an area around them" ) language.Add( "Tool_dynlight_0", "Left click somewhere to spawn a dynamic light" ) language.Add( "Tool_dynlight_col", "The colour and brightness setting for the dynamic light" ) language.Add( "Tool_dynlight_distance", "The maximum distance around the dynamic light that is allowed to be illuminated" ) language.Add( "Tool_dynlight_brightness", "How bright the light is" ) language.Add( "Undone_DynamicLight", "Undone Dynamic Light" ) language.Add( "Cleanup_dynlight", "Dynamic Lights" ) language.Add( "Cleaned_dynlight", "Cleaned up all Dynamic Lights" ) language.Add( "SBoxLimit_dynlights", "You've hit the Dynamic Light limit!" ) end //this is what happens when you left click function TOOL:LeftClick( trace ) if ( !self:GetSWEP():CheckLimit( "dynlights" ) ) then return false end if trace.Entity && (trace.Entity:IsPlayer() ) then return false end local ply = self:GetOwner() local r = self:GetClientInfo( "r" ) local g = self:GetClientInfo( "g" ) local b = self:GetClientInfo( "b" ) local a = self:GetClientInfo( "a" ) local fx = self:GetClientInfo( "fx" ) local distance = self:GetClientInfo( "distance" ) local brightness = self:GetClientInfo( "brightness" ) local key = self:GetClientInfo( "key" ) local Ang = trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 makedynlight( ply, trace, Ang, r, g, b, a, fx, distance, brightness, key ) end //right clicking does the same as left clicking function TOOL:RightClick( trace ) return self:LeftClick( trace, true ) end //the control panel stuff function TOOL.BuildCPanel( cp ) cp:AddControl( "Header", { Text = "#Tool_dynlight_name", Description = "#Tool_dynlight_desc" } ) local params = { Label = "#Presets", MenuButton = 1, Folder = "dynlight", Options = {}, CVars = {} } params.Options.default = { dynlight_r = 255, dynlight_g = 255, dynlight_b = 255, dynlight_a = 255, dynlight_fx = 0, dynlight_distance = 50, dynlight_brightness = 5, dynlight_toggle = 1, dynlight_starton = 1, } table.insert( params.CVars, "dynlight_r" ) table.insert( params.CVars, "dynlight_g" ) table.insert( params.CVars, "dynlight_b" ) table.insert( params.CVars, "dynlight_a" ) table.insert( params.CVars, "dynlight_fx" ) table.insert( params.CVars, "dynlight_distance" ) table.insert( params.CVars, "dynlight_brightness" ) table.insert( params.CVars, "dynlight_toggle" ) table.insert( params.CVars, "dynlight_starton" ) cp:AddControl( "ComboBox", params ) cp:AddControl( "Color", { Label = "#Tool_dynlight_col", Red = "dynlight_r", Green = "dynlight_g", Blue = "dynlight_b", Alpha = "dynlight_a", Multiplier = "255" } ) cp:AddControl( "Slider", { Label = "#Light Radius", Description = "#Tool_dynlight_distance", Type = "Float", Min = 0, Max = 1000, Command = "dynlight_distance" } ) cp:AddControl( "Slider", { Label = "#Brightness Multiplier", Description = "#Tool_dynlight_brightness", Type = "Integer", Min = 0, Max = 10, Command = "dynlight_brightness" } ) local params = {Label = "Render FX", MenuButton = "0", Options = {}} params.Options["Normal"] = {dynlight_fx = "0"} params.Options["Fluorescent Flicker"] = {dynlight_fx = "10"} params.Options["Slow, Strong Pulse"] = {dynlight_fx = "2"} params.Options["Slow Pulse"] = {dynlight_fx = "11"} params.Options["Gentle Pulse"] = {dynlight_fx = "5"} params.Options["Flicker A"] = {dynlight_fx = "1"} params.Options["Flicker B"] = {dynlight_fx = "6"} params.Options["Candle A"] = {dynlight_fx = "3"} params.Options["Candle B"] = {dynlight_fx = "7"} params.Options["Candle C"] = {dynlight_fx = "8"} params.Options["Fast Strobe"] = {dynlight_fx = "4"} params.Options["Slow Strobe"] = {dynlight_fx = "9"} cp:AddControl( "ComboBox", params ) cp:AddControl( "Numpad", { Label = "#Light On/Off", Command = "dynlight_key", ButtonSize = 22 } ) end //ghost entity function TOOL:UpdateGhostDynlight( 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 || trace.Entity:IsPlayer() ) then ent:SetNoDraw( true ) return end local Ang = trace.HitNormal:Angle() Ang.pitch = Ang.pitch + 90 ent:SetAngles( Ang ) local min = ent:OBBMins() ent:SetPos( trace.HitPos - trace.HitNormal * min.z ) ent:SetNoDraw( false ) end function TOOL:Think() if ( !self.GhostEntity || !self.GhostEntity:IsValid() || self.GhostEntity:GetModel() !="models/props_junk/PopCan01a.mdl" ) then self:MakeGhostEntity( "models/props_junk/PopCan01a.mdl", Vector(0,0,0), Angle(0,0,0) ) end self:UpdateGhostDynlight( self.GhostEntity, self:GetOwner() ) end