Skip to content

Commit

Permalink
Improve user-generated entity/wirelink outputs (#2891)
Browse files Browse the repository at this point in the history
* Improve user-generated entity/wirelink outputs
- Add output remover
- Made adding entity and wirelink outputs more sensible
- Cleaned up port assignment to not give bad indices
- Removed using CreateWirelinkOutput when it's not necessary
- Removed E2 `entity:wirelink()` creates a wirelink output
- ??? other magic to make this work

* Move link removal to wire_adv
Refactored wire_adv netcode to use a single networkstring

* Small lints
  • Loading branch information
Denneisk authored Dec 9, 2023
1 parent 4edf127 commit 95adeb4
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 57 deletions.
3 changes: 1 addition & 2 deletions lua/entities/gmod_wire_egp/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ function ENT:Initialize()

self.RenderTable = {}

WireLib.CreateOutputs( self, { "User (Outputs the player who used the screen for a single tick) [ENTITY]" } )
WireLib.CreateWirelinkOutput( nil, self, {true} )
WireLib.CreateOutputs( self, { "User (Outputs the player who used the screen for a single tick) [ENTITY]", "wirelink [WIRELINK]" } )

self.xScale = { 0, 512 }
self.yScale = { 0, 512 }
Expand Down
6 changes: 4 additions & 2 deletions lua/entities/gmod_wire_egp_hud/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ function ENT:Initialize()
self:SetUseType(SIMPLE_USE)
self:AddEFlags( EFL_FORCE_CHECK_TRANSMIT )

self.Inputs = WireLib.CreateInputs( self, { "0 to 512 (If enabled, changes the resolution of the egp hud to be between 0 and 512 instead of the user's monitor's resolution.\nWill cause objects to look stretched out on most screens, so your UI will need to be designed with this in mind.\nIt's recommended to use the egpScrW, egpScrH, and egpScrSize functions instead.)" } )
WireLib.CreateWirelinkOutput( nil, self, {true} )
self.Inputs = WireLib.CreateInputs( self, {
"0 to 512 (If enabled, changes the resolution of the egp hud to be between 0 and 512 instead of the user's monitor's resolution.\nWill cause objects to look stretched out on most screens, so your UI will need to be designed with this in mind.\nIt's recommended to use the egpScrW, egpScrH, and egpScrSize functions instead.)",
"wirelink [WIRELINK]"
})

self.xScale = { 0, 512 }
self.yScale = { 0, 512 }
Expand Down
5 changes: 1 addition & 4 deletions lua/entities/gmod_wire_expression2/core/custom/wiring.lua
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,7 @@ __e2setcost(5)
e2function wirelink entity:wirelink()
if not IsValid(this) then return self:throw("Invalid entity!", nil) end
if not isOwner(self, this) then return self:throw("You do not own this entity!", nil) end

if not this.extended then
WireLib.CreateWirelinkOutput( self.player, this, {true} )

This comment has been minimized.

Copy link
@Fasteroid

Fasteroid Dec 12, 2023

Contributor

why was this removed?

This comment has been minimized.

Copy link
@Denneisk

Denneisk Dec 12, 2023

Author Member

Because it seemed useless and wasteful. If you wanted a wirelink output you can create one using the Wire stool.

This comment has been minimized.

Copy link
@Fasteroid

Fasteroid Dec 12, 2023

Contributor

How am I supposed to make wirelinks via E2 now 😭

end

return this
end

Expand Down
3 changes: 0 additions & 3 deletions lua/entities/gmod_wire_expression2/core/wirelink.lua
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,6 @@ __e2setcost(5) -- temporary

--- Return E2 wirelink -- and create it if none created yet
e2function wirelink wirelink()
if not self.entity.extended then
WireLib.CreateWirelinkOutput( self.player, self.entity, {true} )
end
return self.entity
end

Expand Down
127 changes: 87 additions & 40 deletions lua/weapons/gmod_tool/stools/wire_adv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ if CLIENT then
{ name = "left_2", stage = 2, text = "Select output (Alt: Auto-connect matching input/outputs)" },
{ name = "right_2", stage = 2, text = "Next" },
{ name = "mwheel_2", stage = 2, text = "Mouse wheel: Next" },
{ name = "shift_reload", stage = 0, text = "Shift + Reload: Remove wirelink and entity outputs" }
}
for _, info in pairs(TOOL.Information) do
language.Add("Tool.wire_adv." .. info.name, info.text)
Expand Down Expand Up @@ -59,13 +60,14 @@ if SERVER then
-- Duplicator modifiers
-----------------------------------------------------------------
function WireLib.CreateWirelinkOutput( ply, ent, data )
duplicator.StoreEntityModifier(ent, "CreateWirelinkOutput", data)
if data[1] == true then
if ent.Outputs then
local names = {}
local types = {}
local descs = {}
local x = 0
for k,v in pairs( ent.Outputs ) do
for _,v in pairs( ent.Outputs ) do
x = x + 1
local num = v.Num
names[num] = v.Name
Expand All @@ -74,30 +76,26 @@ if SERVER then
descs[num] = v.Desc
end

