Skip to content

Commit

Permalink
Merge pull request #1695 from MulleDK19/wire_tool_improvements
Browse files Browse the repository at this point in the history
Wire tool improvements
  • Loading branch information
thegrb93 authored Jul 6, 2019
2 parents b5460f8 + b37fc5b commit 93b4d18
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 11 deletions.
204 changes: 195 additions & 9 deletions lua/weapons/gmod_tool/stools/wire_adv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ if CLIENT then
language.Add( "WireTool_width", "Width:" )
language.Add( "WireTool_material", "Material:" )
language.Add( "WireTool_colour", "Colour:" )
language.Add( "WireTool_stick", "Stick to surfaces" )
TOOL.Information = {
{ name = "left_0", stage = 0, text = "Select input (Shift: Select multiple; Alt: Select all)" },
{ name = "right_0", stage = 0, text = "Next" },
{ name = "reload_0", stage = 0, text = "Unlink (Alt: Unlink all)" },
{ name = "mwheel_0", stage = 0, text = "Mouse wheel: Next" },
{ name = "left_1", stage = 1, text = "Select entity" },
{ name = "right_1", stage = 1, text = "Add wirepoint" },
{ name = "f_0", stage = 1, text = "F: Undo wirepoint" },
{ name = "reload_1", stage = 1, text = "Cancel" },
{ name = "left_2", stage = 2, text = "Select output (Alt: Auto-connect matching input/outputs)" },
{ name = "right_2", stage = 2, text = "Next" },
Expand All @@ -42,9 +44,12 @@ TOOL.ClientConVar = {
r = 255,
g = 255,
b = 255,
stick = 1
}

util.PrecacheSound("weapons/pistol/pistol_empty.wav")
util.PrecacheSound("buttons/lightswitch2.wav")
util.PrecacheSound("buttons/button16.wav")

local function get_active_tool(ply, tool)
-- find toolgun
Expand Down Expand Up @@ -412,6 +417,85 @@ elseif CLIENT then
function TOOL:AutoWiringTypeLookup_Check( inputtype )
return self.AutoWiringTypeLookup_t[inputtype]
end

-- Updates the trace hit position and normal to the surface of the parent, perpendicular to the originally hit entity.
-- As not all models have the same forward, up, etc. it checks all directions perpendicular to the hit entity, until it finds the parent.
-- If the parent is not found in any perpendicular direction, it traces the parent in the direction of the tool gun.
function TOOL:UpdateTraceForSurface(trace, parent)
if self:GetClientNumber("stick") == 0 then return end
if not WireLib.HasPorts(trace.Entity) then return end

local hitParentPos
local hitParentNormal
local foundParent
local closestDistanceSquared

local entityUp = trace.Entity:GetUp() * 1000
local entityForward = trace.Entity:GetForward() * 1000
local entityRight = trace.Entity:GetRight() * 1000
local traceVectors =
{
entityUp,
entityForward,
entityRight,
-entityUp,
-entityForward,
-entityRight
}

-- Looks for the parent on all local axes, and returns the closest hit surface on the parent.
local function findParent()
foundParent = false
closestDistanceSquared = math.huge

for i = 1, 6 do
local traceVector = traceVectors[i]

local traceData = util.GetPlayerTrace(LocalPlayer())
traceData.start = trace.HitPos -- Start from the original trace.

traceData.endpos = trace.HitPos + traceVector
traceData.filter = { LocalPlayer(), trace.Entity }
traceData.collisiongroup = LAST_SHARED_COLLISION_GROUP
local newTrace = util.TraceLine(traceData)

if newTrace.Hit and newTrace.Entity == parent then
local distanceSquared = newTrace.HitPos:DistToSqr(trace.HitPos)
if distanceSquared <= 75 * 75 and distanceSquared < closestDistanceSquared then
closestDistanceSquared = distanceSquared
hitParentPos = newTrace.HitPos
hitParentNormal = newTrace.HitNormal
foundParent = true
end
end
end
end

if IsValid(parent) then
findParent()
end

if not foundParent then
-- Didn't find the parent in any direction, treat whichever entity can be traced behind the entity as the parent.
-- This can happen if eg. the component is not directly on the parent (or if the entity just never had an actual parent).
local traceData = util.GetPlayerTrace(LocalPlayer())
traceData.filter = { LocalPlayer(), trace.Entity }
traceData.collisiongroup = LAST_SHARED_COLLISION_GROUP
newTrace = util.TraceLine(traceData)
parent = newTrace.Entity
if not IsValid(parent) or parent == game.GetWorld() then
-- Hit the world, don't update the trace.
return
end

findParent() -- Try again with the new assumed parent.
end

if foundParent then
trace.HitPos = hitParentPos
trace.HitNormal = hitParentNormal
end
end

-----------------------------------------------------------------
-- Mouse buttons
Expand All @@ -427,6 +511,9 @@ elseif CLIENT then

if IsValid( trace.Entity ) then
if self:GetStage() == 0 then
self:UpdateTraceForSurface(trace, trace.Entity:GetParent())
self:BeginRenderingCurrentWire()

local inputs, _ = self:GetPorts( trace.Entity )
if not inputs then return end

Expand All @@ -448,6 +535,7 @@ elseif CLIENT then

return
elseif self:GetStage() == 1 then
self:UpdateTraceForSurface(trace, trace.Entity:GetParent())
local _, outputs = self:GetPorts( trace.Entity )
if not outputs then return end

Expand Down Expand Up @@ -555,19 +643,22 @@ elseif CLIENT then
self:SetStage(0)
self.WiringRender = {} -- Empty this now so the HUD doesn't glitch
self:GetOwner():EmitSound( "weapons/airboat/airboat_gun_lastshot" .. math.random(1,2) .. ".wav" )
self:StopRenderingCurrentWire()
end
end

function TOOL:RightClick(trace)
if self.wtfgarry > CurTime() then return end
self.wtfgarry = CurTime() + 0.1

self:UpdateTraceForSurface(trace, trace.Entity:GetParent())
if self:GetStage() == 0 or self:GetStage() == 2 then
self:ScrollDown(trace)
elseif IsValid(trace.Entity) and self:GetStage() == 1 then
for i=1,#self.Wiring do
self:WireNode( self.Wiring[i], trace.Entity, trace.HitPos + trace.HitNormal*(self:GetClientNumber("width")/2) )
end
self:GetOwner():EmitSound("buttons/lightswitch2.wav")
end
end

Expand All @@ -591,6 +682,7 @@ elseif CLIENT then
self:Holster()
end

self:StopRenderingCurrentWire()
self:GetOwner():EmitSound( "weapons/airboat/airboat_gun_lastshot" .. math.random(1,2) .. ".wav" )
end

Expand Down Expand Up @@ -648,18 +740,40 @@ elseif CLIENT then
if not self then return end

return self:ScrollUp(ply:GetEyeTraceNoCursor())
elseif bind == "impulse 100" and ply:KeyDown( IN_SPEED ) then
local self = get_active_tool(ply, "wire_adv")
if not self then
self = get_active_tool(ply, "wire_debugger")
if not self then return end
elseif bind == "impulse 100" then
if ply:KeyDown( IN_SPEED ) then
local self = get_active_tool(ply, "wire_adv")
if not self then
self = get_active_tool(ply, "wire_debugger")
if not self then return end

spawnmenu.ActivateTool( "wire_adv") -- switch back to wire adv
return true
end

spawnmenu.ActivateTool( "wire_adv") -- switch back to wire adv
spawnmenu.ActivateTool("wire_debugger") -- switch to debugger
return true
end
else
local self = get_active_tool(ply, "wire_adv")
if self and self:GetStage() == 1 then
local len = #self.Wiring
if len > 0 then
local nodesCount = 0
for i=1,len do
nodesCount = nodesCount + #self.Wiring[i][4]
if #self.Wiring[i][4] > 0 then
table.remove(self.Wiring[i][4])
end
end

spawnmenu.ActivateTool("wire_debugger") -- switch to debugger
return true
if nodesCount > 0 then
self:GetOwner():EmitSound( "buttons/button16.wav" )
end
end
return true
end
return true
end
end
end

Expand Down Expand Up @@ -982,6 +1096,76 @@ elseif CLIENT then
end
end

function TOOL:StopRenderingCurrentWire()
hook.Remove("PostDrawOpaqueRenderables", "Wire.ToolWireRenderHook")
self.IsRenderingCurrentWire = false;
Wire_GrayOutWires = false
end

function TOOL:BeginRenderingCurrentWire()
if self.IsRenderingCurrentWire then return end
self.IsRenderingCurrentWire = true
Wire_GrayOutWires = true
hook.Add("PostDrawOpaqueRenderables", "Wire.ToolWireRenderHook", function()
-- Draw the wire path
render.SetColorMaterial()
for i=1, #self.Wiring do
local wiring = self.Wiring[i]
local nodes = wiring[4]
local outputEntity = wiring[5]

local color = Color(self:GetClientNumber("r"), self:GetClientNumber("g"), self:GetClientNumber("b"))
local matName = self:GetClientInfo("material")
local width = self:GetClientInfo("width")
local mat = Material(matName)
local theEnt = wiring[3]
if not theEnt:IsValid() then
break
end

local start = theEnt:LocalToWorld(wiring[2])

local scroll = 0.5
render.SetMaterial(mat)
render.StartBeam((#nodes*2)+1+1+1) -- + startpoint + same as last node (to not have transition to aiming point) +point where player is aiming
render.AddBeam(start, width, scroll, color)

for j=1, #nodes do
local node = nodes[j]

local nodeEnt = node[1]
local nodeOffset = node[2]
local nodePosition = nodeEnt:LocalToWorld(nodeOffset)

scroll = scroll+(nodePosition-start):Length()/10
render.AddBeam(nodePosition, width, scroll, color)
render.AddBeam(nodePosition, width, scroll, color)

start = nodePosition
end

render.AddBeam(start, width, scroll, Color(255,255,255,255))

if not IsValid(outputEntity) then
local traceData = util.GetPlayerTrace(LocalPlayer())
traceData.filter = { LocalPlayer() }

traceData.collisiongroup = LAST_SHARED_COLLISION_GROUP
local traceResult = util.TraceLine(traceData)
if WireLib.HasPorts(traceResult.Entity) then
self:UpdateTraceForSurface(traceResult, traceResult.Entity:GetParent())
end
render.AddBeam(traceResult.HitPos, width, scroll+(traceResult.HitPos-start):Length()/10, Color(100,100,100,255))
else
local outputPos = wiring[6]
outputPos = outputEntity:LocalToWorld(outputPos)
render.AddBeam(outputPos, width, scroll+(outputPos-start):Length()/10, Color(100,100,100,255))
end
render.EndBeam()
end
end)
end


-----------------------------------------------------------------
-- Wiring Render
Expand Down Expand Up @@ -1046,6 +1230,8 @@ elseif CLIENT then
Green = "wire_adv_g",
Blue = "wire_adv_b"
})

panel:CheckBox("#WireTool_stick", "wire_adv_stick")
end

end
12 changes: 10 additions & 2 deletions lua/wire/client/cl_wirelib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local WIRE_SCROLL_SPEED = 0.5
local WIRE_BLINKS_PER_SECOND = 2
local CurPathEnt = {}
local Wire_DisableWireRender = 0
Wire_GrayOutWires = false

WIRE_CLIENT_INSTALLED = 1

Expand Down Expand Up @@ -56,12 +57,18 @@ function Wire_Render(ent)
local start = wiretbl.StartPos
if (ent:IsValid()) then start = ent:LocalToWorld(start) end
local color = wiretbl.Color
if Wire_GrayOutWires then
local h, s, v = ColorToHSV(color)
v = 0.175
local tmpColor = HSVToColor(h, s, v)
color = Color(tmpColor.r, tmpColor.g, tmpColor.b, tmpColor.a) -- HSVToColor does not return a proper Color structure.
end

local nodes = wiretbl.Path
local len = #nodes
if len>0 then
render.SetMaterial(getmat(wiretbl.Material))
render.StartBeam(len+1)
render.StartBeam(len * 2 + 1)
render.AddBeam(start, width, scroll, color)

for j=1, len do
Expand All @@ -72,6 +79,7 @@ function Wire_Render(ent)

scroll = scroll+(endpos-start):Length()/10
render.AddBeam(endpos, width, scroll, color)
render.AddBeam(endpos, width, scroll, color) -- A second beam in the same position ensures the line stays consistent and doesn't change width/become distorted.

start = endpos
end
Expand Down Expand Up @@ -242,4 +250,4 @@ function WireLib.hud_debug(text, oneframe)
if oneframe then hook.Remove("HUDPaint","wire_hud_debug") end
draw.DrawText(text,"Trebuchet24",10,200,Color(255,255,255,255),0)
end)
end
end

0 comments on commit 93b4d18

Please sign in to comment.