@@ -6,7 +6,18 @@ ENT.RenderGroup = RENDERGROUP_BOTH
66ENT .WireDebugName = " Lamp"
77
88function ENT :SetupDataTables ()
9- self :NetworkVar (" Bool" , 0 , " On" )
9+ self :NetworkVar (" Bool" , " On" )
10+ self :NetworkVar (" Int" , " FOV" )
11+ self :NetworkVar (" Int" , " Distance" )
12+ self :NetworkVar (" Int" , " Brightness" )
13+ self :NetworkVar (" String" , " Texture" )
14+
15+ if CLIENT then
16+ self :NetworkVarNotify (" FOV" , self .OnVarChanged )
17+ self :NetworkVarNotify (" Distance" , self .OnVarChanged )
18+ self :NetworkVarNotify (" Brightness" , self .OnVarChanged )
19+ self :NetworkVarNotify (" Texture" , self .OnVarChanged )
20+ end
1021end
1122
1223function ENT :GetEntityDriveMode ()
@@ -36,135 +47,161 @@ local vector_offset = Vector(5, 0, 0)
3647if CLIENT then
3748 local light = Material (" sprites/light_ignorez" )
3849
39- function ENT :DrawEffects ( )
40- if not self : GetOn () then return end
50+ function ENT :DrawTranslucent ( flags )
51+ BaseClass . DrawTranslucent ( self , flags )
4152
42- local light_info = self :GetLightInfo ()
43- local lightpos = self :LocalToWorld (light_info .Offset or vector_offset )
53+ if self :GetOn () then
54+ local light_info = self :GetLightInfo ()
55+ local lightpos = self :LocalToWorld (light_info .Offset or vector_offset )
4456
45- local viewnormal = EyePos ()
46- viewnormal :Negate ()
47- viewnormal :Add (lightpos )
57+ local viewnormal = EyePos ()
58+ viewnormal :Negate ()
59+ viewnormal :Add (lightpos )
4860
49- local distance = viewnormal :Length ()
50- viewnormal :Negate ()
61+ local distance = viewnormal :Length ()
62+ viewnormal :Negate ()
5163
52- local viewdot = viewnormal :Dot (self :LocalToWorldAngles (light_info .Angle or angle_zero ):Forward ()) / distance
53- if viewdot < 0 then return end
64+ local viewdot = viewnormal :Dot (self :LocalToWorldAngles (light_info .Angle or angle_zero ):Forward ()) / distance
65+ if viewdot < 0 then return end
5466
55- local visibile = util .PixelVisible (lightpos , 16 , self .PixVis )
56- local visdot = visibile * viewdot
67+ local visibile = util .PixelVisible (lightpos , 16 , self .PixVis )
68+ local visdot = visibile * viewdot
5769
58- render .SetMaterial (light )
70+ render .SetMaterial (light )
5971
60- local color = self :GetColor ()
61- color .a = math .Clamp ((1000 - math .Clamp (distance , 32 , 800 )) * visdot , 0 , 100 )
72+ local color = self :GetColor ()
73+ color .a = math .Clamp ((1000 - math .Clamp (distance , 32 , 800 )) * visdot , 0 , 100 )
6274
63- local size = math .Clamp (distance * visdot * (light_info .Scale or 2 ), 64 , 512 )
64- render .DrawSprite (lightpos , size , size , color )
75+ local size = math .Clamp (distance * visdot * (light_info .Scale or 2 ), 64 , 512 )
76+ render .DrawSprite (lightpos , size , size , color )
6577
66- color .r , color .g , color .b = 255 , 255 , 255
67- render .DrawSprite (lightpos , size * 0.4 , size * 0.4 , color )
68- end
69-
70- function ENT :DrawTranslucent (flags )
71- BaseClass .DrawTranslucent (self , flags )
72- self :DrawEffects ()
78+ color .r , color .g , color .b = 255 , 255 , 255
79+ render .DrawSprite (lightpos , size * 0.4 , size * 0.4 , color )
80+ end
7381 end
74- end
7582
76- function ENT :Switch (on )
77- if on == IsValid (self .flashlight ) then return end
83+ function ENT :OnVarChanged (name , old , new )
84+ local flashlight = self .Flashlight
85+ if not flashlight then return end
86+
87+ if name == " FOV" then
88+ flashlight :SetFOV (game .SinglePlayer () and new or math .Clamp (new , 0 , 170 ))
89+ elseif name == " Distance" then
90+ flashlight :SetFarZ (game .SinglePlayer () and new or math .Clamp (new , 64 , 2048 ))
91+ elseif name == " Brightness" then
92+ flashlight :SetBrightness (game .SinglePlayer () and new or math .Clamp (new , 0 , 8 ))
93+ elseif name == " Texture" then
94+ flashlight :SetTexture (new )
95+ end
7896
79- self .on = on
80- self :SetOn (on )
97+ self .LastLampMatrix = nil
98+ self .LastLampColor = nil
99+ end
81100
82- if not on then
83- SafeRemoveEntity ( self . flashlight )
84- self . flashlight = nil
101+ function ENT : Think ()
102+ if not self : GetOn () then
103+ self : OnRemove ()
85104
86- return
87- end
105+ return
106+ end
88107
89- local flashlight = ents .Create (" env_projectedtexture" )
90- self .flashlight = flashlight
91- flashlight :SetParent (self )
108+ if not self .Flashlight then
109+ local light_info = self :GetLightInfo ()
110+ local flashlight = ProjectedTexture ()
111+ local singleplayer = game .SinglePlayer ()
92112
93- local singleplayer = game .SinglePlayer ()
94- local light_info = self :GetLightInfo ()
95- local offset = (light_info .Offset or vector_offset ) * - 1
96- offset .x = offset .x + 5
113+ flashlight :SetNearZ (light_info .NearZ or 12 )
114+ flashlight :SetFarZ (singleplayer and self :GetDistance () or math .Clamp (self :GetDistance (), 64 , 2048 ))
115+ flashlight :SetFOV (singleplayer and self :GetFOV () or math .Clamp (self :GetFOV (), 0 , 170 ))
116+ flashlight :SetBrightness (singleplayer and self :GetBrightness () or math .Clamp (self :GetBrightness (), 0 , 8 ))
117+ flashlight :SetTexture (self :GetTexture ())
97118
98- flashlight :SetLocalPos (- offset )
99- flashlight :SetLocalAngles (light_info .Angle or angle_zero )
100- flashlight :SetKeyValue (" enableshadows" , 1 )
101- flashlight :SetKeyValue (" nearz" , light_info .NearZ or 12 )
102- flashlight :SetKeyValue (" farz" , singleplayer and self .Dist or math .Clamp (self .Dist , 64 , 2048 ))
103- flashlight :SetKeyValue (" lightfov" , singleplayer and self .FOV or math .Clamp (self .FOV , 10 , 170 ))
119+ self .Flashlight = flashlight
120+ end
104121
105- local color = self :GetColor ()
106- local brightness = singleplayer and self .Brightness or math .Clamp (self .Brightness , 0 , 8 )
107- flashlight :SetKeyValue (" lightcolor" , Format (" %i %i %i 255" , color .r * brightness , color .g * brightness , color .b * brightness ))
108- flashlight :Spawn ()
122+ local matrix = self :GetWorldTransformMatrix ()
123+ local color = self :GetColor ()
109124
110- flashlight :Input (" SpotlightTexture" , NULL , NULL , self .Texture )
111- end
125+ if self .LastLampMatrix ~= matrix or self .LastLampColor ~= color then
126+ local flashlight = self .Flashlight
127+ local light_info = self :GetLightInfo ()
128+ local lightpos = self :LocalToWorld (light_info .Offset or vector_offset )
112129
113- function ENT : UpdateLight ( )
114- local color = Color ( self . r , self . g , self . b , self : GetColor (). a )
115- self :SetOverlayText ( string.format ( " Red: %i Green: %i Blue: %i \n FOV: %i Distance: %i Brightness: %i " , color . r , color . g , color . b , self . FOV , self . Dist , self . Brightness ))
116- self : SetColor ( color )
130+ flashlight : SetColor ( color )
131+ flashlight : SetPos ( lightpos )
132+ flashlight : SetAngles ( self :LocalToWorldAngles ( light_info . Angle or angle_zero ))
133+ flashlight : Update ( )
117134
118- local flashlight = self .flashlight
119- if not IsValid (flashlight ) then return end
135+ self .LastLampMatrix = matrix
136+ self .LastLampColor = color
137+ end
138+ end
120139
121- local singleplayer = game .SinglePlayer ()
122- flashlight :Input (" SpotlightTexture" , NULL , NULL , self .Texture )
123- flashlight :Input (" FOV" , NULL , NULL , tostring (singleplayer and self .FOV or math .Clamp (self .FOV , 10 , 170 )))
124- flashlight :SetKeyValue (" farz" , singleplayer and self .Dist or math .Clamp (self .Dist , 64 , 2048 ))
140+ function ENT :OnRemove ()
141+ if self .Flashlight then
142+ self .Flashlight :Remove ()
143+ self .Flashlight = nil
144+ self .LastLampMatrix = nil
145+ self .LastLampColor = nil
146+ end
147+ end
125148
126- local brightness = singleplayer and self .Brightness or math .Clamp (self .Brightness , 0 , 8 )
127- flashlight :SetKeyValue (" lightcolor" , Format (" %i %i %i 255" , color .r * brightness , color .g * brightness , color .b * brightness ))
149+ return
128150end
129151
130152function ENT :TriggerInput (name , value )
131- if name == " Red" then
132- self .r = math .Clamp (value , 0 , 255 )
153+ local color = self :GetColor ()
154+
155+ if name == " On" then
156+ self :SetOn (value ~= 0 )
157+ elseif name == " FOV" then
158+ self :SetFOV (value )
159+ elseif name == " Red" then
160+ local color = self :GetColor ()
161+ color .r = value
162+ self :SetColor (color )
133163 elseif name == " Green" then
134- self .g = math .Clamp (value , 0 , 255 )
164+ local color = self :GetColor ()
165+ color .g = value
166+ self :SetColor (color )
135167 elseif name == " Blue" then
136- self .b = math .Clamp (value , 0 , 255 )
168+ local color = self :GetColor ()
169+ color .b = value
170+ self :SetColor (color )
137171 elseif name == " RGB" then
138- self .r , self .g , self .b = math .Clamp (value .r , 0 , 255 ), math .Clamp (value .g , 0 , 255 ), math .Clamp (value .b , 0 , 255 )
139- elseif name == " FOV" then
140- self .FOV = value
172+ local color = self :GetColor ()
173+ color .r = value .r
174+ color .g = value .g
175+ color .b = value .b
176+ self :SetColor (color )
141177 elseif name == " Distance" then
142- self . Dist = value
178+ self : SetDistance ( value )
143179 elseif name == " Brightness" then
144- self .Brightness = value
145- elseif name == " On" then
146- self :Switch (value ~= 0 )
180+ self :SetBrightness (value )
147181 elseif name == " Texture" then
148182 if value ~= " " then
149- self . Texture = value
183+ self : SetTexture ( value )
150184 else
151- self . Texture = " effects/flashlight001"
185+ self : SetTexture ( " effects/flashlight001" )
152186 end
153187 end
188+ end
154189
155- self :UpdateLight ()
190+ function ENT :PrepareOverlayData ()
191+ local color = self :GetColor ()
192+ self :SetOverlayText (string.format (" Red: %i Green: %i Blue: %i\n FOV: %i Distance: %i Brightness: %i" , color .r , color .g , color .b , self :GetFOV (), self :GetDistance (), self :GetBrightness ()))
156193end
157194
158195function ENT :Setup (r , g , b , texture , fov , distance , brightness , on )
159- self . Texture = texture or " effects/flashlight001 "
160- self . FOV = fov or 90
161- self . Dist = distance or 1024
162- self . Brightness = brightness or 8
163- self . r , self . g , self . b = math . Clamp ( r or 255 , 0 , 255 ), math . Clamp ( g or 255 , 0 , 255 ), math . Clamp ( b or 255 , 0 , 255 )
164-
165- self . on = on and true or false
166- self : Switch ( self . on )
167- self :UpdateLight ( )
196+ self : SetOn ( on and true or false )
197+ self : SetFOV ( fov or 90 )
198+ self : SetDistance ( distance or 1024 )
199+ self : SetBrightness ( brightness or 8 )
200+ self : SetTexture ( texture or " effects/flashlight001 " )
201+
202+ local color = self : GetColor ()
203+ color . r , color . g , color . b = math . Clamp ( r or 255 , 0 , 255 ), math . Clamp ( g or 255 , 0 , 255 ), math . Clamp ( b or 255 , 0 , 255 )
204+ self :SetColor ( color )
168205end
169206
170207duplicator .RegisterEntityClass (" gmod_wire_lamp" , WireLib .MakeWireEnt , " Data" , " r" , " g" , " b" , " Texture" , " FOV" , " Dist" , " Brightness" , " on" )
0 commit comments