names[x+1] = "wirelink"
types[x+1] = "WIRELINK"
descs[x+1] = ""

WireLib.AdjustSpecialOutputs( ent, names, types, descs )
WireLib.AdjustSpecialOutputs(ent, names, types, descs)
else
WireLib.CreateSpecialOutputs( ent, { "wirelink" }, { "WIRELINK" } )
end

ent.extended = true
WireLib.TriggerOutput( ent, "wirelink", ent )
end
duplicator.StoreEntityModifier( ent, "CreateWirelinkOutput", data )
end
duplicator.RegisterEntityModifier( "CreateWirelinkOutput", WireLib.CreateWirelinkOutput )

function WireLib.CreateEntityOutput( ply, ent, data )
duplicator.StoreEntityModifier(ent, "CreateEntityOutput", data)
if data[1] == true then
if ent.Outputs then
local names = {}
local types = {}
local descs = {}
local x = 0
for k,v in pairs( ent.Outputs ) do
for _,v in pairs( ent.Outputs ) do
x = x + 1
local num = v.Num
names[num] = v.Name
Expand All @@ -106,30 +104,41 @@ if SERVER then
descs[num] = v.Desc
end

names[x+1] = "entity"
types[x+1] = "ENTITY"
descs[x+1] = ""

WireLib.AdjustSpecialOutputs( ent, names, types, descs )
else
WireLib.CreateSpecialOutputs( ent, { "entity" }, { "ENTITY" } )
end

WireLib.TriggerOutput( ent, "entity", ent )
end
duplicator.StoreEntityModifier( ent, "CreateEntityOutput", data )
end
duplicator.RegisterEntityModifier( "CreateEntityOutput", WireLib.CreateEntityOutput )

local function removeWirelinkOutput(ent)
if ent.EntityMods and ent.EntityMods.CreateWirelinkOutput and ent.Outputs and ent.Outputs.wirelink then
WireLib.DisconnectOutput(ent, "wirelink")
ent.Outputs.wirelink = nil
WireLib.RemoveOutPort(ent, "wirelink")
duplicator.ClearEntityModifier(ent, "CreateWirelinkOutput")
WireLib._SetOutputs(ent)
end
end

local function removeEntityOutput(ent)
if ent.EntityMods and ent.EntityMods.CreateEntityOutput and ent.Outputs and ent.Outputs.entity then
WireLib.DisconnectOutput(ent, "entity")
ent.Outputs.entity = nil
WireLib.RemoveOutPort(ent, "entity")
duplicator.ClearEntityModifier(ent, "CreateEntityOutput")
WireLib._SetOutputs(ent)
end
end

-----------------------------------------------------------------
-- Receving data from client
-----------------------------------------------------------------

util.AddNetworkString( "wire_adv_upload" )
net.Receive( "wire_adv_upload", function( len, ply )
local wirings = net.ReadTable()

local function wireAdvUpload(ply, wirings)
local tool = WireToolHelpers.GetActiveTOOL("wire_adv",ply)
if not tool then return end

Expand Down Expand Up @@ -175,18 +184,46 @@ if SERVER then
end
end
end
end)

