108 lines
2.9 KiB
Lua
108 lines
2.9 KiB
Lua
-- wire_paths.lua
|
|
--
|
|
-- This file implements syncing of wire paths, which are the visual
|
|
-- component of wires.
|
|
--
|
|
-- Conceptually, a wire path has a material, a color, and a non-zero width, as
|
|
-- well as as a non-empty polyline along the wire. (Each point in the line
|
|
-- has both a parent entity, and a local offset from that entity.)
|
|
--
|
|
|
|
if not WireLib then return end
|
|
|
|
if CLIENT then
|
|
net.Receive("WireLib.Paths.TransmitPath", function(length)
|
|
local path = {
|
|
Path = {}
|
|
}
|
|
path.Entity = net.ReadEntity()
|
|
if not path.Entity:IsValid() then return end
|
|
path.Name = net.ReadString()
|
|
path.Width = net.ReadFloat()
|
|
if path.Width<=0 then
|
|
if path.Entity.WirePaths then
|
|
path.Entity.WirePaths[path.Name] = nil
|
|
end
|
|
return
|
|
end
|
|
path.StartPos = net.ReadVector()
|
|
path.Material = net.ReadString()
|
|
path.Color = net.ReadColor()
|
|
|
|
local num_points = net.ReadUInt(16)
|
|
for i = 1, num_points do
|
|
path.Path[i] = { Entity = net.ReadEntity(), Pos = net.ReadVector() }
|
|
end
|
|
|
|
if path.Entity.WirePaths == nil then path.Entity.WirePaths = {} end
|
|
path.Entity.WirePaths[path.Name] = path
|
|
|
|
end)
|
|
return
|
|
end
|
|
|
|
WireLib.Paths = {}
|
|
local transmit_queues = setmetatable({}, { __index = function(t,p) t[p] = {} return t[p] end })
|
|
util.AddNetworkString("WireLib.Paths.RequestPaths")
|
|
util.AddNetworkString("WireLib.Paths.TransmitPath")
|
|
|
|
net.Receive("WireLib.Paths.RequestPaths", function(length, ply)
|
|
local ent = net.ReadEntity()
|
|
if ent:IsValid() and ent.Inputs then
|
|
for name, input in pairs(ent.Inputs) do
|
|
if input.Src then
|
|
WireLib.Paths.Add(input, ply)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function TransmitPath(input, ply)
|
|
net.Start("WireLib.Paths.TransmitPath")
|
|
local color = input.Color
|
|
net.WriteEntity(input.Entity)
|
|
net.WriteString(input.Name)
|
|
if not input.Src or input.Width<=0 then
|
|
net.WriteFloat(0)
|
|
else
|
|
net.WriteFloat(input.Width)
|
|
net.WriteVector(input.StartPos)
|
|
net.WriteString(input.Material)
|
|
net.WriteColor(Color(color.r or 255, color.g or 255, color.b or 255, color.a or 255))
|
|
net.WriteUInt(#input.Path, 16)
|
|
for _, point in ipairs(input.Path) do
|
|
net.WriteEntity(point.Entity)
|
|
net.WriteVector(point.Pos)
|
|
end
|
|
end
|
|
net.Send(ply)
|
|
end
|
|
|
|
local function ProcessQueue()
|
|
for ply, queue in pairs(transmit_queues) do
|
|
if not ply:IsValid() then transmit_queues[ply] = nil continue end
|
|
local nextinqueue = table.remove(queue, 1)
|
|
if nextinqueue then
|
|
TransmitPath(nextinqueue, ply)
|
|
else
|
|
transmit_queues[ply] = nil
|
|
end
|
|
end
|
|
if not next(transmit_queues) then
|
|
timer.Remove("WireLib.Paths.ProcessQueue")
|
|
end
|
|
end
|
|
|
|
-- Add a path to every player's transmit queue
|
|
function WireLib.Paths.Add(input, ply)
|
|
if ply then
|
|
table.insert(transmit_queues[ply], input)
|
|
else
|
|
for _, player in pairs(player.GetAll()) do
|
|
table.insert(transmit_queues[player], input)
|
|
end
|
|
end
|
|
if not timer.Exists("WireLib.Paths.ProcessQueue") then
|
|
timer.Create("WireLib.Paths.ProcessQueue", 0, 0, ProcessQueue)
|
|
end
|
|
end
|