rewrite linker as a gmod_tool

This commit is contained in:
shadowscion 2023-01-17 16:13:49 -06:00
parent f012925687
commit 36477416e1
5 changed files with 836 additions and 28 deletions

View File

@ -7,8 +7,8 @@ AddCSLuaFile()
DEFINE_BASECLASS( "base_anim" )
ENT.Type = "anim"
ENT.Spawnable = true
ENT.AdminOnly = false
ENT.Spawnable = false
ENT.AdminOnly = true
ENT.Category = "tanktracktool"
local tanktracktool = tanktracktool

View File

@ -10,9 +10,9 @@ ENT.Category = "tanktracktool"
local tanktracktool = tanktracktool
ENT.tanktracktool_linkerData = {
{ name = "Entity1", bind = { KEY_E } },
{ name = "Entity2", bind = { KEY_E } },
ENT.tanktracktool_linkData = {
{ name = "Entity1", tool_bind = 2 },
{ name = "Entity2", tool_bind = 3 },
}
function ENT:netvar_setLinks( tbl, ply )

View File

@ -6,8 +6,8 @@ local net, hook, util, math, string, table, surface, draw, scripted_ents, Entity
tanktracktool.linker = tanktracktool.linker or {}
local linker = tanktracktool.linker
function linker.openUI( ent )
linker.TOOL:Init( ent )
function linker.openUI( ent, toolmode )
linker.TOOL:Init( ent, toolmode )
end
@ -19,13 +19,16 @@ linker.TOOL = {}
linker.TOOL.HookName = "tanktracktoolLinker"
linker.TOOL.Colors = {}
linker.TOOL.Colors.line_link = Color( 236, 240, 241, 50 )
linker.TOOL.Colors.line_link = Color( 236, 240, 241, 30 )
linker.TOOL.Colors.text_link = Color( 236, 240, 241 )
linker.TOOL.Colors.text_send = Color( 125, 255, 125, 255 )
linker.TOOL.Colors.text_keys = Color( 255, 125, 125, 255 )
linker.TOOL.Colors.text_send = Color( 202, 255, 191, 255 )
linker.TOOL.Colors.text_keys = Color( 255, 214, 165, 255 )
linker.TOOL.Colors.bbox = Color( 255, 255, 255, 50 )
linker.TOOL.Colors.font_small = "Trebuchet18"
linker.TOOL.Colors.font_large = "Trebuchet24"
linker.TOOL.Colors.font_small = "tanktracktoolLinker_16"
linker.TOOL.Colors.font_large = "tanktracktoolLinker_32"
surface.CreateFont( linker.TOOL.Colors.font_small, { font = "Consolas", size = 16, weight = 200, shadow = false })
surface.CreateFont( linker.TOOL.Colors.font_large, { font = "Consolas", size = 32, weight = 200, shadow = false })
linker.TOOL.Sounds = {}
linker.TOOL.Sounds.Enabled = true
@ -40,7 +43,7 @@ hook.Remove( "PlayerBindPress", linker.TOOL.HookName )
local function KeyPress( ply, bind, pressed, code ) return linker.TOOL:KeyPress( bind, code, ply ) end
local function Paint() return linker.TOOL:Paint() end
local function FormatText( self, v )
local function FormatText( self, v, alias )
if not v.bind then return end
local text = {}
@ -49,7 +52,7 @@ local function FormatText( self, v )
for i = 1, #v.bind do
table.insert( text, self.Colors.text_keys )
table.insert( text, string.upper( language.GetPhrase( input.GetKeyName( v.bind[i] ) ) ) )
table.insert( text, alias and alias[v.bind[i]] or string.upper( language.GetPhrase( input.GetKeyName( v.bind[i] ) ) ) )
if i < #v.bind then
table.insert( text, self.Colors.text_link )
@ -84,10 +87,23 @@ function linker.TOOL:Confirm()
self:Exit( true )
end
function linker.TOOL:Init( ent )
function linker.TOOL:ConfirmCopy( e )
net.Start( "tanktracktool_link" )
net.WriteUInt( self.Data.Controller:EntIndex(), 16 )
net.WriteUInt( 2, 2 )
net.WriteUInt( e:EntIndex(), 16 )
net.SendToServer()
self:PlaySound( self.Sounds.Confirm )
self:Exit( true )
end
function linker.TOOL:Init( ent, toolmode )
self:Exit( true )
self.Data = {}
local alias = toolmode and { [KEY_E] = "Right Click", [KEY_C] = "Left Click" }
self.Data = { toolmode = toolmode }
self.Data.Time = SysTime()
self.Data.Linker = table.Copy( ent.tanktracktool_linkerData )
self.Data.Sender_Lookup = {}
@ -98,31 +114,39 @@ function linker.TOOL:Init( ent )
{ self.Colors.text_send, "Controller" },
{
self.Colors.text_link, "Press ",
self.Colors.text_keys, string.upper( language.GetPhrase( input.GetKeyName( KEY_R ) ) ),
self.Colors.text_keys, alias and alias[KEY_R] or string.upper( language.GetPhrase( input.GetKeyName( KEY_R ) ) ),
self.Colors.text_link, " to cancel",
}
}
}
self.Data.ConfirmText = {
self.Colors.text_link, "Press ",
self.Colors.text_keys, string.upper( language.GetPhrase( input.GetKeyName( KEY_E ) ) ),
self.Colors.text_keys, alias and alias[KEY_E] or string.upper( language.GetPhrase( input.GetKeyName( KEY_E ) ) ),
self.Colors.text_link, " to confirm",
}
self.Data.CopyText = {
self.Colors.text_link, "Press ",
self.Colors.text_keys, alias and alias[KEY_C] or string.upper( language.GetPhrase( input.GetKeyName( KEY_C ) ) ),
self.Colors.text_link, " to copy controller values",
}
for _, v in pairs( self.Data.Linker ) do
if v.name then
v.text = FormatText( self, v )
v.text = FormatText( self, v, alias )
else
for _, v in pairs( v ) do
v.text = FormatText( self, v )
v.text = FormatText( self, v, alias )
self.Data.Sender_Lookup[v.name] = {}
self.Data.Sender_Table[v.name] = {}
end
end
end
hook.Add( "HUDPaint", self.HookName, Paint )
hook.Add( "PlayerBindPress", self.HookName, KeyPress )
if not toolmode then
hook.Add( "HUDPaint", self.HookName, Paint )
hook.Add( "PlayerBindPress", self.HookName, KeyPress )
end
self:PlaySound( self.Sounds.Open )
end
@ -144,6 +168,56 @@ function linker.TOOL:CheckDoubleKey()
end
end
function linker.TOOL:KeyPressTool( tool, tr, keys )
if not IsValid( self.Data.Controller ) or ( keys[KEY_R] and not self:CheckDoubleKey() ) then
self:Exit()
return true
end
local e2 = tr.Entity
if e2 == self.Data.Controller and ( keys[KEY_E] and not self:CheckDoubleKey() ) then
self:Confirm()
return true
end
local id, command = next( self.Data.Linker )
if not id or not command then
return
end
if command.name then
local isdown = true
for i, key in pairs( command.bind or {} ) do
if not keys[key] then
isdown = false
break
end
end
if isdown then
self:SetupLink( id, command )
return true
end
else
for i, subcommand in ipairs( command ) do
local isdown = true
for _, key in pairs( subcommand.bind or {} ) do
if not keys[key] then
isdown = false
break
end
end
if isdown then
self:SetupLink( id, subcommand, i )
return true
end
end
end
end
function linker.TOOL:KeyPress( bind, code )
if not IsValid( self.Data.Controller ) or ( input.IsKeyDown( KEY_R ) and not self:CheckDoubleKey() ) then
self:Exit()
@ -156,6 +230,11 @@ function linker.TOOL:KeyPress( bind, code )
return true
end
if e2 ~= self.Data.Controller and e2:GetClass() == self.Data.Controller:GetClass() and ( input.IsKeyDown( KEY_C ) and not self:CheckDoubleKey() ) then
self:ConfirmCopy( e2 )
return true
end
local id, command = next( self.Data.Linker )
if not id or not command then
return
@ -275,6 +354,8 @@ local function ColoredText( p0, p1, frac, line, font, t )
end
end
linker.TOOL.Colors.DrawText = ColoredText
function linker.TOOL:Paint()
if not IsValid( self.Data.Controller ) then
self:Exit()
@ -294,11 +375,14 @@ function linker.TOOL:Paint()
end
local p2 = ent:GetPos():ToScreen()
local y = #texts * sh * 0.5
-- local lx = p1.x + ( p2.x - p1.x ) * 0.9
-- local ly = p1.y + ( p2.y - p1.y ) * 0.9
surface.SetDrawColor( self.Colors.line_link )
surface.DrawLine( p1.x, p1.y, p2.x, p2.y )
local y = #texts * sh * 0.5
--surface.DrawRect( lx - 2, ly - 2, 4, 4 )
for i, text in ipairs( texts ) do
ColoredText( { x = p2.x, y = p2.y + ( i - 1 ) * sh - y }, nil, nil, nil, self.Colors.font_small, text )
@ -314,7 +398,12 @@ function linker.TOOL:Paint()
cam.End3D()
if e2 == e1 then
ColoredText( { x = p1.x, y = p1.y + sh }, nil, nil, nil, self.Colors.font_large, self.Data.ConfirmText )
ColoredText( { x = p1.x, y = p1.y + sh }, nil, nil, nil, self.Colors.font_small, self.Data.ConfirmText )
return
end
if e2:GetClass() == e1:GetClass() then
ColoredText( e2:GetPos():ToScreen(), nil, nil, nil, self.Colors.font_large, self.Data.CopyText )
return
end

