dobrograd-13-06-2022/garrysmod/addons/feature-wire/lua/entities/gmod_wire_oscilloscope.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

188 lines
4.5 KiB
Lua

AddCSLuaFile()
DEFINE_BASECLASS( "base_wire_entity" )
ENT.PrintName = "Wire Oscilloscope"
ENT.WireDebugName = "Oscilloscope"
if CLIENT then
function ENT:Initialize()
self.GPU = WireGPU(self)
self.Nodes = {}
end
function ENT:OnRemove()
self.GPU:Finalize()
end
function ENT:GetNodeList()
return self.Nodes
end
function ENT:AddNode(x,y)
self.Nodes[#self.Nodes+1] = {
X = x,
Y = y
}
if #self.Nodes > self:GetNWFloat("Length",50) then
for i=#self.Nodes,self:GetNWFloat("Length",50),-1 do
table.remove(self.Nodes,1)
end
end
end
net.Receive( "wire_oscilloscope_send_node", function( length )
local ent = net.ReadEntity()
local x = net.ReadFloat()
local y = net.ReadFloat()
if IsValid(ent) then
ent:AddNode(x,y)
end
end)
function ENT:Draw()
self:DrawModel()
local length = self:GetNWFloat("Length", 50)
local r,g,b = self:GetNWFloat("R"), self:GetNWFloat("G"), self:GetNWFloat("B")
if r == 0 and g == 0 and b == 0 then g = 200 end
self.GPU:RenderToGPU(function()
surface.SetDrawColor(10,20,5,255)
surface.DrawRect(0,0,512,512)
local nodes = self:GetNodeList()
for i=1,length do
local i_next = i+1
if not nodes[i_next] then continue end
local nx1 = nodes[i].X*256+256
local ny1 = -nodes[i].Y*256+256
local nx2 = nodes[i_next].X*256+256
local ny2 = -nodes[i_next].Y*256+256
if ((nx1-nx2)*(nx1-nx2) + (ny1-ny2)*(ny1-ny2) < 256*256) then
local a = math.max(1, 3.75-(3*i)/length)^1.33
local a2 = math.max(1, a/2)
for i=-3,3 do
surface.SetDrawColor(r/a, g/a, b/a, 255)
surface.DrawLine(nx1, ny1+i, nx2, ny2+i)
surface.SetDrawColor(r/a, g/a, b/a, 255)
surface.DrawLine(nx1+i, ny1, nx2+i, ny2)
end
surface.SetDrawColor(r/a2, g/a2, b/a2, 255)
surface.DrawLine(nx1, ny1, nx2, ny2)
end
end
surface.SetDrawColor(30, 120, 10, 255)
surface.DrawLine(0, 128, 512, 128)
surface.DrawLine(0, 384, 512, 384)
surface.DrawLine(128, 0, 128, 512)
surface.DrawLine(384, 0, 384, 512)
surface.SetDrawColor(180, 200, 10, 255)
surface.DrawLine(0, 256, 512, 256)
surface.DrawLine(256, 0, 256, 512)
end)
self.GPU:Render()
Wire_Render(self)
end
return -- No more client
end
-- Server
local wire_oscilloscope_maxlength = CreateConVar("wire_oscilloscope_maxlength", 100, {FCVAR_ARCHIVE}, "Maximum number of nodes")
util.AddNetworkString( "wire_oscilloscope_send_node" )
function ENT:SetNextNode(x, y)
net.Start("wire_oscilloscope_send_node")
net.WriteEntity(self)
net.WriteFloat(x)
net.WriteFloat(y)
net.SendPVS( self:GetPos() )
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" })
end
function ENT:Think()
if (self.Inputs.Pause.Value == 0) then
BaseClass.Think(self)
local x = math.max(-1, math.min(self.Inputs.X.Value or 0, 1))
local y = math.max(-1, math.min(self.Inputs.Y.Value or 0, 1))
self:SetNextNode(x, y)
self:NextThink(CurTime()+(self.updaterate or 0.08))
return true
end
end
function ENT:TriggerInput(iname, value)
if iname == "R" then
self:SetNWFloat("R", math.Clamp(value, 0, 255))
elseif iname == "G" then
self:SetNWFloat("G", math.Clamp(value, 0, 255))
elseif iname == "B" then
self:SetNWFloat("B", math.Clamp(value, 0, 255))
elseif iname == "Length" then
if value == 0 then value = 50 end
self:SetNWFloat("Length", math.Clamp(value, 1, wire_oscilloscope_maxlength:GetInt()))
elseif iname == "Update Frequency" then
if value <= 0 then value = 0.08 end
self.updaterate = value
end
end
--[[
hi-speed Addresses:
0: X
1: Y
2: R
3: G
4: B
5: Length
6: Update frequency
]]
local address_lookup = {nil,nil,"R","G","B","Length","Update Frequency"}
function ENT:WriteCell( address, value )
address = math.floor(address)
address = address + 1
if address == 1 then
self.Inputs.X.Value = value
elseif address == 2 then
self.Inputs.Y.Value = value
elseif address_lookup[address] then
self:TriggerInput( address_lookup[address], value )
end
end
function ENT:ReadCell( address )
address = math.floor(address)
address = address + 1
if address == 1 then
return self.Inputs.X.Value
elseif address == 2 then
return self.Inputs.Y.Value
elseif address == 4 then
return self.updaterate
elseif address_lookup[address] then
return self:GetNWFloat( address_lookup[address] )
end
return 0
end
duplicator.RegisterEntityClass("gmod_wire_oscilloscope", WireLib.MakeWireEnt, "Data")