diff --git a/lua/entities/gmod_wire_lamp.lua b/lua/entities/gmod_wire_lamp.lua index 03a37e4895..a582064ca5 100644 --- a/lua/entities/gmod_wire_lamp.lua +++ b/lua/entities/gmod_wire_lamp.lua @@ -6,7 +6,18 @@ ENT.RenderGroup = RENDERGROUP_BOTH ENT.WireDebugName = "Lamp" function ENT:SetupDataTables() - self:NetworkVar("Bool", 0, "On") + self:NetworkVar("Bool", "On") + self:NetworkVar("Int", "FOV") + self:NetworkVar("Int", "Distance") + self:NetworkVar("Int", "Brightness") + self:NetworkVar("String", "Texture") + + if CLIENT then + self:NetworkVarNotify("FOV", self.OnVarChanged) + self:NetworkVarNotify("Distance", self.OnVarChanged) + self:NetworkVarNotify("Brightness", self.OnVarChanged) + self:NetworkVarNotify("Texture", self.OnVarChanged) + end end function ENT:GetEntityDriveMode() @@ -36,135 +47,161 @@ local vector_offset = Vector(5, 0, 0) if CLIENT then local light = Material("sprites/light_ignorez") - function ENT:DrawEffects() - if not self:GetOn() then return end + function ENT:DrawTranslucent(flags) + BaseClass.DrawTranslucent(self, flags) - local light_info = self:GetLightInfo() - local lightpos = self:LocalToWorld(light_info.Offset or vector_offset) + if self:GetOn() then + local light_info = self:GetLightInfo() + local lightpos = self:LocalToWorld(light_info.Offset or vector_offset) - local viewnormal = EyePos() - viewnormal:Negate() - viewnormal:Add(lightpos) + local viewnormal = EyePos() + viewnormal:Negate() + viewnormal:Add(lightpos) - local distance = viewnormal:Length() - viewnormal:Negate() + local distance = viewnormal:Length() + viewnormal:Negate() - local viewdot = viewnormal:Dot(self:LocalToWorldAngles(light_info.Angle or angle_zero):Forward()) / distance - if viewdot < 0 then return end + local viewdot = viewnormal:Dot(self:LocalToWorldAngles(light_info.Angle or angle_zero):Forward()) / distance + if viewdot < 0 then return end - local visibile = util.PixelVisible(lightpos, 16, self.PixVis) - local visdot = visibile * viewdot + local visibile = util.PixelVisible(lightpos, 16, self.PixVis) + local visdot = visibile * viewdot - render.SetMaterial(light) + render.SetMaterial(light) - local color = self:GetColor() - color.a = math.Clamp((1000 - math.Clamp(distance, 32, 800)) * visdot, 0, 100) + local color = self:GetColor() + color.a = math.Clamp((1000 - math.Clamp(distance, 32, 800)) * visdot, 0, 100) - local size = math.Clamp(distance * visdot * (light_info.Scale or 2), 64, 512) - render.DrawSprite(lightpos, size, size, color) + local size = math.Clamp(distance * visdot * (light_info.Scale or 2), 64, 512) + render.DrawSprite(lightpos, size, size, color) - color.r, color.g, color.b = 255, 255, 255 - render.DrawSprite(lightpos, size * 0.4, size * 0.4, color) - end - - function ENT:DrawTranslucent(flags) - BaseClass.DrawTranslucent(self, flags) - self:DrawEffects() + color.r, color.g, color.b = 255, 255, 255 + render.DrawSprite(lightpos, size * 0.4, size * 0.4, color) + end end -end -function ENT:Switch(on) - if on == IsValid(self.flashlight) then return end + function ENT:OnVarChanged(name, old, new) + local flashlight = self.Flashlight + if not flashlight then return end + + if name == "FOV" then + flashlight:SetFOV(game.SinglePlayer() and new or math.Clamp(new, 0, 170)) + elseif name == "Distance" then + flashlight:SetFarZ(game.SinglePlayer() and new or math.Clamp(new, 64, 2048)) + elseif name == "Brightness" then + flashlight:SetBrightness(game.SinglePlayer() and new or math.Clamp(new, 0, 8)) + elseif name == "Texture" then + flashlight:SetTexture(new) + end - self.on = on - self:SetOn(on) + self.LastLampMatrix = nil + self.LastLampColor = nil + end - if not on then - SafeRemoveEntity(self.flashlight) - self.flashlight = nil + function ENT:Think() + if not self:GetOn() then + self:OnRemove() - return - end + return + end - local flashlight = ents.Create("env_projectedtexture") - self.flashlight = flashlight - flashlight:SetParent(self) + if not self.Flashlight then + local light_info = self:GetLightInfo() + local flashlight = ProjectedTexture() + local singleplayer = game.SinglePlayer() - local singleplayer = game.SinglePlayer() - local light_info = self:GetLightInfo() - local offset = (light_info.Offset or vector_offset) * -1 - offset.x = offset.x + 5 + flashlight:SetNearZ(light_info.NearZ or 12) + flashlight:SetFarZ(singleplayer and self:GetDistance() or math.Clamp(self:GetDistance(), 64, 2048)) + flashlight:SetFOV(singleplayer and self:GetFOV() or math.Clamp(self:GetFOV(), 0, 170)) + flashlight:SetBrightness(singleplayer and self:GetBrightness() or math.Clamp(self:GetBrightness(), 0, 8)) + flashlight:SetTexture(self:GetTexture()) - flashlight:SetLocalPos(-offset) - flashlight:SetLocalAngles(light_info.Angle or angle_zero) - flashlight:SetKeyValue("enableshadows", 1) - flashlight:SetKeyValue("nearz", light_info.NearZ or 12) - flashlight:SetKeyValue("farz", singleplayer and self.Dist or math.Clamp(self.Dist, 64, 2048)) - flashlight:SetKeyValue("lightfov", singleplayer and self.FOV or math.Clamp(self.FOV, 10, 170)) + self.Flashlight = flashlight + end - local color = self:GetColor() - local brightness = singleplayer and self.Brightness or math.Clamp(self.Brightness, 0, 8) - flashlight:SetKeyValue("lightcolor", Format("%i %i %i 255", color.r * brightness, color.g * brightness, color.b * brightness)) - flashlight:Spawn() + local matrix = self:GetWorldTransformMatrix() + local color = self:GetColor() - flashlight:Input("SpotlightTexture", NULL, NULL, self.Texture) -end + if self.LastLampMatrix ~= matrix or self.LastLampColor ~= color then + local flashlight = self.Flashlight + local light_info = self:GetLightInfo() + local lightpos = self:LocalToWorld(light_info.Offset or vector_offset) -function ENT:UpdateLight() - local color = Color(self.r, self.g, self.b, self:GetColor().a) - self:SetOverlayText(string.format("Red: %i Green: %i Blue: %i\nFOV: %i Distance: %i Brightness: %i", color.r, color.g, color.b, self.FOV, self.Dist, self.Brightness)) - self:SetColor(color) + flashlight:SetColor(color) + flashlight:SetPos(lightpos) + flashlight:SetAngles(self:LocalToWorldAngles(light_info.Angle or angle_zero)) + flashlight:Update() - local flashlight = self.flashlight - if not IsValid(flashlight) then return end + self.LastLampMatrix = matrix + self.LastLampColor = color + end + end - local singleplayer = game.SinglePlayer() - flashlight:Input("SpotlightTexture", NULL, NULL, self.Texture) - flashlight:Input("FOV", NULL, NULL, tostring(singleplayer and self.FOV or math.Clamp(self.FOV, 10, 170))) - flashlight:SetKeyValue("farz", singleplayer and self.Dist or math.Clamp(self.Dist, 64, 2048)) + function ENT:OnRemove() + if self.Flashlight then + self.Flashlight:Remove() + self.Flashlight = nil + self.LastLampMatrix = nil + self.LastLampColor = nil + end + end - local brightness = singleplayer and self.Brightness or math.Clamp(self.Brightness, 0, 8) - flashlight:SetKeyValue("lightcolor", Format("%i %i %i 255", color.r * brightness, color.g * brightness, color.b * brightness)) + return end function ENT:TriggerInput(name, value) - if name == "Red" then - self.r = math.Clamp(value, 0, 255) + local color = self:GetColor() + + if name == "On" then + self:SetOn(value ~= 0) + elseif name == "FOV" then + self:SetFOV(value) + elseif name == "Red" then + local color = self:GetColor() + color.r = value + self:SetColor(color) elseif name == "Green" then - self.g = math.Clamp(value, 0, 255) + local color = self:GetColor() + color.g = value + self:SetColor(color) elseif name == "Blue" then - self.b = math.Clamp(value, 0, 255) + local color = self:GetColor() + color.b = value + self:SetColor(color) elseif name == "RGB" then - self.r, self.g, self.b = math.Clamp(value.r, 0, 255), math.Clamp(value.g, 0, 255), math.Clamp(value.b, 0, 255) - elseif name == "FOV" then - self.FOV = value + local color = self:GetColor() + color.r = value.r + color.g = value.g + color.b = value.b + self:SetColor(color) elseif name == "Distance" then - self.Dist = value + self:SetDistance(value) elseif name == "Brightness" then - self.Brightness = value - elseif name == "On" then - self:Switch(value ~= 0) + self:SetBrightness(value) elseif name == "Texture" then if value ~= "" then - self.Texture = value + self:SetTexture(value) else - self.Texture = "effects/flashlight001" + self:SetTexture("effects/flashlight001") end end +end - self:UpdateLight() +function ENT:PrepareOverlayData() + local color = self:GetColor() + self:SetOverlayText(string.format("Red: %i Green: %i Blue: %i\nFOV: %i Distance: %i Brightness: %i", color.r, color.g, color.b, self:GetFOV(), self:GetDistance(), self:GetBrightness())) end function ENT:Setup(r, g, b, texture, fov, distance, brightness, on) - self.Texture = texture or "effects/flashlight001" - self.FOV = fov or 90 - self.Dist = distance or 1024 - self.Brightness = brightness or 8 - 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) - - self.on = on and true or false - self:Switch(self.on) - self:UpdateLight() + self:SetOn(on and true or false) + self:SetFOV(fov or 90) + self:SetDistance(distance or 1024) + self:SetBrightness(brightness or 8) + self:SetTexture(texture or "effects/flashlight001") + + local color = self:GetColor() + 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) + self:SetColor(color) end duplicator.RegisterEntityClass("gmod_wire_lamp", WireLib.MakeWireEnt, "Data", "r", "g", "b", "Texture", "FOV", "Dist", "Brightness", "on") diff --git a/lua/wire/stools/lamp.lua b/lua/wire/stools/lamp.lua index 1f5bdf394a..ca2afce540 100644 --- a/lua/wire/stools/lamp.lua +++ b/lua/wire/stools/lamp.lua @@ -18,7 +18,7 @@ WireToolSetup.SetupMax(10) if SERVER then function TOOL:GetConVars() - return self:GetClientNumber("r"), self:GetClientNumber("g"), self:GetClientNumber("b"), self:GetClientInfo("texture"), self:GetClientNumber("fov"), self:GetClientNumber("distance"), self:GetClientNumber("brightness") + return self:GetClientNumber("r"), self:GetClientNumber("g"), self:GetClientNumber("b"), self:GetClientInfo("texture"), self:GetClientNumber("fov"), self:GetClientNumber("distance"), self:GetClientNumber("brightness"), self:GetClientBool("on") end function TOOL:LeftClick_PostMake(ent, ply, trace) @@ -108,6 +108,7 @@ TOOL.ClientConVar["fov"] = 90 TOOL.ClientConVar["distance"] = 1024 TOOL.ClientConVar["brightness"] = 4 TOOL.ClientConVar["model"] = "models/lamps/torch.mdl" +TOOL.ClientConVar["on"] = 1 function TOOL:RightClick(trace) if CLIENT then return true end @@ -132,6 +133,7 @@ function TOOL.BuildCPanel(panel) WireToolHelpers.MakePresetControl(panel, "wire_lamp") WireDermaExts.ModelSelect(panel, "wire_lamp_model", list.Get("LampModels"), 1, true) + panel:CheckBox("Start On", "wire_lamp_on") panel:NumSlider("Rope Length:", "wire_lamp_ropelength", 4, 400, 0) panel:NumSlider("FOV:", "wire_lamp_fov", 10, 170, 2) panel:NumSlider("Distance:", "wire_lamp_distance", 64, 2048, 0)