From 08e309763d206d63378318e9fbc30f79bc657618 Mon Sep 17 00:00:00 2001 From: wav3 Date: Wed, 27 Aug 2025 22:23:08 +0200 Subject: [PATCH 01/10] intprop --- .../gmod_wire_characterlcd/cl_init.lua | 40 ++ lua/entities/gmod_wire_characterlcd/init.lua | 70 ++- .../gmod_wire_consolescreen/cl_init.lua | 41 ++ lua/entities/gmod_wire_consolescreen/init.lua | 424 ++++++++++-------- lua/entities/gmod_wire_interactiveprop.lua | 84 ++-- lua/wire/stools/interactiveprop.lua | 4 +- 6 files changed, 440 insertions(+), 223 deletions(-) diff --git a/lua/entities/gmod_wire_characterlcd/cl_init.lua b/lua/entities/gmod_wire_characterlcd/cl_init.lua index 90061c3720..e28f2ca533 100644 --- a/lua/entities/gmod_wire_characterlcd/cl_init.lua +++ b/lua/entities/gmod_wire_characterlcd/cl_init.lua @@ -1,5 +1,6 @@ include("shared.lua") + function ENT:Initialize() local mem = {} self.Memory = mem @@ -7,6 +8,18 @@ function ENT:Initialize() mem[i] = 0 end + self.InteractiveData = {} + self.LastButtons = {} + self.Buttons = {} + local interactive_model = WireLib.GetInteractiveModel(self:GetModel()) + self.IsInteractive = false + if interactive_model then + self.IsInteractive = true + for i=1, #WireLib.GetInteractiveModel(self:GetModel()).widgets do + self.InteractiveData[i] = 0 + end + end + -- Screen control: -- [1003] - Background red -- [1004] - Background green @@ -74,10 +87,37 @@ function ENT:Initialize() GPULib.ClientCacheCallback(self,function(Address,Value) self:WriteCell(Address,Value) end) + + WireLib.netRegister(self) end +local panel + +function ENT:SendData() + net.Start("wire_interactiveprop_action") + + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + net.WriteEntity(self) + for i=1, #data do + net.WriteFloat(self.InteractiveData[i]) + end + net.SendToServer() +end + +function ENT:GetPanel() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()) + return WireLib.GetInteractiveWidgetBody(self, data) +end + + +function ENT:AddButton(id,button) + if not self.IsInteractive then return end + self.Buttons[id] = button +end + function ENT:OnRemove() self.GPU:Finalize() end diff --git a/lua/entities/gmod_wire_characterlcd/init.lua b/lua/entities/gmod_wire_characterlcd/init.lua index 6f5261409f..e1f929a335 100644 --- a/lua/entities/gmod_wire_characterlcd/init.lua +++ b/lua/entities/gmod_wire_characterlcd/init.lua @@ -1,16 +1,36 @@ -AddCSLuaFile("cl_init.lua") +AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") include("shared.lua") ENT.WireDebugName = "CharacterLcdScreen" +function ENT:InitInteractive() + local model = self:GetModel() + local outputs = {"Memory"} + local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + for i=1, #interactivemodel.widgets do + outputs[i+1] = interactivemodel.widgets[i].name + end + self.BlockInput = false + self.NextPrompt = 0 + self.Outputs=WireLib.CreateOutputs(self,outputs) + self.IsInteractive = true +end + function ENT:Initialize() self:PhysicsInit(SOLID_VPHYSICS) self:SetMoveType(MOVETYPE_VPHYSICS) self:SetSolid(SOLID_VPHYSICS) self.Inputs = WireLib.CreateInputs(self, { "CharAddress", "Char (ASCII/Unicode)", "Contrast", "Clk", "Reset" }) - self.Outputs = WireLib.CreateOutputs(self, { "Memory" }) + + self.InteractiveData = {} + self.IsInteractive = false + if WireLib.IsValidInteractiveModel(self:GetModel()) then + self:InitInteractive() + else + self.Outputs = WireLib.CreateOutputs(self, { "Memory" }) + end self.Memory = {} @@ -179,4 +199,50 @@ function ENT:ClientWriteCell(Address, value) end end + + +function ENT:ReceiveData() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + for i = 1, #data do + WireLib.TriggerOutput(self, data[i].name, net.ReadFloat()) + end +end + +function ENT:UpdateOverlay() -- required by interactiveprop functions + +end + + +function ENT:Prompt( ply ) + if not self.IsInteractive then return end + if ply then + if CurTime() < self.NextPrompt then return end -- anti spam + self.NextPrompt = CurTime() + 0.1 + + if IsValid( self.User ) then + WireLib.AddNotify(ply,"That interactive prop is in use by another player!",NOTIFY_ERROR,5,6) + return + end + + self.User = ply + + net.Start( "wire_interactiveprop_show" ) + net.WriteEntity( self ) + net.Send( ply ) + else + self:Prompt( self:GetPlayer() ) -- prompt for owner + end +end + +function ENT:Use(ply) + if not IsValid( ply ) then return end + self:Prompt( ply ) +end + +function ENT:Unprompt() + if not self.IsInteractive then return end + self.User = nil +end + duplicator.RegisterEntityClass("gmod_wire_characterlcd", WireLib.MakeWireEnt, "Data", "ScreenWidth", "ScreenHeight") diff --git a/lua/entities/gmod_wire_consolescreen/cl_init.lua b/lua/entities/gmod_wire_consolescreen/cl_init.lua index 5b1222f146..7de763341b 100644 --- a/lua/entities/gmod_wire_consolescreen/cl_init.lua +++ b/lua/entities/gmod_wire_consolescreen/cl_init.lua @@ -1,11 +1,25 @@ include("shared.lua") + + function ENT:Initialize() self.Memory1 = {} self.Memory2 = {} for i = 0, 2047 do self.Memory1[i] = 0 end + + self.InteractiveData = {} + self.LastButtons = {} + self.Buttons = {} + local interactive_model = WireLib.GetInteractiveModel(self:GetModel()) + self.IsInteractive = false + if interactive_model then + self.IsInteractive = true + for i=1, #WireLib.GetInteractiveModel(self:GetModel()).widgets do + self.InteractiveData[i] = 0 + end + end -- Caching control: -- [2020] - Force cache refresh @@ -694,3 +708,30 @@ end function ENT:IsTranslucent() return true end + + + +local panel + +function ENT:SendData() + net.Start("wire_interactiveprop_action") + + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + net.WriteEntity(self) + for i=1, #data do + net.WriteFloat(self.InteractiveData[i]) + end + net.SendToServer() +end + +function ENT:GetPanel() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()) + return WireLib.GetInteractiveWidgetBody(self, data) +end + + +function ENT:AddButton(id,button) + if not self.IsInteractive then return end + self.Buttons[id] = button +end \ No newline at end of file diff --git a/lua/entities/gmod_wire_consolescreen/init.lua b/lua/entities/gmod_wire_consolescreen/init.lua index f9eb661953..ce0f0d1502 100644 --- a/lua/entities/gmod_wire_consolescreen/init.lua +++ b/lua/entities/gmod_wire_consolescreen/init.lua @@ -4,95 +4,159 @@ include('shared.lua') ENT.WireDebugName = "ConsoleScreen" +function ENT:InitInteractive() + local model = self:GetModel() + local outputs = {"Memory"} + local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + for i=1, #interactivemodel.widgets do + outputs[i+1] = interactivemodel.widgets[i].name + end + self.BlockInput = false + self.NextPrompt = 0 + self.Outputs=WireLib.CreateOutputs(self,outputs) + self.IsInteractive = true +end + + +function ENT:ReceiveData() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + for i = 1, #data do + WireLib.TriggerOutput(self, data[i].name, net.ReadFloat()) + end +end + +function ENT:UpdateOverlay() -- required by interactiveprop functions + +end + + +function ENT:Prompt( ply ) + if not self.IsInteractive then return end + if ply then + if CurTime() < self.NextPrompt then return end -- anti spam + self.NextPrompt = CurTime() + 0.1 + + if IsValid( self.User ) then + WireLib.AddNotify(ply,"That interactive prop is in use by another player!",NOTIFY_ERROR,5,6) + return + end + + self.User = ply + + net.Start( "wire_interactiveprop_show" ) + net.WriteEntity( self ) + net.Send( ply ) + else + self:Prompt( self:GetPlayer() ) -- prompt for owner + end +end + +function ENT:Use(ply) + if not IsValid( ply ) then return end + self:Prompt( ply ) +end + +function ENT:Unprompt() + if not self.IsInteractive then return end + self.User = nil +end + + function ENT:Initialize() - self:PhysicsInit(SOLID_VPHYSICS) - self:SetMoveType(MOVETYPE_VPHYSICS) - self:SetSolid(SOLID_VPHYSICS) - - self.Inputs = WireLib.CreateInputs(self, { "CharX", "CharY", "Char (ASCII/Unicode)", "CharParam (RGBrgb; White=999)", "Clk", "Reset" }) - self.Outputs = WireLib.CreateOutputs(self, { "Memory" }) - - self.Memory = {} - - for i = 0, 2047 do - self.Memory[i] = 0 - end - - self.CharX = 0 - self.CharY = 0 - self.Char = 0 - self.CharParam = 0 - - self.Memory[2020] = 0 - self.Memory[2021] = 0 - - self.Memory[2022] = 3/4 - self.Memory[2023] = 0 - self.Memory[2024] = 0 - self.Memory[2025] = 1 - self.Memory[2026] = 1 - self.Memory[2027] = 1 - self.Memory[2028] = 1 - self.Memory[2029] = 1 - self.Memory[2030] = 1 - self.Memory[2031] = 0 - self.Memory[2032] = 29 - self.Memory[2033] = 0 - self.Memory[2034] = 17 - self.Memory[2035] = 0 - self.Memory[2036] = 0 - - self.Memory[2042] = 000 - self.Memory[2043] = 0.5 - self.Memory[2044] = 0.25 - self.Memory[2045] = 0 - self.Memory[2046] = 0 - self.Memory[2047] = 1 -- CLK - - self.Cache = GPUCacheManager(self,true) + self:PhysicsInit(SOLID_VPHYSICS) + self:SetMoveType(MOVETYPE_VPHYSICS) + self:SetSolid(SOLID_VPHYSICS) + + self.Inputs = WireLib.CreateInputs(self, { "CharX", "CharY", "Char (ASCII/Unicode)", "CharParam (RGBrgb; White=999)", "Clk", "Reset" }) + if WireLib.IsValidInteractiveModel(self:GetModel()) then + self:InitInteractive() + else + self.Outputs = WireLib.CreateOutputs(self, { "Memory" }) + end + + + self.Memory = {} + + for i = 0, 2047 do + self.Memory[i] = 0 + end + + self.CharX = 0 + self.CharY = 0 + self.Char = 0 + self.CharParam = 0 + + self.Memory[2020] = 0 + self.Memory[2021] = 0 + + self.Memory[2022] = 3/4 + self.Memory[2023] = 0 + self.Memory[2024] = 0 + self.Memory[2025] = 1 + self.Memory[2026] = 1 + self.Memory[2027] = 1 + self.Memory[2028] = 1 + self.Memory[2029] = 1 + self.Memory[2030] = 1 + self.Memory[2031] = 0 + self.Memory[2032] = 29 + self.Memory[2033] = 0 + self.Memory[2034] = 17 + self.Memory[2035] = 0 + self.Memory[2036] = 0 + + self.Memory[2042] = 000 + self.Memory[2043] = 0.5 + self.Memory[2044] = 0.25 + self.Memory[2045] = 0 + self.Memory[2046] = 0 + self.Memory[2047] = 1 -- CLK + + self.Cache = GPUCacheManager(self,true) end function ENT:SendPixel() - if (self.Memory[2047] ~= 0) and (self.CharX >= 0) and (self.CharX < 30) and - (self.CharY >= 0) and (self.CharY < 18) then - local pixelno = math.floor(self.CharY)*30+math.floor(self.CharX) + if (self.Memory[2047] ~= 0) and (self.CharX >= 0) and (self.CharX < 30) and + (self.CharY >= 0) and (self.CharY < 18) then + local pixelno = math.floor(self.CharY)*30+math.floor(self.CharX) - self:WriteCell(pixelno*2, self.Char) - self:WriteCell(pixelno*2+1, self.CharParam) - end + self:WriteCell(pixelno*2, self.Char) + self:WriteCell(pixelno*2+1, self.CharParam) + end end function ENT:ReadCell(Address) - Address = math.floor(Address) - if Address < 0 then return nil end - if Address >= 2048 then return nil end - if Address == 2022 then return WireGPU_Monitors[self:GetModel()].RatioX end + Address = math.floor(Address) + if Address < 0 then return nil end + if Address >= 2048 then return nil end + if Address == 2022 then return WireGPU_Monitors[self:GetModel()].RatioX end - return self.Memory[Address] + return self.Memory[Address] end function ENT:WriteCell(Address, value) - Address = math.floor(Address) - if Address < 0 then return false end - if Address >= 2048 then return false end - if Address < 2000 then -- text/attribute data - if self.Memory[Address] == value then return true end - else --- self.Memory[Address] = value - self:ClientWriteCell(Address, value) --- self.Cache:WriteNow(Address, value) --- return true - end - - self.Memory[Address] = value - self.Cache:Write(Address,value) - return true + Address = math.floor(Address) + if Address < 0 then return false end + if Address >= 2048 then return false end + if Address < 2000 then -- text/attribute data + if self.Memory[Address] == value then return true end + else +-- self.Memory[Address] = value + self:ClientWriteCell(Address, value) +-- self.Cache:WriteNow(Address, value) +-- return true + end + + self.Memory[Address] = value + self.Cache:Write(Address,value) + return true end function ENT:Think() - self.Cache:Flush() - self:NextThink(CurTime()+0.1) - return true + self.Cache:Flush() + self:NextThink(CurTime()+0.1) + return true end function ENT:Retransmit(ply) @@ -104,115 +168,115 @@ function ENT:Retransmit(ply) end function ENT:TriggerInput(iname, value) - if iname == "CharX" then - self.CharX = value - self:SendPixel() - elseif iname == "CharY" then - self.CharY = value - self:SendPixel() - elseif iname == "Char" then - self.Char = value - self:SendPixel() - elseif iname == "CharParam" then - self.CharParam = value - self:SendPixel() - elseif iname == "Clk" then - self:WriteCell(2047, value) - self:SendPixel() - elseif iname == "Reset" then - self:WriteCell(2041,0) - self:WriteCell(2046,0) - self:WriteCell(2042,0) - end + if iname == "CharX" then + self.CharX = value + self:SendPixel() + elseif iname == "CharY" then + self.CharY = value + self:SendPixel() + elseif iname == "Char" then + self.Char = value + self:SendPixel() + elseif iname == "CharParam" then + self.CharParam = value + self:SendPixel() + elseif iname == "Clk" then + self:WriteCell(2047, value) + self:SendPixel() + elseif iname == "Reset" then + self:WriteCell(2041,0) + self:WriteCell(2046,0) + self:WriteCell(2042,0) + end end function ENT:ClientWriteCell(Address, value) - if Address == 2019 then -- Hardware Clear Viewport - local low = math.floor(math.Clamp(self.Memory[2033],0,17)) - local high = math.floor(math.Clamp(self.Memory[2034],0,17)) - local lowc = math.floor(math.Clamp(self.Memory[2031],0,29)) - local highc = math.floor(math.Clamp(self.Memory[2032],0,29)) - for j = low, high do - for i = 2*lowc, 2*highc+1 do - self.Memory[i*60+value] = 0 - end - end - elseif Address == 2037 then -- Shift cells (number of cells, >0 right, <0 left) - local delta = math.floor(math.Clamp(math.abs(value),-30,30)) - local low = math.floor(math.Clamp(self.Memory[2033],0,17)) - local high = math.floor(math.Clamp(self.Memory[2034],0,17)) - local lowc = math.floor(math.Clamp(self.Memory[2031],0,29)) - local highc = math.floor(math.Clamp(self.Memory[2032],0,29)) - if value > 0 then - for j = low,high do - for i = highc,lowc+delta,-1 do - self.Memory[j*60+i*2] = self.Memory[j*60+i*2-delta*2] - self.Memory[j*60+i*2+1] = self.Memory[j*60+i*2+1-delta*2] - end - end - for j = low,high do - for i = lowc, lowc+delta-1 do - self.Memory[j*60+i*2] = 0 - self.Memory[j*60+i*2+1] = 0 - end - end - else - for j = low,high do - for i = lowc,highc-delta do - self.Memory[j*60+i*2] = self.Memory[j*60+i*2+delta*2] - self.Memory[j*60+i*2+1] = self.Memory[j*60+i*2+1+delta*2] - end - end - for j = low,high do - for i = highc-delta+1,highc do - self.Memory[j*60+i*2] = 0 - self.Memory[j*60+i*2+1] = 0 - end - end - end - elseif Address == 2038 then -- Shift rows (number of rows, >0 shift down, <0 shift up) - local delta = math.floor(math.Clamp(math.abs(value),-30,30)) - local low = math.floor(math.Clamp(self.Memory[2033],0,17)) - local high = math.floor(math.Clamp(self.Memory[2034],0,17)) - local lowc = math.floor(math.Clamp(self.Memory[2031],0,29)) - local highc = math.floor(math.Clamp(self.Memory[2032],0,29)) - if value > 0 then - for j = low, high-delta do - for i = 2*lowc, 2*highc+1 do - self.Memory[j*60+i] = self.Memory[(j+delta)*60+i] - end - end - for j = high-delta+1,high do - for i = 2*lowc, 2*highc+1 do - self.Memory[j*60+i] = 0 - end - end - else - for j = high,low+delta,-1 do - for i = 2*lowc, 2*highc+1 do - self.Memory[j*60+i] = self.Memory[(j-delta)*60+i] - end - end - for j = low,low+delta-1 do - for i = 2*lowc, 2*highc+1 do - self.Memory[j*60+i] = 0 - end - end - end - elseif Address == 2039 then -- Hardware Clear Row (Writing clears row) - for i = 0, 59 do - self.Memory[value*60+i] = 0 - end - elseif Address == 2040 then -- Hardware Clear Column (Writing clears column) - for i = 0, 17 do - self.Memory[i*60+value] = 0 - end - elseif Address == 2041 then -- Hardware Clear Screen - for i = 0, 18*30*2-1 do - self.Memory[i] = 0 - end - self.Cache:Reset() - end + if Address == 2019 then -- Hardware Clear Viewport + local low = math.floor(math.Clamp(self.Memory[2033],0,17)) + local high = math.floor(math.Clamp(self.Memory[2034],0,17)) + local lowc = math.floor(math.Clamp(self.Memory[2031],0,29)) + local highc = math.floor(math.Clamp(self.Memory[2032],0,29)) + for j = low, high do + for i = 2*lowc, 2*highc+1 do + self.Memory[i*60+value] = 0 + end + end + elseif Address == 2037 then -- Shift cells (number of cells, >0 right, <0 left) + local delta = math.floor(math.Clamp(math.abs(value),-30,30)) + local low = math.floor(math.Clamp(self.Memory[2033],0,17)) + local high = math.floor(math.Clamp(self.Memory[2034],0,17)) + local lowc = math.floor(math.Clamp(self.Memory[2031],0,29)) + local highc = math.floor(math.Clamp(self.Memory[2032],0,29)) + if value > 0 then + for j = low,high do + for i = highc,lowc+delta,-1 do + self.Memory[j*60+i*2] = self.Memory[j*60+i*2-delta*2] + self.Memory[j*60+i*2+1] = self.Memory[j*60+i*2+1-delta*2] + end + end + for j = low,high do + for i = lowc, lowc+delta-1 do + self.Memory[j*60+i*2] = 0 + self.Memory[j*60+i*2+1] = 0 + end + end + else + for j = low,high do + for i = lowc,highc-delta do + self.Memory[j*60+i*2] = self.Memory[j*60+i*2+delta*2] + self.Memory[j*60+i*2+1] = self.Memory[j*60+i*2+1+delta*2] + end + end + for j = low,high do + for i = highc-delta+1,highc do + self.Memory[j*60+i*2] = 0 + self.Memory[j*60+i*2+1] = 0 + end + end + end + elseif Address == 2038 then -- Shift rows (number of rows, >0 shift down, <0 shift up) + local delta = math.floor(math.Clamp(math.abs(value),-30,30)) + local low = math.floor(math.Clamp(self.Memory[2033],0,17)) + local high = math.floor(math.Clamp(self.Memory[2034],0,17)) + local lowc = math.floor(math.Clamp(self.Memory[2031],0,29)) + local highc = math.floor(math.Clamp(self.Memory[2032],0,29)) + if value > 0 then + for j = low, high-delta do + for i = 2*lowc, 2*highc+1 do + self.Memory[j*60+i] = self.Memory[(j+delta)*60+i] + end + end + for j = high-delta+1,high do + for i = 2*lowc, 2*highc+1 do + self.Memory[j*60+i] = 0 + end + end + else + for j = high,low+delta,-1 do + for i = 2*lowc, 2*highc+1 do + self.Memory[j*60+i] = self.Memory[(j-delta)*60+i] + end + end + for j = low,low+delta-1 do + for i = 2*lowc, 2*highc+1 do + self.Memory[j*60+i] = 0 + end + end + end + elseif Address == 2039 then -- Hardware Clear Row (Writing clears row) + for i = 0, 59 do + self.Memory[value*60+i] = 0 + end + elseif Address == 2040 then -- Hardware Clear Column (Writing clears column) + for i = 0, 17 do + self.Memory[i*60+value] = 0 + end + elseif Address == 2041 then -- Hardware Clear Screen + for i = 0, 18*30*2-1 do + self.Memory[i] = 0 + end + self.Cache:Reset() + end end duplicator.RegisterEntityClass("gmod_wire_consolescreen", WireLib.MakeWireEnt, "Data") diff --git a/lua/entities/gmod_wire_interactiveprop.lua b/lua/entities/gmod_wire_interactiveprop.lua index 749c56bc94..2210df6f47 100644 --- a/lua/entities/gmod_wire_interactiveprop.lua +++ b/lua/entities/gmod_wire_interactiveprop.lua @@ -203,11 +203,38 @@ function WireLib.IsValidInteractiveModel( model ) return InteractiveModels[model] ~= nil end +function WireLib.GetInteractiveModel( model ) + return InteractiveModels[model] +end + +function WireLib.GetInteractiveWidgetBody( ent, data ) + local body = vgui.Create("DFrame") + body:SetTitle(data.title) + body:SetSize(data.width, data.height) + body:SetVisible(true) + body.Paint = function( self, w, h ) -- 'function Frame:Paint( w, h )' works too + -- surface.SetDrawColor(255,255,255) + -- surface.DrawOutlinedRect(0, 0, w, h) + -- surface.SetDrawColor(0,0,0) + -- surface.DrawOutlinedRect(1, 1, w-2, h-2) + draw.RoundedBox( 4, 0, 0, w, h, Color( 255, 255, 255 ) ) + draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 64, 64, 64 ) ) + end + body:SetDraggable(false) + body:Center() + body:ShowCloseButton(true) + body:MakePopup() + for id, widget in ipairs( data.widgets ) do + WidgetBuilders[widget.type](ent, widget, body, id) + end + return body +end + InteractiveModels["models/props_c17/furnituresink001a.mdl"] = copyPropUI( "models/props_interiors/bathtub01a.mdl", "Furniture Sink" ) InteractiveModels["models/props_interiors/sinkkitchen01a.mdl"] = copyPropUI( "models/props_interiors/bathtub01a.mdl", "Kitchen Sink" ) InteractiveModels["models/props_wasteland/prison_sink001a.mdl"] = copyPropUI( "models/props_interiors/bathtub01a.mdl", "Prison Sink" ) -local WidgetBuilders = { +WidgetBuilders = { DCheckBox = function(self, data, body, index) local checkbox = vgui.Create("DCheckBox", body) @@ -252,6 +279,14 @@ local WidgetBuilders = { button:SetPos(data.x, data.y) button:SetText(data.text or "") button:SetSize(data.width or 20, data.height or 20) + button.OnDepressed = function(scratch) + self.InteractiveData[index] = 1 + self:SendData() + end + button.OnReleased = function(scratch) + self.InteractiveData[index] = 0 + self:SendData() + end self:AddButton(index,button) end @@ -259,26 +294,7 @@ local WidgetBuilders = { function ENT:GetPanel() local data = InteractiveModels[ self:GetModel() ] - local body = vgui.Create("DFrame") - body:SetTitle(data.title) - body:SetSize(data.width, data.height) - body:SetVisible(true) - body.Paint = function( self, w, h ) -- 'function Frame:Paint( w, h )' works too - -- surface.SetDrawColor(255,255,255) - -- surface.DrawOutlinedRect(0, 0, w, h) - -- surface.SetDrawColor(0,0,0) - -- surface.DrawOutlinedRect(1, 1, w-2, h-2) - draw.RoundedBox( 4, 0, 0, w, h, Color( 255, 255, 255 ) ) - draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 64, 64, 64 ) ) - end - body:SetDraggable(false) - body:Center() - body:ShowCloseButton(true) - body:MakePopup() - for id, widget in ipairs( data.widgets ) do - WidgetBuilders[widget.type](self, widget, body, id) - end - return body + return WireLib.GetInteractiveWidgetBody(self, data) end @@ -312,22 +328,6 @@ if CLIENT then end end - function ENT:Think() - if IsValid( panel ) and #self.Buttons ~= 0 then - local needToUpdate = false - for k,v in pairs(self.Buttons) do - self.LastButtons[k] = self.InteractiveData[k] - self.InteractiveData[k] = v:IsDown() and 1 or 0 - if self.InteractiveData[k] ~= self.LastButtons[k] then - needToUpdate = true - end - end - if needToUpdate then - self:SendData() - end - end - end - net.Receive("wire_interactiveprop_show",function() local self = net.ReadEntity() if not IsValid(self) then return end @@ -419,7 +419,10 @@ end util.AddNetworkString("wire_interactiveprop_action") net.Receive("wire_interactiveprop_action",function(len,ply) local ent = net.ReadEntity() - if not ent:IsValid() or ent:GetClass() ~= "gmod_wire_interactiveprop" or ply ~= ent.User then return end + if not ent:IsValid() or (ent:GetClass() ~= "gmod_wire_interactiveprop" and + ent:GetClass() ~= "gmod_wire_characterlcd" and + ent:GetClass() ~= "gmod_wire_consolescreen" + ) or ply ~= ent.User then return end ent:ReceiveData() ent:UpdateOverlay() @@ -455,7 +458,10 @@ end util.AddNetworkString("wire_interactiveprop_close") net.Receive("wire_interactiveprop_close",function(len,ply) local ent = net.ReadEntity() - if not ent:IsValid() or ent:GetClass() ~= "gmod_wire_interactiveprop" or ply ~= ent.User then return end + if not ent:IsValid() or (ent:GetClass() ~= "gmod_wire_interactiveprop" and + ent:GetClass() ~= "gmod_wire_characterlcd" and + ent:GetClass() ~= "gmod_wire_consolescreen" + ) or ply ~= ent.User then return end ent:Unprompt() end) diff --git a/lua/wire/stools/interactiveprop.lua b/lua/wire/stools/interactiveprop.lua index 6d5815bd6c..44ea69b21f 100644 --- a/lua/wire/stools/interactiveprop.lua +++ b/lua/wire/stools/interactiveprop.lua @@ -16,8 +16,8 @@ TOOL.ClientConVar = { if SERVER then function TOOL:GetDataTables() - return {} - end + return {} + end end WireToolSetup.BaseLang() From 579e40761d0496f37e85b7615b59b0785f90748f Mon Sep 17 00:00:00 2001 From: wav3 Date: Wed, 27 Aug 2025 22:30:14 +0200 Subject: [PATCH 02/10] digi --- .../gmod_wire_consolescreen/cl_init.lua | 47 +++++++------- .../gmod_wire_digitalscreen/cl_init.lua | 37 +++++++++++ lua/entities/gmod_wire_digitalscreen/init.lua | 65 ++++++++++++++++++- lua/entities/gmod_wire_interactiveprop.lua | 16 ++++- 4 files changed, 138 insertions(+), 27 deletions(-) diff --git a/lua/entities/gmod_wire_consolescreen/cl_init.lua b/lua/entities/gmod_wire_consolescreen/cl_init.lua index 7de763341b..5ccb5a1477 100644 --- a/lua/entities/gmod_wire_consolescreen/cl_init.lua +++ b/lua/entities/gmod_wire_consolescreen/cl_init.lua @@ -1,6 +1,29 @@ include("shared.lua") +local panel + +function ENT:SendData() + net.Start("wire_interactiveprop_action") + + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + net.WriteEntity(self) + for i=1, #data do + net.WriteFloat(self.InteractiveData[i]) + end + net.SendToServer() +end +function ENT:GetPanel() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()) + return WireLib.GetInteractiveWidgetBody(self, data) +end + + +function ENT:AddButton(id,button) + if not self.IsInteractive then return end + self.Buttons[id] = button +end function ENT:Initialize() self.Memory1 = {} @@ -711,27 +734,3 @@ end -local panel - -function ENT:SendData() - net.Start("wire_interactiveprop_action") - - local data = WireLib.GetInteractiveModel(self:GetModel()).widgets - net.WriteEntity(self) - for i=1, #data do - net.WriteFloat(self.InteractiveData[i]) - end - net.SendToServer() -end - -function ENT:GetPanel() - if not self.IsInteractive then return end - local data = WireLib.GetInteractiveModel(self:GetModel()) - return WireLib.GetInteractiveWidgetBody(self, data) -end - - -function ENT:AddButton(id,button) - if not self.IsInteractive then return end - self.Buttons[id] = button -end \ No newline at end of file diff --git a/lua/entities/gmod_wire_digitalscreen/cl_init.lua b/lua/entities/gmod_wire_digitalscreen/cl_init.lua index 2295fdf215..b14c1bd788 100644 --- a/lua/entities/gmod_wire_digitalscreen/cl_init.lua +++ b/lua/entities/gmod_wire_digitalscreen/cl_init.lua @@ -1,9 +1,46 @@ include('shared.lua') +local panel + +function ENT:SendData() + net.Start("wire_interactiveprop_action") + + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + net.WriteEntity(self) + for i=1, #data do + net.WriteFloat(self.InteractiveData[i]) + end + net.SendToServer() +end + +function ENT:GetPanel() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()) + return WireLib.GetInteractiveWidgetBody(self, data) +end + + +function ENT:AddButton(id,button) + if not self.IsInteractive then return end + self.Buttons[id] = button +end + function ENT:Initialize() self.Memory1 = {} self.Memory2 = {} + self.InteractiveData = {} + self.LastButtons = {} + self.Buttons = {} + local interactive_model = WireLib.GetInteractiveModel(self:GetModel()) + self.IsInteractive = false + if interactive_model then + self.IsInteractive = true + for i=1, #WireLib.GetInteractiveModel(self:GetModel()).widgets do + self.InteractiveData[i] = 0 + end + end + self.LastClk = true self.NewClk = true self.Memory1[1048575] = 1 diff --git a/lua/entities/gmod_wire_digitalscreen/init.lua b/lua/entities/gmod_wire_digitalscreen/init.lua index 3fc448cbd4..f882e00956 100644 --- a/lua/entities/gmod_wire_digitalscreen/init.lua +++ b/lua/entities/gmod_wire_digitalscreen/init.lua @@ -5,6 +5,65 @@ DEFINE_BASECLASS( "base_wire_entity" ) ENT.WireDebugName = "DigitalScreen" + +function ENT:InitInteractive() + local model = self:GetModel() + local outputs = {"Memory"} + local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + for i=1, #interactivemodel.widgets do + outputs[i+1] = interactivemodel.widgets[i].name + end + self.BlockInput = false + self.NextPrompt = 0 + self.Outputs=WireLib.CreateOutputs(self,outputs) + self.IsInteractive = true +end + + +function ENT:ReceiveData() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + for i = 1, #data do + WireLib.TriggerOutput(self, data[i].name, net.ReadFloat()) + end +end + +function ENT:UpdateOverlay() -- required by interactiveprop functions + +end + + +function ENT:Prompt( ply ) + if not self.IsInteractive then return end + if ply then + if CurTime() < self.NextPrompt then return end -- anti spam + self.NextPrompt = CurTime() + 0.1 + + if IsValid( self.User ) then + WireLib.AddNotify(ply,"That interactive prop is in use by another player!",NOTIFY_ERROR,5,6) + return + end + + self.User = ply + + net.Start( "wire_interactiveprop_show" ) + net.WriteEntity( self ) + net.Send( ply ) + else + self:Prompt( self:GetPlayer() ) -- prompt for owner + end +end + +function ENT:Use(ply) + if not IsValid( ply ) then return end + self:Prompt( ply ) +end + +function ENT:Unprompt() + if not self.IsInteractive then return end + self.User = nil +end + function ENT:Initialize() self:PhysicsInit(SOLID_VPHYSICS) @@ -12,7 +71,11 @@ function ENT:Initialize() self:SetSolid(SOLID_VPHYSICS) self.Inputs = Wire_CreateInputs(self, { "PixelX", "PixelY", "PixelG", "Clk", "FillColor", "ClearRow", "ClearCol" }) - self.Outputs = Wire_CreateOutputs(self, { "Memory" }) + if WireLib.IsValidInteractiveModel(self:GetModel()) then + self:InitInteractive() + else + self.Outputs = WireLib.CreateOutputs(self, { "Memory" }) + end self.Memory = {} diff --git a/lua/entities/gmod_wire_interactiveprop.lua b/lua/entities/gmod_wire_interactiveprop.lua index 2210df6f47..4c8b4a3653 100644 --- a/lua/entities/gmod_wire_interactiveprop.lua +++ b/lua/entities/gmod_wire_interactiveprop.lua @@ -194,6 +194,16 @@ InteractiveModels = { {type="DButton", x=135, y=60, name="Button11"}, {type="DButton", x=160, y=60, name="Button12"}, } + }, + ["models/props_lab/monitor01b.mdl"] = { + width = 40, + height = 128, + title = "plotter", + widgets={ + {type="DNumberScratch", x = 10, y = 32, name="Knob1"}, + {type="DNumberScratch", x = 10, y = 64, name="Knob2"}, + {type="DNumberScratch", x = 10, y = 96, name="Knob3"}, + } } } @@ -421,7 +431,8 @@ net.Receive("wire_interactiveprop_action",function(len,ply) local ent = net.ReadEntity() if not ent:IsValid() or (ent:GetClass() ~= "gmod_wire_interactiveprop" and ent:GetClass() ~= "gmod_wire_characterlcd" and - ent:GetClass() ~= "gmod_wire_consolescreen" + ent:GetClass() ~= "gmod_wire_consolescreen" and + ent:GetClass() ~= "gmod_wire_digitalscreen" ) or ply ~= ent.User then return end ent:ReceiveData() @@ -460,7 +471,8 @@ net.Receive("wire_interactiveprop_close",function(len,ply) local ent = net.ReadEntity() if not ent:IsValid() or (ent:GetClass() ~= "gmod_wire_interactiveprop" and ent:GetClass() ~= "gmod_wire_characterlcd" and - ent:GetClass() ~= "gmod_wire_consolescreen" + ent:GetClass() ~= "gmod_wire_consolescreen" and + ent:GetClass() ~= "gmod_wire_digitalscreen" ) or ply ~= ent.User then return end ent:Unprompt() end) From 44049cd932d4a7890cfea7d710587005b04889e9 Mon Sep 17 00:00:00 2001 From: wav3 Date: Wed, 27 Aug 2025 22:44:25 +0200 Subject: [PATCH 03/10] add oscilloscope --- lua/entities/gmod_wire_interactiveprop.lua | 12 +-- lua/entities/gmod_wire_oscilloscope.lua | 103 +++++++++++++++++++++ lua/wire/stools/characterlcd.lua | 34 +++---- 3 files changed, 122 insertions(+), 27 deletions(-) diff --git a/lua/entities/gmod_wire_interactiveprop.lua b/lua/entities/gmod_wire_interactiveprop.lua index 4c8b4a3653..395e5ae217 100644 --- a/lua/entities/gmod_wire_interactiveprop.lua +++ b/lua/entities/gmod_wire_interactiveprop.lua @@ -429,11 +429,7 @@ end util.AddNetworkString("wire_interactiveprop_action") net.Receive("wire_interactiveprop_action",function(len,ply) local ent = net.ReadEntity() - if not ent:IsValid() or (ent:GetClass() ~= "gmod_wire_interactiveprop" and - ent:GetClass() ~= "gmod_wire_characterlcd" and - ent:GetClass() ~= "gmod_wire_consolescreen" and - ent:GetClass() ~= "gmod_wire_digitalscreen" - ) or ply ~= ent.User then return end + if not ent:IsValid() or ply ~= ent.User then return end ent:ReceiveData() ent:UpdateOverlay() @@ -469,11 +465,7 @@ end util.AddNetworkString("wire_interactiveprop_close") net.Receive("wire_interactiveprop_close",function(len,ply) local ent = net.ReadEntity() - if not ent:IsValid() or (ent:GetClass() ~= "gmod_wire_interactiveprop" and - ent:GetClass() ~= "gmod_wire_characterlcd" and - ent:GetClass() ~= "gmod_wire_consolescreen" and - ent:GetClass() ~= "gmod_wire_digitalscreen" - ) or ply ~= ent.User then return end + if not ent:IsValid() or ply ~= ent.User then return end ent:Unprompt() end) diff --git a/lua/entities/gmod_wire_oscilloscope.lua b/lua/entities/gmod_wire_oscilloscope.lua index ee44bf7d82..ae41a7ac86 100644 --- a/lua/entities/gmod_wire_oscilloscope.lua +++ b/lua/entities/gmod_wire_oscilloscope.lua @@ -4,8 +4,47 @@ ENT.PrintName = "Wire Oscilloscope" ENT.WireDebugName = "Oscilloscope" if CLIENT then + + local panel + + function ENT:SendData() + net.Start("wire_interactiveprop_action") + + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + net.WriteEntity(self) + for i=1, #data do + net.WriteFloat(self.InteractiveData[i]) + end + net.SendToServer() + end + + function ENT:GetPanel() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()) + return WireLib.GetInteractiveWidgetBody(self, data) + end + + + function ENT:AddButton(id,button) + if not self.IsInteractive then return end + self.Buttons[id] = button + end + function ENT:Initialize() self.GPU = WireGPU(self) + + + self.InteractiveData = {} + self.LastButtons = {} + self.Buttons = {} + local interactive_model = WireLib.GetInteractiveModel(self:GetModel()) + self.IsInteractive = false + if interactive_model then + self.IsInteractive = true + for i=1, #WireLib.GetInteractiveModel(self:GetModel()).widgets do + self.InteractiveData[i] = 0 + end + end self.Nodes = {} end @@ -109,12 +148,76 @@ function ENT:SetNextNode(x, y) net.SendPVS( self:GetPos() ) end + +function ENT:InitInteractive() + local model = self:GetModel() + local outputs = {} + local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + for i=1, #interactivemodel.widgets do + outputs[i+1] = interactivemodel.widgets[i].name + end + self.BlockInput = false + self.NextPrompt = 0 + self.Outputs=WireLib.CreateOutputs(self,outputs) + self.IsInteractive = true +end + + +function ENT:ReceiveData() + if not self.IsInteractive then return end + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets + for i = 1, #data do + WireLib.TriggerOutput(self, data[i].name, net.ReadFloat()) + end +end + +function ENT:UpdateOverlay() -- required by interactiveprop functions + +end + + +function ENT:Prompt( ply ) + if not self.IsInteractive then return end + if ply then + if CurTime() < self.NextPrompt then return end -- anti spam + self.NextPrompt = CurTime() + 0.1 + + if IsValid( self.User ) then + WireLib.AddNotify(ply,"That interactive prop is in use by another player!",NOTIFY_ERROR,5,6) + return + end + + self.User = ply + + net.Start( "wire_interactiveprop_show" ) + net.WriteEntity( self ) + net.Send( ply ) + else + self:Prompt( self:GetPlayer() ) -- prompt for owner + end +end + +function ENT:Use(ply) + if not IsValid( ply ) then return end + self:Prompt( ply ) +end + +function ENT:Unprompt() + if not self.IsInteractive then return end + self.User = nil +end + + function ENT:Initialize() self:PhysicsInit( SOLID_VPHYSICS ) self:SetMoveType( MOVETYPE_VPHYSICS ) self:SetSolid( SOLID_VPHYSICS ) self.Inputs = WireLib.CreateInputs(self, { "X", "Y", "R", "G", "B", "Pause", "Length", "Update Frequency" }) + + if WireLib.IsValidInteractiveModel(self:GetModel()) then + self:InitInteractive() + end end function ENT:Think() diff --git a/lua/wire/stools/characterlcd.lua b/lua/wire/stools/characterlcd.lua index f5d4c2b08f..cbb9565e61 100644 --- a/lua/wire/stools/characterlcd.lua +++ b/lua/wire/stools/characterlcd.lua @@ -4,8 +4,8 @@ WireToolSetup.open( "characterlcd", "Character LCD", "gmod_wire_characterlcd", n if CLIENT then language.Add( "tool.wire_characterlcd.name", "Character LCD Tool (Wire)" ) language.Add( "tool.wire_characterlcd.desc", "Spawns a Character LCD, which can be used to display text" ) - language.Add( "tool.wire_characterlcd.bgcolor", "Background color:" ) - language.Add( "tool.wire_characterlcd.fgcolor", "Text color:" ) + language.Add( "tool.wire_characterlcd.bgcolor", "Background color:" ) + language.Add( "tool.wire_characterlcd.fgcolor", "Text color:" ) TOOL.Information = { { name = "left", text = "Create/Update " .. TOOL.Name } } WireToolSetup.setToolMenuIcon("icon16/application_xp_terminal.png") @@ -16,33 +16,33 @@ WireToolSetup.SetupMax( 20 ) if SERVER then function TOOL:GetConVars() return self:GetClientInfo("width"), self:GetClientInfo("height"), - math.Clamp(self:GetClientNumber("bgred"), 0, 255), + math.Clamp(self:GetClientNumber("bgred"), 0, 255), math.Clamp(self:GetClientNumber("bggreen"), 0, 255), math.Clamp(self:GetClientNumber("bgblue"), 0, 255), - math.Clamp(self:GetClientNumber("fgred"), 0, 255), + math.Clamp(self:GetClientNumber("fgred"), 0, 255), math.Clamp(self:GetClientNumber("fggreen"), 0, 255), math.Clamp(self:GetClientNumber("fgblue"), 0, 255) end end TOOL.ClientConVar = { - model = "models/props_lab/monitor01b.mdl", - width = 16, - height = 2, - createflat = 0, - bgred = 148, - bggreen = 178, - bgblue = 15, - fgred = 45, - fggreen = 91, - fgblue = 45, + model = "models/props_lab/monitor01b.mdl", + width = 16, + height = 2, + createflat = 0, + bgred = 148, + bggreen = 178, + bgblue = 15, + fgred = 45, + fggreen = 91, + fgblue = 45, } function TOOL.BuildCPanel(panel) - WireToolHelpers.MakePresetControl(panel, "wire_characterlcd") + WireToolHelpers.MakePresetControl(panel, "wire_characterlcd") WireDermaExts.ModelSelect(panel, "wire_characterlcd_model", list.Get( "WireScreenModels" ), 5) - panel:AddControl("Color", { + panel:AddControl("Color", { Label = "#tool.wire_characterlcd.bgcolor", Red = "wire_characterlcd_bgred", Green = "wire_characterlcd_bggreen", @@ -52,7 +52,7 @@ function TOOL.BuildCPanel(panel) ShowRGB = "1", Multiplier = "255" }) - panel:AddControl("Color", { + panel:AddControl("Color", { Label = "#tool.wire_characterlcd.fgcolor", Red = "wire_characterlcd_fgred", Green = "wire_characterlcd_fggreen", From ca83be4bdc04f1749f812b20b0172af7aea88f78 Mon Sep 17 00:00:00 2001 From: wav3 Date: Wed, 27 Aug 2025 23:40:10 +0200 Subject: [PATCH 04/10] Fix linting --- lua/entities/gmod_wire_characterlcd/cl_init.lua | 9 ++++----- lua/entities/gmod_wire_characterlcd/init.lua | 6 +++--- lua/entities/gmod_wire_consolescreen/cl_init.lua | 6 ++---- lua/entities/gmod_wire_consolescreen/init.lua | 2 +- lua/entities/gmod_wire_digitalscreen/cl_init.lua | 2 +- lua/entities/gmod_wire_digitalscreen/init.lua | 2 +- lua/entities/gmod_wire_oscilloscope.lua | 12 +++++------- 7 files changed, 17 insertions(+), 22 deletions(-) diff --git a/lua/entities/gmod_wire_characterlcd/cl_init.lua b/lua/entities/gmod_wire_characterlcd/cl_init.lua index e28f2ca533..16275b2216 100644 --- a/lua/entities/gmod_wire_characterlcd/cl_init.lua +++ b/lua/entities/gmod_wire_characterlcd/cl_init.lua @@ -19,7 +19,7 @@ function ENT:Initialize() self.InteractiveData[i] = 0 end end - + -- Screen control: -- [1003] - Background red -- [1004] - Background green @@ -87,17 +87,16 @@ function ENT:Initialize() GPULib.ClientCacheCallback(self,function(Address,Value) self:WriteCell(Address,Value) end) - - + + WireLib.netRegister(self) end -local panel function ENT:SendData() net.Start("wire_interactiveprop_action") - + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets net.WriteEntity(self) for i=1, #data do diff --git a/lua/entities/gmod_wire_characterlcd/init.lua b/lua/entities/gmod_wire_characterlcd/init.lua index e1f929a335..95d119c004 100644 --- a/lua/entities/gmod_wire_characterlcd/init.lua +++ b/lua/entities/gmod_wire_characterlcd/init.lua @@ -1,4 +1,4 @@ -AddCSLuaFile("cl_init.lua") +AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") include("shared.lua") @@ -7,7 +7,7 @@ ENT.WireDebugName = "CharacterLcdScreen" function ENT:InitInteractive() local model = self:GetModel() local outputs = {"Memory"} - local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + local interactivemodel = WireLib.GetInteractiveModel(model) for i=1, #interactivemodel.widgets do outputs[i+1] = interactivemodel.widgets[i].name end @@ -23,7 +23,7 @@ function ENT:Initialize() self:SetSolid(SOLID_VPHYSICS) self.Inputs = WireLib.CreateInputs(self, { "CharAddress", "Char (ASCII/Unicode)", "Contrast", "Clk", "Reset" }) - + self.InteractiveData = {} self.IsInteractive = false if WireLib.IsValidInteractiveModel(self:GetModel()) then diff --git a/lua/entities/gmod_wire_consolescreen/cl_init.lua b/lua/entities/gmod_wire_consolescreen/cl_init.lua index 5ccb5a1477..780605c986 100644 --- a/lua/entities/gmod_wire_consolescreen/cl_init.lua +++ b/lua/entities/gmod_wire_consolescreen/cl_init.lua @@ -1,10 +1,8 @@ include("shared.lua") -local panel - function ENT:SendData() net.Start("wire_interactiveprop_action") - + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets net.WriteEntity(self) for i=1, #data do @@ -31,7 +29,7 @@ function ENT:Initialize() for i = 0, 2047 do self.Memory1[i] = 0 end - + self.InteractiveData = {} self.LastButtons = {} self.Buttons = {} diff --git a/lua/entities/gmod_wire_consolescreen/init.lua b/lua/entities/gmod_wire_consolescreen/init.lua index ce0f0d1502..d0086b8748 100644 --- a/lua/entities/gmod_wire_consolescreen/init.lua +++ b/lua/entities/gmod_wire_consolescreen/init.lua @@ -7,7 +7,7 @@ ENT.WireDebugName = "ConsoleScreen" function ENT:InitInteractive() local model = self:GetModel() local outputs = {"Memory"} - local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + local interactivemodel = WireLib.GetInteractiveModel(model) for i=1, #interactivemodel.widgets do outputs[i+1] = interactivemodel.widgets[i].name end diff --git a/lua/entities/gmod_wire_digitalscreen/cl_init.lua b/lua/entities/gmod_wire_digitalscreen/cl_init.lua index b14c1bd788..cb76842e13 100644 --- a/lua/entities/gmod_wire_digitalscreen/cl_init.lua +++ b/lua/entities/gmod_wire_digitalscreen/cl_init.lua @@ -4,7 +4,7 @@ local panel function ENT:SendData() net.Start("wire_interactiveprop_action") - + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets net.WriteEntity(self) for i=1, #data do diff --git a/lua/entities/gmod_wire_digitalscreen/init.lua b/lua/entities/gmod_wire_digitalscreen/init.lua index f882e00956..5858f21d3e 100644 --- a/lua/entities/gmod_wire_digitalscreen/init.lua +++ b/lua/entities/gmod_wire_digitalscreen/init.lua @@ -1,6 +1,6 @@ AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) -include('shared.lua') +include("shared.lua") DEFINE_BASECLASS( "base_wire_entity" ) ENT.WireDebugName = "DigitalScreen" diff --git a/lua/entities/gmod_wire_oscilloscope.lua b/lua/entities/gmod_wire_oscilloscope.lua index ae41a7ac86..21ffcbeca8 100644 --- a/lua/entities/gmod_wire_oscilloscope.lua +++ b/lua/entities/gmod_wire_oscilloscope.lua @@ -4,12 +4,10 @@ ENT.PrintName = "Wire Oscilloscope" ENT.WireDebugName = "Oscilloscope" if CLIENT then - - local panel function ENT:SendData() net.Start("wire_interactiveprop_action") - + local data = WireLib.GetInteractiveModel(self:GetModel()).widgets net.WriteEntity(self) for i=1, #data do @@ -32,8 +30,8 @@ if CLIENT then function ENT:Initialize() self.GPU = WireGPU(self) - - + + self.InteractiveData = {} self.LastButtons = {} self.Buttons = {} @@ -152,7 +150,7 @@ end function ENT:InitInteractive() local model = self:GetModel() local outputs = {} - local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + local interactivemodel = WireLib.GetInteractiveModel(model) for i=1, #interactivemodel.widgets do outputs[i+1] = interactivemodel.widgets[i].name end @@ -214,7 +212,7 @@ function ENT:Initialize() self:SetSolid( SOLID_VPHYSICS ) self.Inputs = WireLib.CreateInputs(self, { "X", "Y", "R", "G", "B", "Pause", "Length", "Update Frequency" }) - + if WireLib.IsValidInteractiveModel(self:GetModel()) then self:InitInteractive() end From a0471593e6c0a190981a789763ad1a1e189b8e9f Mon Sep 17 00:00:00 2001 From: wav3 Date: Thu, 28 Aug 2025 02:54:21 +0200 Subject: [PATCH 05/10] linter should be happy now --- lua/entities/gmod_wire_consolescreen/init.lua | 2 +- .../gmod_wire_digitalscreen/cl_init.lua | 22 +++++++++---------- lua/entities/gmod_wire_digitalscreen/init.lua | 4 ++-- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/lua/entities/gmod_wire_consolescreen/init.lua b/lua/entities/gmod_wire_consolescreen/init.lua index d0086b8748..463cf74c21 100644 --- a/lua/entities/gmod_wire_consolescreen/init.lua +++ b/lua/entities/gmod_wire_consolescreen/init.lua @@ -1,6 +1,6 @@ AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") -include('shared.lua') +include("shared.lua") ENT.WireDebugName = "ConsoleScreen" diff --git a/lua/entities/gmod_wire_digitalscreen/cl_init.lua b/lua/entities/gmod_wire_digitalscreen/cl_init.lua index cb76842e13..788a343127 100644 --- a/lua/entities/gmod_wire_digitalscreen/cl_init.lua +++ b/lua/entities/gmod_wire_digitalscreen/cl_init.lua @@ -1,6 +1,6 @@ -include('shared.lua') +include("shared.lua") + -local panel function ENT:SendData() net.Start("wire_interactiveprop_action") @@ -58,15 +58,15 @@ function ENT:Initialize() self.RefreshRows[i] = i-1 end - //0..786431 - RGB data + --0..786431 - RGB data - //1048569 - Color mode (0: RGBXXX; 1: R G B) - //1048570 - Clear row - //1048571 - Clear column - //1048572 - Screen Height - //1048573 - Screen Width - //1048574 - Hardware Clear Screen - //1048575 - CLK + --1048569 - Color mode (0: RGBXXX; 1: R G B) + --1048570 - Clear row + --1048571 - Clear column + --1048572 - Screen Height + --1048573 - Screen Width + --1048574 - Hardware Clear Screen + --1048575 - CLK self.GPU = WireGPU(self) @@ -264,8 +264,6 @@ transformcolor[4] = function(c) -- XXX return c, c, c end -local floor = math.floor - function ENT:RedrawPixel(a) if a >= self.ScreenWidth*self.ScreenHeight then return end diff --git a/lua/entities/gmod_wire_digitalscreen/init.lua b/lua/entities/gmod_wire_digitalscreen/init.lua index 5858f21d3e..f76e0a1cfa 100644 --- a/lua/entities/gmod_wire_digitalscreen/init.lua +++ b/lua/entities/gmod_wire_digitalscreen/init.lua @@ -9,7 +9,7 @@ ENT.WireDebugName = "DigitalScreen" function ENT:InitInteractive() local model = self:GetModel() local outputs = {"Memory"} - local interactivemodel = WireLib.GetInteractiveModel(self:GetModel()) + local interactivemodel = WireLib.GetInteractiveModel(model) for i=1, #interactivemodel.widgets do outputs[i+1] = interactivemodel.widgets[i].name end @@ -378,7 +378,7 @@ function ENT:WriteCell(Address, value) -- reset memory self.Memory = mem - elseif Address == 1048575 then -- CLK + -- elseif Address == 1048575 then -- CLK -- not needed atm end end From 2b4f898cb6ff200fb72941ee57e4f40391b4c280 Mon Sep 17 00:00:00 2001 From: wav3 Date: Fri, 29 Aug 2025 18:19:28 +0200 Subject: [PATCH 06/10] This should be better --- lua/entities/gmod_wire_interactiveprop.lua | 47 +++++++++++----------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/lua/entities/gmod_wire_interactiveprop.lua b/lua/entities/gmod_wire_interactiveprop.lua index 395e5ae217..8990df01de 100644 --- a/lua/entities/gmod_wire_interactiveprop.lua +++ b/lua/entities/gmod_wire_interactiveprop.lua @@ -219,24 +219,23 @@ end function WireLib.GetInteractiveWidgetBody( ent, data ) local body = vgui.Create("DFrame") - body:SetTitle(data.title) - body:SetSize(data.width, data.height) - body:SetVisible(true) - body.Paint = function( self, w, h ) -- 'function Frame:Paint( w, h )' works too - -- surface.SetDrawColor(255,255,255) - -- surface.DrawOutlinedRect(0, 0, w, h) - -- surface.SetDrawColor(0,0,0) - -- surface.DrawOutlinedRect(1, 1, w-2, h-2) - draw.RoundedBox( 4, 0, 0, w, h, Color( 255, 255, 255 ) ) - draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 64, 64, 64 ) ) - end - body:SetDraggable(false) - body:Center() - body:ShowCloseButton(true) - body:MakePopup() - for id, widget in ipairs( data.widgets ) do - WidgetBuilders[widget.type](ent, widget, body, id) - end + + body:SetTitle(data.title) + body:SetSize(data.width, data.height) + body:SetVisible(true) + body:SetDraggable(false) + body:ShowCloseButton(true) + body:MakePopup() + body:Center() + + function body:Paint(w, h) + draw.RoundedBox(4, 0, 0, w, h, color_white) + draw.RoundedBox(4, 1, 1, w - 2, h - 2, Color(64, 64, 64)) + end + + for id, widget in ipairs( data.widgets ) do + WidgetBuilders[widget.type](ent, widget, body, id) + end return body end @@ -250,7 +249,7 @@ WidgetBuilders = { local checkbox = vgui.Create("DCheckBox", body) checkbox:SetPos(data.x, data.y) checkbox:SetValue(self.InteractiveData[index]) - checkbox.OnChange = function(box,value) + function checkbox.OnChange(box, value) surface.PlaySound("buttons/lightswitch2.wav") self.InteractiveData[index] = value and 1 or 0 self:SendData() @@ -265,13 +264,13 @@ WidgetBuilders = { numberscratch:SetDecimals(4) numberscratch:SetPos(data.x, data.y) numberscratch:SetValue(self.InteractiveData[index]) - numberscratch.OnValueChanged = function(scratch,value) + function numberscratch.OnValueChanged(scratch, value) self.InteractiveData[index] = value self:SendData() end numberscratch:SetImageVisible( false ) numberscratch:SetSize( 17, 17 ) - numberscratch.Paint = function( self, w, h ) + function numberscratch:Paint( w, h ) draw.RoundedBox( 8.5, 0, 0, w, h, numberscratch.color ) local value = self:GetFloatValue() surface.SetDrawColor(255, 255, 255) @@ -289,11 +288,11 @@ WidgetBuilders = { button:SetPos(data.x, data.y) button:SetText(data.text or "") button:SetSize(data.width or 20, data.height or 20) - button.OnDepressed = function(scratch) + function button.OnDepressed(btn) self.InteractiveData[index] = 1 self:SendData() end - button.OnReleased = function(scratch) + function button.OnReleased(btn) self.InteractiveData[index] = 0 self:SendData() end @@ -342,7 +341,7 @@ if CLIENT then local self = net.ReadEntity() if not IsValid(self) then return end panel = self:GetPanel() - panel.OnClose = function(panel) + function panel.OnClose(panel) net.Start("wire_interactiveprop_close") self.Buttons = {} self.LastButtons = {} From fa18df478620410d59cb34cbbf570c70e35099e1 Mon Sep 17 00:00:00 2001 From: wav3 Date: Fri, 29 Aug 2025 19:19:10 +0200 Subject: [PATCH 07/10] get rid of trailing ws --- lua/entities/gmod_wire_interactiveprop.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/entities/gmod_wire_interactiveprop.lua b/lua/entities/gmod_wire_interactiveprop.lua index 8990df01de..f41b4000e5 100644 --- a/lua/entities/gmod_wire_interactiveprop.lua +++ b/lua/entities/gmod_wire_interactiveprop.lua @@ -219,7 +219,7 @@ end function WireLib.GetInteractiveWidgetBody( ent, data ) local body = vgui.Create("DFrame") - + body:SetTitle(data.title) body:SetSize(data.width, data.height) body:SetVisible(true) @@ -227,7 +227,7 @@ function WireLib.GetInteractiveWidgetBody( ent, data ) body:ShowCloseButton(true) body:MakePopup() body:Center() - + function body:Paint(w, h) draw.RoundedBox(4, 0, 0, w, h, color_white) draw.RoundedBox(4, 1, 1, w - 2, h - 2, Color(64, 64, 64)) From fdd6adf7daee80ec00820993421c45c6ec9c9374 Mon Sep 17 00:00:00 2001 From: wav3 Date: Fri, 29 Aug 2025 19:19:43 +0200 Subject: [PATCH 08/10] They are visible by default --- lua/entities/gmod_wire_interactiveprop.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/lua/entities/gmod_wire_interactiveprop.lua b/lua/entities/gmod_wire_interactiveprop.lua index f41b4000e5..e3acce6dd4 100644 --- a/lua/entities/gmod_wire_interactiveprop.lua +++ b/lua/entities/gmod_wire_interactiveprop.lua @@ -222,9 +222,7 @@ function WireLib.GetInteractiveWidgetBody( ent, data ) body:SetTitle(data.title) body:SetSize(data.width, data.height) - body:SetVisible(true) body:SetDraggable(false) - body:ShowCloseButton(true) body:MakePopup() body:Center() From eb55f3d005030a71a8b166d923a34c2674aaa8fa Mon Sep 17 00:00:00 2001 From: wav3 Date: Mon, 1 Sep 2025 01:03:10 +0200 Subject: [PATCH 09/10] Optional interactiveness --- lua/entities/gmod_wire_characterlcd/init.lua | 21 ++++++++++++++++--- lua/entities/gmod_wire_consolescreen/init.lua | 18 ++++++++++++++-- lua/entities/gmod_wire_digitalscreen/init.lua | 17 ++++++++++++--- lua/entities/gmod_wire_oscilloscope.lua | 18 +++++++++++++++- lua/wire/stools/characterlcd.lua | 6 +++++- lua/wire/stools/consolescreen.lua | 10 ++++++++- lua/wire/stools/digitalscreen.lua | 5 ++++- lua/wire/stools/oscilloscope.lua | 10 ++++++++- 8 files changed, 92 insertions(+), 13 deletions(-) diff --git a/lua/entities/gmod_wire_characterlcd/init.lua b/lua/entities/gmod_wire_characterlcd/init.lua index 95d119c004..7622d96bb9 100644 --- a/lua/entities/gmod_wire_characterlcd/init.lua +++ b/lua/entities/gmod_wire_characterlcd/init.lua @@ -15,8 +15,11 @@ function ENT:InitInteractive() self.NextPrompt = 0 self.Outputs=WireLib.CreateOutputs(self,outputs) self.IsInteractive = true + self:UpdateOverlay() end + + function ENT:Initialize() self:PhysicsInit(SOLID_VPHYSICS) self:SetMoveType(MOVETYPE_VPHYSICS) @@ -61,7 +64,7 @@ function ENT:Initialize() self.Cache = GPUCacheManager(self,true) end -function ENT:Setup(ScreenWidth, ScreenHeight, bgred,bggreen,bgblue,fgred,fggreen,fgblue) +function ENT:Setup(ScreenWidth, ScreenHeight, bgred,bggreen,bgblue,fgred,fggreen,fgblue,IsInteractive) self:WriteCell(1010, tonumber(ScreenHeight) or 2) self:WriteCell(1009, tonumber(ScreenWidth) or 16) self:WriteCell(1008, tonumber(fgblue) or 45) @@ -71,6 +74,7 @@ function ENT:Setup(ScreenWidth, ScreenHeight, bgred,bggreen,bgblue,fgred,fggreen self:WriteCell(1004, tonumber(bggreen) or 178) self:WriteCell(1003, tonumber(bgred) or 148) self:WriteCell(1023,1) + self.IsInteractive = WireLib.IsValidInteractiveModel(self:GetModel()) and (IsInteractive == 1) end function ENT:SendPixel() if (self.Memory[1023] ~= 0) and (self.CharAddress >= 0) and (self.CharAddress < self.ScreenWidth*self.ScreenHeight) then @@ -209,11 +213,22 @@ function ENT:ReceiveData() end end -function ENT:UpdateOverlay() -- required by interactiveprop functions +function ENT:UpdateOverlay() + if not self.IsInteractive then + return + end + + txt = "" + if IsValid(self.User) then + txt = "In use by: " .. self.User:Nick() + end + + self:SetOverlayText(txt) end + function ENT:Prompt( ply ) if not self.IsInteractive then return end if ply then @@ -245,4 +260,4 @@ function ENT:Unprompt() self.User = nil end -duplicator.RegisterEntityClass("gmod_wire_characterlcd", WireLib.MakeWireEnt, "Data", "ScreenWidth", "ScreenHeight") +duplicator.RegisterEntityClass("gmod_wire_characterlcd", WireLib.MakeWireEnt, "Data", "ScreenWidth", "ScreenHeight", "IsInteractive") diff --git a/lua/entities/gmod_wire_consolescreen/init.lua b/lua/entities/gmod_wire_consolescreen/init.lua index 463cf74c21..ae0672e645 100644 --- a/lua/entities/gmod_wire_consolescreen/init.lua +++ b/lua/entities/gmod_wire_consolescreen/init.lua @@ -15,6 +15,7 @@ function ENT:InitInteractive() self.NextPrompt = 0 self.Outputs=WireLib.CreateOutputs(self,outputs) self.IsInteractive = true + self:UpdateOverlay() end @@ -26,8 +27,17 @@ function ENT:ReceiveData() end end -function ENT:UpdateOverlay() -- required by interactiveprop functions +function ENT:UpdateOverlay() + if not self.IsInteractive then + return + end + + txt = "" + if IsValid(self.User) then + txt = "In use by: " .. self.User:Nick() + end + self:SetOverlayText(txt) end @@ -52,6 +62,10 @@ function ENT:Prompt( ply ) end end +function ENT:Setup(IsInteractive) + self.IsInteractive = WireLib.IsValidInteractiveModel(self:GetModel()) and (IsInteractive == 1) +end + function ENT:Use(ply) if not IsValid( ply ) then return end self:Prompt( ply ) @@ -279,4 +293,4 @@ function ENT:ClientWriteCell(Address, value) end end -duplicator.RegisterEntityClass("gmod_wire_consolescreen", WireLib.MakeWireEnt, "Data") +duplicator.RegisterEntityClass("gmod_wire_consolescreen", WireLib.MakeWireEnt, "Data", "IsInteractive") diff --git a/lua/entities/gmod_wire_digitalscreen/init.lua b/lua/entities/gmod_wire_digitalscreen/init.lua index f76e0a1cfa..23d49f53d2 100644 --- a/lua/entities/gmod_wire_digitalscreen/init.lua +++ b/lua/entities/gmod_wire_digitalscreen/init.lua @@ -17,6 +17,7 @@ function ENT:InitInteractive() self.NextPrompt = 0 self.Outputs=WireLib.CreateOutputs(self,outputs) self.IsInteractive = true + self:UpdateOverlay() end @@ -28,8 +29,17 @@ function ENT:ReceiveData() end end -function ENT:UpdateOverlay() -- required by interactiveprop functions +function ENT:UpdateOverlay() + if not self.IsInteractive then + return + end + + txt = "" + if IsValid(self.User) then + txt = "In use by: " .. self.User:Nick() + end + self:SetOverlayText(txt) end @@ -97,9 +107,10 @@ function ENT:Initialize() self.ChangedStep = 1 end -function ENT:Setup(ScreenWidth, ScreenHeight) +function ENT:Setup(ScreenWidth, ScreenHeight, IsInteractive) self:WriteCell(1048572, ScreenHeight or 32) self:WriteCell(1048573, ScreenWidth or 32) + self.IsInteractive = WireLib.IsValidInteractiveModel(self:GetModel()) and (IsInteractive == 1) end function ENT:SendPixel() @@ -418,4 +429,4 @@ function ENT:TriggerInput(iname, value) end end -duplicator.RegisterEntityClass("gmod_wire_digitalscreen", WireLib.MakeWireEnt, "Data", "ScreenWidth", "ScreenHeight") +duplicator.RegisterEntityClass("gmod_wire_digitalscreen", WireLib.MakeWireEnt, "Data", "ScreenWidth", "ScreenHeight", "IsInteractive") diff --git a/lua/entities/gmod_wire_oscilloscope.lua b/lua/entities/gmod_wire_oscilloscope.lua index 21ffcbeca8..77731ff233 100644 --- a/lua/entities/gmod_wire_oscilloscope.lua +++ b/lua/entities/gmod_wire_oscilloscope.lua @@ -146,6 +146,9 @@ function ENT:SetNextNode(x, y) net.SendPVS( self:GetPos() ) end +function ENT:Setup(IsInteractive) + self.IsInteractive = WireLib.IsValidInteractiveModel(self:GetModel()) and (IsInteractive == 1) +end function ENT:InitInteractive() local model = self:GetModel() @@ -158,6 +161,7 @@ function ENT:InitInteractive() self.NextPrompt = 0 self.Outputs=WireLib.CreateOutputs(self,outputs) self.IsInteractive = true + self:UpdateOverlay() end @@ -169,11 +173,22 @@ function ENT:ReceiveData() end end -function ENT:UpdateOverlay() -- required by interactiveprop functions +function ENT:UpdateOverlay() + if not self.IsInteractive then + return + end + + txt = "" + if IsValid(self.User) then + txt = "In use by: " .. self.User:Nick() + end + + self:SetOverlayText(txt) end + function ENT:Prompt( ply ) if not self.IsInteractive then return end if ply then @@ -197,6 +212,7 @@ end function ENT:Use(ply) if not IsValid( ply ) then return end + if not self.IsInteractive then return end self:Prompt( ply ) end diff --git a/lua/wire/stools/characterlcd.lua b/lua/wire/stools/characterlcd.lua index cbb9565e61..05b6ca756c 100644 --- a/lua/wire/stools/characterlcd.lua +++ b/lua/wire/stools/characterlcd.lua @@ -6,6 +6,7 @@ if CLIENT then language.Add( "tool.wire_characterlcd.desc", "Spawns a Character LCD, which can be used to display text" ) language.Add( "tool.wire_characterlcd.bgcolor", "Background color:" ) language.Add( "tool.wire_characterlcd.fgcolor", "Text color:" ) + language.Add( "tool.wire_characterlcd.interactive", "Interactive (if available):" ) TOOL.Information = { { name = "left", text = "Create/Update " .. TOOL.Name } } WireToolSetup.setToolMenuIcon("icon16/application_xp_terminal.png") @@ -21,7 +22,8 @@ if SERVER then math.Clamp(self:GetClientNumber("bgblue"), 0, 255), math.Clamp(self:GetClientNumber("fgred"), 0, 255), math.Clamp(self:GetClientNumber("fggreen"), 0, 255), - math.Clamp(self:GetClientNumber("fgblue"), 0, 255) + math.Clamp(self:GetClientNumber("fgblue"), 0, 255), + self:GetClientNumber("interactive") end end @@ -36,6 +38,7 @@ TOOL.ClientConVar = { fgred = 45, fggreen = 91, fgblue = 45, + interactive = 1, } @@ -64,6 +67,7 @@ function TOOL.BuildCPanel(panel) }) panel:NumSlider("Width", "wire_characterlcd_width", 1, 56, 0) panel:NumSlider("Height", "wire_characterlcd_height", 1, 16, 0) + panel:CheckBox("#tool.wire_characterlcd.interactive", "wire_characterlcd_interactive") panel:CheckBox("#Create Flat to Surface", "wire_characterlcd_createflat") end diff --git a/lua/wire/stools/consolescreen.lua b/lua/wire/stools/consolescreen.lua index 836b51e427..aa1d4bbb95 100644 --- a/lua/wire/stools/consolescreen.lua +++ b/lua/wire/stools/consolescreen.lua @@ -4,6 +4,7 @@ WireToolSetup.open( "consolescreen", "Console Screen", "gmod_wire_consolescreen" if CLIENT then language.Add( "tool.wire_consolescreen.name", "Console Screen Tool (Wire)" ) language.Add( "tool.wire_consolescreen.desc", "Spawns a console screen" ) + language.Add( "tool.wire_consolescreen.interactive", "Interactive (if available):" ) TOOL.Information = { { name = "left", text = "Create " .. TOOL.Name } } WireToolSetup.setToolMenuIcon( "icon16/application_xp_terminal.png" ) @@ -11,14 +12,21 @@ end WireToolSetup.BaseLang() WireToolSetup.SetupMax( 20 ) -TOOL.NoLeftOnClass = true -- no update ent function needed +if SERVER then + function TOOL:GetConVars() + return self:GetClientNumber("interactive") + end +end + TOOL.ClientConVar = { model = "models/props_lab/monitor01b.mdl", createflat = 0, + interactive = 1, } function TOOL.BuildCPanel(panel) WireDermaExts.ModelSelect(panel, "wire_consolescreen_model", list.Get( "WireScreenModels" ), 5) + panel:CheckBox("#tool.wire_consolescreen.interactive", "wire_consolescreen_interactive") panel:CheckBox("#Create Flat to Surface", "wire_consolescreen_createflat") panel:Help("CharParam is LBBBFFF format: background and foreground colour of the character (one digit each for RGB), if L is nonzero the char flashes") end diff --git a/lua/wire/stools/digitalscreen.lua b/lua/wire/stools/digitalscreen.lua index 0a3b03ed27..5f984d5ecf 100644 --- a/lua/wire/stools/digitalscreen.lua +++ b/lua/wire/stools/digitalscreen.lua @@ -4,6 +4,7 @@ WireToolSetup.open( "digitalscreen", "Digital Screen", "gmod_wire_digitalscreen" if CLIENT then language.Add( "tool.wire_digitalscreen.name", "Digital Screen Tool (Wire)" ) language.Add( "tool.wire_digitalscreen.desc", "Spawns a digital screen, which can be used to draw pixel by pixel." ) + language.Add( "tool.wire_digitalscreen.interactive", "Interactive (if available):" ) TOOL.Information = { { name = "left", text = "Create/Update " .. TOOL.Name } } WireToolSetup.setToolMenuIcon("icon16/application_xp_terminal.png") @@ -13,7 +14,7 @@ WireToolSetup.SetupMax( 20 ) if SERVER then function TOOL:GetConVars() - return self:GetClientInfo("width"), self:GetClientInfo("height") + return self:GetClientInfo("width"), self:GetClientInfo("height"), self:GetClientNumber("interactive") end end @@ -22,11 +23,13 @@ TOOL.ClientConVar = { width = 32, height = 32, createflat = 0, + interactive = 1, } function TOOL.BuildCPanel(panel) WireDermaExts.ModelSelect(panel, "wire_digitalscreen_model", list.Get( "WireScreenModels" ), 5) panel:NumSlider("Width", "wire_digitalscreen_width", 1, 512, 0) panel:NumSlider("Height", "wire_digitalscreen_height", 1, 512, 0) + panel:CheckBox("#tool.wire_digitalscreen.interactive", "wire_digitalscreen_interactive") panel:CheckBox("#Create Flat to Surface", "wire_digitalscreen_createflat") end diff --git a/lua/wire/stools/oscilloscope.lua b/lua/wire/stools/oscilloscope.lua index 531af22dbe..ff97632400 100644 --- a/lua/wire/stools/oscilloscope.lua +++ b/lua/wire/stools/oscilloscope.lua @@ -4,6 +4,7 @@ WireToolSetup.open( "oscilloscope", "Oscilloscope", "gmod_wire_oscilloscope", ni if CLIENT then language.Add( "tool.wire_oscilloscope.name", "Oscilloscope Tool (Wire)" ) language.Add( "tool.wire_oscilloscope.desc", "Spawns an oscilloscope that displays line graphs." ) + language.Add( "tool.wire_oscilloscope.interactive", "Interactive (if available):" ) TOOL.Information = { { name = "left", text = "Create/Update " .. TOOL.Name } } WireToolSetup.setToolMenuIcon("icon16/chart_line.png") @@ -11,13 +12,20 @@ end WireToolSetup.BaseLang() WireToolSetup.SetupMax( 20 ) -TOOL.NoLeftOnClass = true -- no update ent function needed +if SERVER then + function TOOL:GetConVars() + return self:GetClientNumber("interactive") + end +end + TOOL.ClientConVar = { model = "models/props_lab/monitor01b.mdl", createflat = 0, + interactive = 1, } function TOOL.BuildCPanel(panel) WireDermaExts.ModelSelect(panel, "wire_oscilloscope_model", list.Get( "WireScreenModels" ), 5) + panel:CheckBox("#tool.wire_oscilloscope.interactive", "wire_oscilloscope_interactive") panel:CheckBox("#Create Flat to Surface", "wire_oscilloscope_createflat") end From 599365b636ccd48f2efab71557eef5d28bfcefac Mon Sep 17 00:00:00 2001 From: wav3 Date: Wed, 3 Sep 2025 08:52:02 +0200 Subject: [PATCH 10/10] Fix lint --- lua/entities/gmod_wire_characterlcd/init.lua | 2 +- lua/entities/gmod_wire_consolescreen/init.lua | 2 +- lua/entities/gmod_wire_digitalscreen/init.lua | 2 +- lua/entities/gmod_wire_oscilloscope.lua | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/entities/gmod_wire_characterlcd/init.lua b/lua/entities/gmod_wire_characterlcd/init.lua index 7622d96bb9..1acba99350 100644 --- a/lua/entities/gmod_wire_characterlcd/init.lua +++ b/lua/entities/gmod_wire_characterlcd/init.lua @@ -218,7 +218,7 @@ function ENT:UpdateOverlay() if not self.IsInteractive then return end - + txt = "" if IsValid(self.User) then txt = "In use by: " .. self.User:Nick() diff --git a/lua/entities/gmod_wire_consolescreen/init.lua b/lua/entities/gmod_wire_consolescreen/init.lua index ae0672e645..252002559a 100644 --- a/lua/entities/gmod_wire_consolescreen/init.lua +++ b/lua/entities/gmod_wire_consolescreen/init.lua @@ -31,7 +31,7 @@ function ENT:UpdateOverlay() if not self.IsInteractive then return end - + txt = "" if IsValid(self.User) then txt = "In use by: " .. self.User:Nick() diff --git a/lua/entities/gmod_wire_digitalscreen/init.lua b/lua/entities/gmod_wire_digitalscreen/init.lua index 23d49f53d2..3be26fc1ee 100644 --- a/lua/entities/gmod_wire_digitalscreen/init.lua +++ b/lua/entities/gmod_wire_digitalscreen/init.lua @@ -33,7 +33,7 @@ function ENT:UpdateOverlay() if not self.IsInteractive then return end - + txt = "" if IsValid(self.User) then txt = "In use by: " .. self.User:Nick() diff --git a/lua/entities/gmod_wire_oscilloscope.lua b/lua/entities/gmod_wire_oscilloscope.lua index 77731ff233..c7320560b3 100644 --- a/lua/entities/gmod_wire_oscilloscope.lua +++ b/lua/entities/gmod_wire_oscilloscope.lua @@ -178,7 +178,7 @@ function ENT:UpdateOverlay() if not self.IsInteractive then return end - + txt = "" if IsValid(self.User) then txt = "In use by: " .. self.User:Nick()