util.AddNetworkString( "wire_adv_unwire" )
net.Receive( "wire_adv_unwire", function( len, ply )
local ent = net.ReadEntity()
local tbl = net.ReadTable()
end

if WireLib.CanTool(ply, ent, "wire_adv" ) then
local function wireAdvUnwire(ply, ent, tbl)
if WireLib.CanTool(ply, ent, "wire_adv") then
for i=1,#tbl do
WireLib.Link_Clear( ent, tbl[i] )
end
end
end

local function wireAdvRemoveUGLinks(ply, ent)
if WireLib.CanTool(ply, ent, "wire_adv") then
if ent:IsValid() then
removeEntityOutput(ent)
removeWirelinkOutput(ent)
end
end
end

util.AddNetworkString("wire_adv_upload")
local function wireAdvReceiver(_, ply)
local flag = net.ReadUInt(8)

if flag == 1 then
wireAdvUpload(ply, net.ReadTable())
elseif flag == 2 then
wireAdvUnwire(ply, net.ReadEntity(), net.ReadTable())
elseif flag == 3 then
wireAdvRemoveUGLinks(ply, net.ReadEntity())
else
ErrorNoHalt("Tried to call wire_adv_upload without a proper message flag")
end
end
net.Receive("wire_adv_upload", wireAdvReceiver)

util.AddNetworkString("wire_adv_unwire")
net.Receive( "wire_adv_unwire", function(ply)
ErrorNoHalt("wire_adv_unwire is deprecated, use wire_adv_upload with an unsigned byte 2 at the start")

wireAdvUnwire(ply, net.ReadEntity(), net.ReadTable())
end)

WireToolHelpers.SetupSingleplayerClickHacks(TOOL)
Expand Down Expand Up @@ -220,14 +257,16 @@ elseif CLIENT then
function TOOL:Upload()
self:SanitizeUpload() -- Remove all invalid wirings before sending

net.Start( "wire_adv_upload" )
net.Start("wire_adv_upload")
net.WriteUInt(1, 8)
net.WriteTable( self.Wiring )
net.SendToServer()

self:Holster()
end
function TOOL:Unwire( ent, names )
net.Start( "wire_adv_unwire" )
net.Start("wire_adv_upload")
net.WriteUInt(2, 8)
net.WriteEntity( ent )
net.WriteTable( names )
net.SendToServer()
Expand All @@ -249,7 +288,7 @@ elseif CLIENT then
if outputs then
local found = false
for i=1,#outputs do
if outputs[i][2] == "WIRELINK" then found = true break end
if outputs[i] and outputs[i][2] == "WIRELINK" then found = true break end
end
if not found then
outputs = table.Copy(outputs) -- we don't want to modify the original table
Expand Down Expand Up @@ -658,17 +697,26 @@ elseif CLIENT then
function TOOL:Reload(trace)
if not game.SinglePlayer() and not IsFirstTimePredicted() then return end

if self:GetStage() == 0 and IsValid( trace.Entity ) and WireLib.HasPorts( trace.Entity ) then
local inputs, outputs = self:GetPorts( trace.Entity )
if not isTableEmpty(inputs) then return end
if self:GetOwner():KeyDown( IN_WALK ) then
local t = {}
for i=1,#inputs do
t[i] = inputs[i][1]
end
self:Unwire( trace.Entity, t )
local ent = trace.Entity

if self:GetStage() == 0 and ent:IsValid() and WireLib.HasPorts(ent) then
if self:GetOwner():KeyDown(IN_SPEED) then
net.Start("wire_adv_upload")
net.WriteUInt(3, 8)
net.WriteEntity(ent)
net.SendToServer()
else
self:Unwire( trace.Entity, { inputs[self.CurrentWireIndex][1] } )
local inputs = self:GetPorts(ent)
if not isTableEmpty(inputs) then return end
if self:GetOwner():KeyDown( IN_WALK ) then
local t = {}
for i=1,#inputs do
t[i] = inputs[i][1]
end
self:Unwire(ent, t)
else
self:Unwire(ent, { inputs[self.CurrentWireIndex][1] })
end
end
else
self:Holster()
Expand All @@ -686,7 +734,6 @@ elseif CLIENT then
local check = self:GetStage() == 0 and inputs or outputs
if #check == 0 then return end

local b = false
local oldport = self.CurrentWireIndex

if self:GetStage() == 2 then
Expand Down Expand Up @@ -884,7 +931,7 @@ elseif CLIENT then
return self.CurrentWireIndex == idx -- Highlight selected output
end
elseif name == "Selected" and self:GetStage() == 2 and alt then -- highlight all selected inputs that will be wired
local inputs, outputs = self:GetPorts( ent )
local _, outputs = self:GetPorts( ent )

local inputname = tbl[idx][1]
local inputtype = tbl[idx][2]
Expand Down Expand Up @@ -1246,7 +1293,7 @@ elseif CLIENT then
return (outputname == inputname and outputtype == inputtype) or (inputtype == "WIRELINK" and (outputname == "wirelink" or outputname == "Create Wirelink") and outputtype == "WIRELINK") or
(inputtype == "ENTITY" and (outputname == "entity" or outputname == "Create Entity") and outputtype == "ENTITY")
else
return (outputname == inputname and outputtype == inputtype)
return outputname == inputname and outputtype == inputtype
end
end

Expand Down
26 changes: 20 additions & 6 deletions lua/wire/server/wirelib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,25 @@ function WireLib.AdjustSpecialOutputs(ent, names, types, descs)

local ent_ports = ent.Outputs or {}

if ent_ports.wirelink then
local n = #names+1
local ent_mods = ent.EntityMods
if ent_mods then
local n = #names
if ent_mods.CreateEntityOutput then
n = n + 1

names[n] = "entity"
types[n] = "ENTITY"
end
if ent_mods.CreateWirelinkOutput then
n = n + 1

names[n] = "wirelink"
types[n] = "WIRELINK"
names[n] = "wirelink"
types[n] = "WIRELINK"
end
end


local i = 0
for n,v in ipairs(names) do
local name, desc, tp = ParsePortName(v, types[n] or "NORMAL", descs and descs[n])

Expand All @@ -352,10 +364,11 @@ function WireLib.AdjustSpecialOutputs(ent, names, types, descs)
WireLib.DisconnectOutput(ent, name)
ent_ports[name].Type = tp
end
WireLib.RemoveOutPort(ent, name)
ent_ports[name].Keep = true
ent_ports[name].Num = n
ent_ports[name].Desc = desc
else
i = i + 1
local port = {
Keep = true,
Name = name,
Expand All @@ -364,7 +377,7 @@ function WireLib.AdjustSpecialOutputs(ent, names, types, descs)
Value = WireLib.GetDefaultForType(tp),
Connected = {},
TriggerLimit = 8,
Num = n,
Num = i,
}

local idx = 1
Expand All @@ -383,6 +396,7 @@ function WireLib.AdjustSpecialOutputs(ent, names, types, descs)
port.Keep = nil
else
WireLib.DisconnectOutput(ent, portname)
WireLib.RemoveOutPort(ent, portname)
ent_ports[portname] = nil
end
end
Expand Down
11 changes: 11 additions & 0 deletions lua/wire/wireshared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,17 @@ if SERVER then
return ents_with_inputs[eid], ents_with_outputs[eid]
end

function WireLib.RemoveOutPort(ent, name)
local outputs = ents_with_outputs[ent:EntIndex()]
if outputs then
for k, v in ipairs(outputs) do
if v[1] == name then
table.remove(outputs, k)
end
end
end
end

function WireLib._RemoveWire(eid, DontSend) -- To remove the inputs without to remove the entity. Very important for IsWire checks!
local hasinputs, hasoutputs = ents_with_inputs[eid], ents_with_outputs[eid]
if hasinputs or hasoutputs then
Expand Down

0 comments on commit 95adeb4

Please sign in to comment.