View File

@ -90,6 +90,14 @@ if SERVER then
tanktracktool.note( string.format( "receiving link update\nply: %s\nent: %s\n", tostring( ply ), tostring( ent ) ) )
end
elseif type == 2 then
if not netvar.canEdit( ent, ply ) then return end
print( "copy to", ent, "from", Entity( net.ReadUInt( 16 ) ) )
-- if tanktracktool.loud( tanktracktool.loud_link ) then
-- tanktracktool.note( string.format( "receiving link update\nply: %s\nent: %s\n", tostring( ply ), tostring( ent ) ) )
-- end
end
end )
@ -520,13 +528,12 @@ end
function tanktracktool.netvar.setLinks( ent, tbl, ply )
if not netvar.isValid( ent ) then return false end
--if not istable( tbl ) or not table.IsSequential( tbl ) then return false end
if not istable( tbl ) then return false end
local entities = {}
for k, v in pairs( tbl ) do
if not IsValid( v ) then return false end
if ply and not netvar.canLink( ent, ply ) then return false end
if not isentity( v ) or not IsValid( v ) then return false end
if ply and not netvar.canLink( v, ply ) then return false end
entities[k] = v
end

View File

@ -0,0 +1,712 @@
TOOL.Category = "Construction"
TOOL.Name = "#tool.tanktracktool.listname"
--[[
mostly clientside stool base using the rest of the tanktracktool lib
]]
local cam, net, ents, math, util, draw, hook, halo, surface, render, language =
cam, net, ents, math, util, draw, hook, halo, surface, render, language
local tanktracktool = tanktracktool
if SERVER then
util.AddNetworkString( "tanktracktool_stool" )
else
language.Add( "tool.tanktracktool.listname", "Tank Track Tool" )
language.Add( "tool.tanktracktool.name", "Tank Track Tool" )
language.Add( "tool.tanktracktool.desc", "Spawn and modify controllers" )
end
function TOOL:LeftClick( tr )
if not tr.Hit then return false end
if SERVER then
net.Start( "tanktracktool_stool" )
net.WriteUInt( 0, 2 )
net.Send( self:GetOwner() )
end
return true
end
function TOOL:RightClick( tr )
if not tr.Hit then return false end
if SERVER then
net.Start( "tanktracktool_stool" )
net.WriteUInt( 1, 2 )
net.Send( self:GetOwner() )
end
return true
end
function TOOL:Reload( tr )
if not tr.Hit then return false end
if SERVER then
net.Start( "tanktracktool_stool" )
net.WriteUInt( 2, 2 )
net.Send( self:GetOwner() )
end
return true
end
if SERVER then return end
--[[
multitool base
]]
local multitool = { modes = {} }
TOOL.Information = {}
local function AddInformation( name, icon, text, stage, op )
table.insert( TOOL.Information, { name = name, icon = icon, text = text, stage = stage, op = op } )
language.Add( string.format( "tool.tanktracktool.%s", name ), text )
end
AddInformation( "reset", "materials/gui/r.png", "Reset the tool at any time" )
function TOOL:SetOperation( i ) self._operation = i end
function TOOL:GetOperation() return self._operation or 0 end
function TOOL:SetStage( i ) self._stage = i end
function TOOL:GetStage() return self._stage or 0 end
function TOOL:DrawHUD()
multitool:draw( self, LocalPlayer() )
end
function TOOL:Think()
multitool:update( self, LocalPlayer() )
end
net.Receive( "tanktracktool_stool", function()
local t = LocalPlayer():GetTool()
if not t or t.Mode ~= "tanktracktool" then return end
local k = net.ReadUInt( 2 )
multitool:keyPress( t, t:GetOwner(), k )
end )
concommand.Add( "tanktracktool_multitool_reset", function()
if multitool then multitool:reset() end
end )
--[[
multitool methods
]]
function multitool:reset()
multitool.mode = nil
end
function multitool:setMode( gmod_tool, ply, mode, ... )
if not self.modes[mode] then mode = "wait" end
if self.modes[mode].init then
gmod_tool:SetStage( 0 )
gmod_tool:SetOperation( 0 )
self.modes[mode]:init( gmod_tool, ply, self.mode, ... )
self.mode = mode
end
end
function multitool:draw( gmod_tool, ply )
if not self.modes[self.mode] then
self:setMode( gmod_tool, ply, "wait" )
return
end
if self.modes[self.mode] and self.modes[self.mode].draw then
self.modes[self.mode]:draw( gmod_tool, ply )
end
end
function multitool:update( gmod_tool, ply )
if not self.modes[self.mode] then
self:setMode( gmod_tool, ply, "wait" )
return
end
if self.modes[self.mode] and self.modes[self.mode].update then
self.modes[self.mode]:update( gmod_tool, ply )
end
end
function multitool:keyPress( gmod_tool, ply, key )
if not self.modes[self.mode] then
self:setMode( gmod_tool, ply, "wait" )
return
end
if self.modes[self.mode] and self.modes[self.mode].keyPress then
self.modes[self.mode]:keyPress( gmod_tool, ply, key )
end
end
function multitool:getLinkableInfo( ent )
return table.Copy( ent.tanktracktool_linkData )
end
function multitool:isLinkable( ent )
return IsValid( ent ) and istable( ent.tanktracktool_linkData )
end
function multitool:isCopyable( ent1, ent2 )
if ent2 then
if ent1 == ent2 then return false end
if not IsValid( ent1 ) or ent1.netvar == nil then return false end
if not IsValid( ent2 ) or ent2.netvar == nil then return false end
if ent1:GetClass() ~= ent2:GetClass() then return false end
return true
end
return IsValid( ent1 ) and ent1.netvar ~= nil
end
function multitool:findEntities( ply, dist, ang, class )
local e = {}
local f = ents.FindInCone( ply:EyePos(), ply:GetAimVector(), dist, math.cos( math.rad( ang ) ) )
for i = 1, #f do
local v = f[i]
if v.netvar and ( not class or v:GetClass() == class ) then e[#e + 1] = v end
end
return #e > 0 and e or nil
end
--[[
HUD stuff
]]
local function rgb( color, a )
return Color( color.r / 255, color.g / 255, color.b / 255, a )
end
multitool.ui = {}
multitool.ui.colors = {}
multitool.ui.colors.text_class = Color( 255, 200, 0 )
multitool.ui.colors.text_keyword = Color( 0, 255, 255 )
multitool.ui.colors.text_input = Color( 0, 255, 0 )
multitool.ui.colors.text_plain = Color( 255, 255, 255 )
multitool.ui.colors.text_box = Color( 0, 0, 0, 100 )
multitool.ui.colors.ents_bbox = Color( 255, 255, 255, 30 )
multitool.ui.colors.ents_possible = rgb( multitool.ui.colors.text_plain, 0.111 )
multitool.ui.colors.ents_selected = rgb( multitool.ui.colors.text_class, 0.333 )
multitool.ui.colors.ents_hovered = rgb( multitool.ui.colors.text_keyword, 0.333 )
multitool.ui.fonts = {}
multitool.ui.fonts.small = "tanktracktool_stool0"
multitool.ui.fonts.large = "tanktracktool_stool1"
surface.CreateFont( multitool.ui.fonts.small, { font = "Comic Sans MS", size = 24, weight = 100, shadow = false } )
surface.CreateFont( multitool.ui.fonts.large, { font = "Comic Sans MS", size = 30, weight = 100, shadow = false } )
function multitool:renderModel( ent, color )
if not IsValid( ent ) then return end
if not IsValid( self.csent ) then
self.csent = ClientsideModel( "models/error.mdl" )
self.csent:SetNoDraw( true )
self.csent:SetMaterial( "models/debug/debugwhite" )
end
cam.Start3D()
render.SuppressEngineLighting( true )
render.SetBlend( color.a )
render.SetColorModulation( color.r, color.g, color.b )
self.csent:SetModel( ent:GetModel() )
self.csent:SetPos( ent:GetPos() )
self.csent:SetAngles( ent:GetAngles() )
self.csent:SetupBones()
self.csent:DrawModel()
render.SetBlend( 1 )
render.SetColorModulation( 1, 1, 1 )
render.SuppressEngineLighting( false )
local min, max = ent:GetRenderBounds()
render.DrawWireframeBox( ent:GetPos(), ent:GetAngles(), min, max, multitool.ui.colors.ents_bbox )
cam.End3D()
end
local function GetTextSize( text, font )
surface.SetFont( font )
local w, h = surface.GetTextSize( text )
return { w = w, h = h }
end
local function DrawOverlay( x, y, overlay )
local w, h = 0, 0
for i = 1, #overlay do
local ui = overlay[i]
if ui.enabled then
y = y - ( ui.size.h ) * 2
w = math.max( w, ui.size.w )
h = h + ui.size.h
end
end
x = x - w * 0.5
draw.RoundedBox( 8, x - 8, y - 8, w + 16, h + 16, multitool.ui.colors.text_box )
for i = 1, #overlay do
local ui = overlay[i]
if not overlay[i].enabled then goto CONTINUE end
surface.SetFont( ui.font )
surface.SetTextColor( color_black )
for ox = -1, 1 do
for oy = -1, 1 do
surface.SetTextPos( x + ox, y + oy )
surface.DrawText( ui.text )
end
end
surface.SetTextPos( x, y )
for j = 1, #ui.draw.text do
surface.SetTextColor( ui.draw.cols[j] )
surface.DrawText( ui.draw.text[j] )
end
y = y + ui.size.h
::CONTINUE::
end
end
local function GetOverlay( overlay )
for k, v in ipairs( overlay ) do
v.text = table.concat( v.draw.text, "" )
v.size = GetTextSize( v.text, v.font )
v.enabled = false
end
return overlay
end
--[[
wait mode
]]
do
AddInformation( "wait_look", "materials/icon16/eye.png", "Look at a controller to begin", 0, 0 )
AddInformation( "wait_copy", "materials/gui/lmb.png", "Copy values from this controller", 1, 0 )
AddInformation( "wait_link", "materials/gui/rmb.png", "Start linking entities to this controller", 1, 0 )
multitool.modes.wait = {}
local overlay = GetOverlay( {
{
font = multitool.ui.fonts.small,
draw = {
text = {
"",
},
cols = {
multitool.ui.colors.text_class,
},
},
},
{
font = multitool.ui.fonts.small,
draw = {
text = {
"Left Click ",
"to ",
"copy values ",
"from this controller",
},
cols = {
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_keyword,
multitool.ui.colors.text_plain,
},
},
},
{
font = multitool.ui.fonts.small,
draw = {
text = {
"Right Click ",
"to start ",
"linking entities ",
"to this controller",
},
cols = {
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_keyword,
multitool.ui.colors.text_plain,
},
},
},
} )
function multitool.modes.wait:init( gmod_tool, ply, prevmode, ... )
overlay[1].enabled = false
overlay[2].enabled = false
overlay[3].enabled = false
end
function multitool.modes.wait:keyPress( gmod_tool, ply, key )
if key == 2 then return multitool:reset() end
if IsValid( self.LookAt ) then
if multitool:isCopyable( self.LookAt ) and key == 0 then
multitool:setMode( gmod_tool, ply, "copy", self.LookAt )
return
end
if multitool:isLinkable( self.LookAt ) and key == 1 then
multitool:setMode( gmod_tool, ply, "link", self.LookAt )
return
end
end
end
function multitool.modes.wait:update( gmod_tool, ply )
local tr = ply:GetEyeTrace()
if tanktracktool.netvar.isValid( tr.Entity ) then
overlay[1].enabled = true
overlay[2].enabled = multitool:isCopyable( tr.Entity )
overlay[3].enabled = multitool:isLinkable( tr.Entity )
self.LookAt = tr.Entity
gmod_tool:SetStage( 1 )
else
overlay[1].enabled = false
overlay[2].enabled = false
overlay[3].enabled = false
self.LookAt = nil
gmod_tool:SetStage( 0 )
end
self.Ents = multitool:findEntities( ply, 200, 45 )
end
function multitool.modes.wait:draw( gmod_tool, ply )
if self.Ents then
for i = 1, #self.Ents do
local v = self.Ents[i]
if v == self.LookAt then
goto CONTINUE
end
multitool:renderModel( self.Ents[i], multitool.ui.colors.ents_possible )
::CONTINUE::
end
end
if IsValid( self.LookAt ) then
multitool:renderModel( self.LookAt, multitool.ui.colors.ents_hovered )
local pos = self.LookAt:GetPos():ToScreen()
local x = pos.x
local y = pos.y
local class = self.LookAt:GetClass()
overlay[1].text = class
overlay[1].size = GetTextSize( class, overlay[1].font )
overlay[1].draw.text[1] = class
DrawOverlay( x, y, overlay )
end
end
end
--[[
copy mode
]]
do
AddInformation( "copy_look", "materials/icon16/eye.png", "Look at another controller to begin", 0, 1 )
AddInformation( "copy_to", "materials/gui/lmb.png", "+ Shift to paste values to this controller", 1, 1 )
multitool.modes.copy = {}
local overlay = GetOverlay( {
{
font = multitool.ui.fonts.small,
draw = {
text = {
"",
},
cols = {
multitool.ui.colors.text_class,
},
},
},
{
font = multitool.ui.fonts.small,
draw = {
text = {
"Left Click ",
"and ",
"Shift ",
"to ",
"paste values ",
"to this controller",
},
cols = {
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_keyword,
multitool.ui.colors.text_plain,
},
},
},
} )
function multitool.modes.copy:init( gmod_tool, ply, prevmode, ent )
self.CopyFrom = ent
if not IsValid( self.CopyFrom ) then
multitool:reset()
return
end
overlay[1].enabled = true
overlay[2].enabled = true
gmod_tool:SetOperation( 1 )
end
function multitool.modes.copy:update( gmod_tool, ply )
if not IsValid( self.CopyFrom ) then
multitool:reset()
return
end
local tr = ply:GetEyeTrace()
if not IsValid( tr.Entity ) or not multitool:isCopyable( self.CopyFrom, tr.Entity ) then
self.LookAt = nil
gmod_tool:SetStage( 0 )
else
self.LookAt = tr.Entity
gmod_tool:SetStage( 1 )
end
self.Ents = multitool:findEntities( ply, 200, 45, self.CopyFrom:GetClass() )
end
function multitool.modes.copy:draw( gmod_tool, ply )
if not IsValid( self.CopyFrom ) then return end
if self.Ents then
for i = 1, #self.Ents do
local v = self.Ents[i]
if v == self.CopyFrom or v == self.LookAt then
goto CONTINUE
end
multitool:renderModel( v, multitool.ui.colors.ents_possible )
::CONTINUE::
end
end
multitool:renderModel( self.CopyFrom, multitool.ui.colors.ents_selected )
if IsValid( self.LookAt ) then
multitool:renderModel( self.LookAt, multitool.ui.colors.ents_hovered )
local pos = self.LookAt:GetPos():ToScreen()
local x = pos.x
local y = pos.y
local class = self.LookAt:GetClass()
overlay[1].text = class
overlay[1].size = GetTextSize( class, overlay[1].font )
overlay[1].draw.text[1] = class
DrawOverlay( x, y, overlay )
end
end
function multitool.modes.copy:keyPress( gmod_tool, ply, key )
if key == 2 then return multitool:reset() end
if key == 0 and ply:KeyDown( IN_SPEED ) then
if IsValid( self.CopyFrom ) and IsValid( self.LookAt ) then
if multitool:isCopyable( self.CopyFrom, self.LookAt ) then
net.Start( "tanktracktool_link" )
net.WriteUInt( self.LookAt:EntIndex(), 16 )
net.WriteUInt( 2, 2 )
net.WriteUInt( self.CopyFrom:EntIndex(), 16 )
net.SendToServer()
end
return multitool:reset()
end
end
end
end
--[[
link mode
]]
do
AddInformation( "link_look", "materials/icon16/eye.png", "Look at another entity to begin", 0, 2 )
AddInformation( "link_set", "materials/gui/rmb.png", "Link this entity to selected controller", 1, 2 )
multitool.modes.link = {}
local overlay = GetOverlay( {
{
font = multitool.ui.fonts.small,
draw = {
text = {
"",
},
cols = {
multitool.ui.colors.text_class,
},
},
},
{
font = multitool.ui.fonts.small,
draw = {
text = {
"Right Click ",
"to ",
"link this ",
"entity as ",
"",
},
cols = {
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_keyword,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_class,
},
},
},
{
font = multitool.ui.fonts.small,
draw = {
text = {
"Right Click ",
"and ",
"Shift ",
"to ",
"link this ",
"entity as ",
"",
},
cols = {
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_input,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_keyword,
multitool.ui.colors.text_plain,
multitool.ui.colors.text_class,
},
},
},
} )
function multitool.modes.link:init( gmod_tool, ply, prevmode, ent )
self.LinkTo = ent
if not IsValid( self.LinkTo ) or not multitool:isLinkable( self.LinkTo ) then
multitool:reset()
return
end
self.Data = {}
self.Data.Send = {}
self.Data.Info = multitool:getLinkableInfo( self.LinkTo )
self:updateOverlays()
gmod_tool:SetOperation( 2 )
end
function multitool.modes.link:update( gmod_tool, ply )
if not IsValid( self.LinkTo ) then
multitool:reset()
return
end
local tr = ply:GetEyeTrace()
if not IsValid( tr.Entity ) or tr.Entity == self.LinkTo then
self.LookAt = nil
gmod_tool:SetStage( 0 )
else
self.LookAt = tr.Entity
gmod_tool:SetStage( 1 )
end
end
function multitool.modes.link:draw( gmod_tool, ply )
if not IsValid( self.LinkTo ) then return end
multitool:renderModel( self.LinkTo, multitool.ui.colors.ents_selected )
if IsValid( self.LookAt ) then
multitool:renderModel( self.LookAt, multitool.ui.colors.ents_hovered )
local pos = self.LookAt:GetPos():ToScreen()
local x = pos.x
local y = pos.y
local class = self.LookAt:GetClass()
overlay[1].text = class
overlay[1].size = GetTextSize( class, overlay[1].font )
overlay[1].draw.text[1] = class
DrawOverlay( x, y, overlay )
end
end
function multitool.modes.link:updateOverlays()
overlay[1].enabled = true
overlay[2].enabled = false
overlay[3].enabled = false
local k, v = next( self.Data.Info )
if not k or not v then return end
if v.tool_bind == 2 then
local name = v.name
overlay[2].draw.text[5] = name
overlay[2].text = table.concat( overlay[2].draw.text, "" )
overlay[2].size = GetTextSize( overlay[2].text, overlay[2].font )
overlay[2].enabled = true
end
if v.tool_bind == 3 then
local name = v.name
overlay[3].draw.text[7] = name
overlay[3].text = table.concat( overlay[3].draw.text, "" )
overlay[3].size = GetTextSize( overlay[3].text, overlay[3].font )
overlay[3].enabled = true
end
end
function multitool.modes.link:keyPress( gmod_tool, ply, key )
if key == 2 then return multitool:reset() end
if #self.Data.Info > 0 then
table.remove( self.Data.Info, 1 )
end
self:updateOverlays()
end
end