try to fix entity transmissions

This commit is contained in:
shadowscion 2023-01-19 13:53:21 -06:00
parent aa0993571e
commit db5d574275
9 changed files with 585 additions and 342 deletions

View File

@ -34,10 +34,10 @@ function ENT:Think()
end
if SERVER then
function ENT:UpdateTransmitState() return TRANSMIT_ALWAYS end
local function getmodel( ply, class )
local a = ply:GetInfo( "tanktracktool_spawn_model" )
print( a )
if a and util.IsValidModel( a ) then return a end
local b = scripted_ents.GetMember( class, "tanktracktool_model" )
@ -172,14 +172,6 @@ function ENT:netvar_getValues()
return self.netvar.values
end
function ENT:netvar_getLinks()
return self.netvar.entities
end
-- function ENT:netvar_setLinks( tbl, ply )
-- return tanktracktool.netvar.setLinks( self, tbl, ply )
-- end
function ENT:netvar_callback( id, ... )
end

View File

@ -12,9 +12,27 @@ local tanktracktool = tanktracktool
--[[
wiremod setup
wiremod & tool_link setup
]]
if CLIENT then
tanktracktool.netvar.addToolLink( ENT, "Entity1", nil, nil )
tanktracktool.netvar.addToolLink( ENT, "Entity2", nil, nil )
end
if SERVER then
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
tbl = {
Entity1 = isentity( tbl.Entity1 ) and tbl.Entity1 or nil,
Entity2 = isentity( tbl.Entity2 ) and tbl.Entity2 or nil,
}
return tanktracktool.netvar.setLinks( self, tbl, ply )
end
function ENT:netvar_nme( data )
return data
end
@ -53,27 +71,6 @@ if SERVER then
end
--[[
tool_link setup
]]
if CLIENT then
tanktracktool.netvar.addToolLink( ENT, "Entity1", nil, nil )
tanktracktool.netvar.addToolLink( ENT, "Entity2", nil, nil )
end
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
tbl = {
Entity1 = tbl.Entity1 or self.netvar.entities.Entity1,
Entity2 = tbl.Entity2 or self.netvar.entities.Entity2,
}
return tanktracktool.netvar.setLinks( self, tbl, ply )
end
--[[
netvar setup
]]
@ -274,7 +271,6 @@ function mode:onInit( controller )
local data = self:getData( controller )
data.vars = controller:netvar_getValues()
data.ents = controller:netvar_getLinks()
data.pointCount = math.abs( data.vars.pointCount or 10 )
data.pointMulti = math.Clamp( data.vars.pointMulti or 1, 1, 4 )
@ -343,13 +339,6 @@ function mode:onInit( controller )
data.beams = {}
end
local function GetEntity( self, netkey, netlink )
if netkey then netkey = self:GetNW2Entity( netkey ) end
if IsValid( netkey ) then return netkey else
return IsValid( netlink ) and netlink or self
end
end
local emitter = ParticleEmitter( Vector() )
local gravity = Vector()
@ -419,6 +408,13 @@ local function CreateBeam( controller, ent1, ent2, pos1, pos2, data, fx )
return beam
end
local function GetEntity( self, netkey, netlink )
if netkey then netkey = self:GetNW2Entity( netkey ) end
if IsValid( netkey ) then return netkey else
return IsValid( netlink ) and netlink or self
end
end
function mode:onThink( controller )
local data = self:getData( controller )
@ -427,8 +423,16 @@ function mode:onThink( controller )
return
end
local ent1 = GetEntity( controller, "netwire_Entity1", data.ents.Entity1 )
local ent2 = GetEntity( controller, "netwire_Entity2", data.ents.Entity2 )
if not controller.netvar.entities then
local t = {}
for k, v in pairs( controller.netvar.entindex ) do
t[k] = IsValid( Entity( v ) ) and Entity( v ) or nil
end
controller.netvar.entities = t
end
local ent1 = GetEntity( controller, "netwire_Entity1", controller.netvar.entities.Entity1 )
local ent2 = GetEntity( controller, "netwire_Entity2", controller.netvar.entities.Entity1 )
local pos1 = ent1:LocalToWorld( controller:GetNW2Vector( "netwire_Offset1" ), Vector() )
local pos2 = ent2:LocalToWorld( controller:GetNW2Vector( "netwire_Offset2" ), Vector() )

View File

@ -3,7 +3,7 @@ AddCSLuaFile()
DEFINE_BASECLASS( "base_tanktracktool" )
ENT.Type = "anim"
ENT.Spawnable = true
ENT.Spawnable = false
ENT.AdminOnly = false
ENT.Category = "tanktracktool"
@ -19,17 +19,19 @@ if CLIENT then
tanktracktool.netvar.addToolLink( ENT, "RightWheel", nil, nil )
end
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
if SERVER then
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
tbl = {
Chassis = tbl.Chassis or self.netvar.entities.Chassis,
LeftWheel = tbl.LeftWheel or self.netvar.entities.LeftWheel,
RightWheel = tbl.RightWheel or self.netvar.entities.RightWheel,
}
return tanktracktool.netvar.setLinks( self, tbl, ply )
tbl = {
Chassis = tbl.Chassis or self.netvar.entities.Chassis,
LeftWheel = tbl.LeftWheel or self.netvar.entities.LeftWheel,
RightWheel = tbl.RightWheel or self.netvar.entities.RightWheel,
}
return tanktracktool.netvar.setLinks( self, tbl, ply )
end
end

View File

@ -0,0 +1,172 @@
AddCSLuaFile()
DEFINE_BASECLASS( "base_tanktracktool" )
ENT.Type = "anim"
ENT.Spawnable = false
ENT.AdminOnly = false
ENT.Category = "tanktracktool"
local tanktracktool = tanktracktool
--[[
wiremod & tool_link setup
]]
if CLIENT then
tanktracktool.netvar.addToolLink( ENT, "Entity1", nil, nil )
tanktracktool.netvar.addToolLink( ENT, "Entity2", nil, nil )
end
if SERVER then
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
tbl = {
Entity1 = tbl.Entity1 or self.netvar.entities.Entity1,
Entity2 = tbl.Entity2 or self.netvar.entities.Entity2,
}
return tanktracktool.netvar.setLinks( self, tbl, ply )
end
function ENT:netvar_wireInputs()
return { "Entity1 [ENTITY]", "Entity2 [ENTITY]", "Offset1 [VECTOR]", "Offset2 [VECTOR]" }
end
local function isnan( v ) return v.x ~= v.x or v.y ~= v.y or v.z ~= v.z end
local function clamp( v ) return Vector( math.Clamp( v.x, -16384, 16384 ), math.Clamp( v.y, -16384, 16384 ), math.Clamp( v.z, -16384, 16384 ) ) end
local inputs = {}
inputs.Entity1 = function( self, ply, value )
if ply and not tanktracktool.netvar.canLink( value, ply ) then value = nil end
self:SetNW2Entity( "netwire_Entity1", value )
end
inputs.Entity2 = function( self, ply, value )
if ply and not tanktracktool.netvar.canLink( value, ply ) then value = nil end
self:SetNW2Entity( "netwire_Entity2", value )
end
inputs.Offset1 = function( self, ply, value )
if not isvector( value ) or isnan( value ) then value = nil else value = clamp( value ) end
self:SetNW2Vector( "netwire_Offset1", value )
end
inputs.Offset2 = function( self, ply, value )
if not isvector( value ) or isnan( value ) then value = nil else value = clamp( value ) end
self:SetNW2Vector( "netwire_Offset2", clamp( value ) )
end
function ENT:TriggerInput( name, value )
if inputs[name] then inputs[name]( self, WireLib and WireLib.GetOwner( self ), value ) end
end
end
--[[
netvar setup
]]
local netvar = tanktracktool.netvar.new()
local default = {
}
function ENT:netvar_setup()
return netvar, default
end
--[[
CLIENT
]]
if SERVER then return end
local math, util, string, table, render =
math, util, string, table, render
local next, pairs, FrameTime, Entity, IsValid, EyePos, EyeVector, Vector, Angle, Matrix, WorldToLocal, LocalToWorld, Lerp, LerpVector =
next, pairs, FrameTime, Entity, IsValid, EyePos, EyeVector, Vector, Angle, Matrix, WorldToLocal, LocalToWorld, Lerp, LerpVector
local pi = math.pi
--[[
editor callbacks
]]
--[[
netvar hooks
]]
local hooks = {}
hooks.editor_open = function( self, editor )
for k, cat in pairs( editor.Categories ) do
cat:SetExpanded( true )
end
end
hooks.netvar_set = function( self ) self.tanktracktool_reset = true end
hooks.netvar_syncLink = function( self ) self.tanktracktool_reset = true end
hooks.netvar_syncData = function( self ) self.tanktracktool_reset = true end
function ENT:netvar_callback( id, ... )
if hooks[id] then hooks[id]( self, ... ) end
end
--[[
]]
local mode = tanktracktool.render.mode()
local function GetEntity( self, entID, netID )
if netID then
netID = self:GetNW2Entity( netID, nil )
if IsValid( netID ) then
return netID
end
end
if not self.netvar.entindex[entID] then
return nil
end
local e = Entity( self.netvar.entindex[entID] )
return IsValid( e ) and e or nil
end
function mode:onInit( controller )
self:override( controller, true )
end
function mode:onThink( controller )
local e1 = GetEntity( controller, "Entity1", "netwire_Entity1" )
local e2 = GetEntity( controller, "Entity2", "netwire_Entity2" )
if not e1 or not e2 then
self:setnodraw( controller, true )
return
end
self:setnodraw( controller, false )
local data = self:getData( controller )
end
function mode:onDraw( controller, eyepos, eyedir, empty )
local data = self:getData( controller )
end
function ENT:Think()
self.BaseClass.Think( self )
if self.tanktracktool_reset then
self.tanktracktool_reset = nil
mode:init( self )
return
end
mode:think( self )
end
function ENT:Draw()
self:DrawModel()
end

View File

@ -3,6 +3,14 @@ include( "shared.lua" )
local tanktracktool = tanktracktool
local math, util, string, table, render =
math, util, string, table, render
local next, pairs, FrameTime, Entity, IsValid, EyePos, EyeVector, Vector, Angle, Matrix, WorldToLocal, LocalToWorld, Lerp, LerpVector =
next, pairs, FrameTime, Entity, IsValid, EyePos, EyeVector, Vector, Angle, Matrix, WorldToLocal, LocalToWorld, Lerp, LerpVector
local pi = math.pi
--[[
tool_link setup
@ -86,7 +94,7 @@ end
--[[
base ent
mode
]]
local function real_radius( ent )
if ent:GetHitBoxBounds( 0, 0 ) then
@ -102,9 +110,7 @@ local function GetAngularVelocity( ent, pos, ang )
local ang = math.deg( math.atan2( dir.z, dir.x ) )
ent.m_DeltaAngle = ent.m_DeltaAngle or 0
local ang_vel = ( ang - ent.m_DeltaAngle + 180 ) % 360 - 180
ent.m_DeltaAngle = ang
return ang_vel --/ FrameTime()
@ -113,44 +119,31 @@ end
local mode = tanktracktool.render.mode()
function mode:onInit( controller )
local entities = controller.netvar.entities
controller.autotracks_chassis = entities[1]
if not IsValid( controller.autotracks_chassis ) or not table.IsSequential( entities ) then
return false
end
local values = controller.netvar.values
controller.autotracks_trackvalues = {
trackColor = values.trackColor,
trackMaterial = values.trackMaterial,
trackWidth = values.trackWidth,
trackHeight = values.trackHeight,
trackGuideY = values.trackGuideY,
trackGrouser = values.trackGrouser,
trackTension = values.trackTension,
trackRes = values.trackRes,
trackFlip = values.trackFlip,
}
controller.autotracks_rotate = values.systemRotate ~= 0 and Angle( 0, -90, 0 ) or nil
controller:autotracks_setMatrix()
local pos, ang = controller:autotracks_getMatrix()
controller.tanktracktool_modeData.parts = {}
local parts = controller.tanktracktool_modeData.parts
for i = 2, #entities do
local wheel = entities[i]
if IsValid( wheel ) then
local part = { { entity = wheel, radius = real_radius( wheel ) } }
part.index = table.insert( parts, part )
part[1][1] = WorldToLocal( wheel:GetPos(), wheel:GetAngles(), pos, ang )
end
controller.autotracks_matrixRotate = tobool( values.systemRotate ) and Angle( 0, -90, 0 )
controller.autotracks_matrix = controller.autotracks_chassis:GetWorldTransformMatrix()
if controller.autotracks_matrixRotate then
controller.autotracks_matrix:Rotate( controller.autotracks_matrixRotate )
end
if #parts == 0 then return false end
local pos = controller.autotracks_matrix:GetTranslation()
local ang = controller.autotracks_matrix:GetAngles()
local parts = self:getParts( controller )
for i = 1, #controller.autotracks_wheels do
local wheel = controller.autotracks_wheels[i]
table.insert( parts, {
index = i,
{
entity = wheel,
radius = real_radius( wheel ),
[1] = WorldToLocal( wheel:GetPos(), wheel:GetAngles(), pos, ang ),
}
} )
end
local rollercount = 0
for i = 1, #parts do
@ -166,6 +159,18 @@ function mode:onInit( controller )
end
end
controller.autotracks_trackvalues = {
trackColor = values.trackColor,
trackMaterial = values.trackMaterial,
trackWidth = values.trackWidth,
trackHeight = values.trackHeight,
trackGuideY = values.trackGuideY,
trackGrouser = values.trackGrouser,
trackTension = values.trackTension,
trackRes = values.trackRes,
trackFlip = values.trackFlip,
}
controller.autotracks_rollercount = rollercount
controller.autotracks_trackoffset = parts[1][1][1].y + ( controller.autotracks_trackvalues.trackFlip ~= 0 and -1 or 1 ) * values.trackOffsetY
controller.autotracks_sprocket = math.Clamp( values.wheelSprocket, 1, #parts )
@ -175,13 +180,41 @@ function mode:onInit( controller )
tanktracktool.autotracks.setup( controller )
tanktracktool.autotracks.think( controller )
self:override( controller, true )
end
function mode:updateTracks( controller, pos, ang )
local parts = controller.tanktracktool_modeData.parts
if not parts then return end
function mode:onThink( controller, eyepos, eyedir )
controller.autotracks_data_ready = nil
if not IsValid( controller.autotracks_chassis ) then
controller.tanktracktool_reset = true
return
end
if controller.autotracks_chassis:IsDormant() then
return
end
for i = 1, #controller.autotracks_wheels do
if not IsValid( controller.autotracks_wheels[i] ) then
controller.tanktracktool_reset = true
print( "invalid wheell " )
return
end
end
local parts = self:getParts( controller )
controller.autotracks_matrix = controller.autotracks_chassis:GetWorldTransformMatrix()
if controller.autotracks_matrixRotate then
controller.autotracks_matrix:Rotate( controller.autotracks_matrixRotate )
end
local pos, ang = controller.autotracks_matrix:GetTranslation(), controller.autotracks_matrix:GetAngles()
local dir = pos - eyepos
if dir:Dot( eyedir ) / dir:Length() < -0.75 then return end
local sprocket = controller.autotracks_sprocket
@ -189,11 +222,6 @@ function mode:updateTracks( controller, pos, ang )
local wheel = parts[i][1]
local ent = wheel.entity
if not IsValid( ent ) then
controller.tanktracktool_reset = true
return
end
wheel[1] = WorldToLocal( ent:GetPos(), ent:GetAngles(), pos, ang )
wheel[1].y = controller.autotracks_trackoffset
@ -204,68 +232,73 @@ function mode:updateTracks( controller, pos, ang )
end
tanktracktool.autotracks.think( controller )
return controller.autotracks_data_ready
end
function mode:onDraw( controller, eyepos, eyedir, empty )
if not IsValid( controller ) then
self:override( controller, false )
return
end
if not IsValid( controller.autotracks_chassis ) then
self:override( controller, false )
return
end
if controller.autotracks_chassis:IsDormant() then return end
function mode:onDraw( controller, eyepos, eyedir, emptyCSENT, flashlightMODE )
local pos, ang = controller.autotracks_matrix:GetTranslation(), controller.autotracks_matrix:GetAngles()
controller:autotracks_setMatrix()
local pos, ang = controller:autotracks_getMatrix()
if controller.autotracks_data_ready and emptyCSENT then
local matrix = controller.autotracks_matrix
local pos, ang = matrix:GetTranslation(), matrix:GetAngles()
local dot = eyedir:Dot( pos - eyepos )
if dot < 0 and math.abs( dot ) > 100 then return end
if empty and self:updateTracks( controller, pos, ang ) then
render.SetBlend( 0 )
empty:SetPos( pos )
empty:SetAngles( ang )
empty:SetupBones()
empty:DrawModel()
emptyCSENT:SetPos( pos )
emptyCSENT:SetAngles( ang )
emptyCSENT:SetupBones()
emptyCSENT:DrawModel()
render.SetBlend( 1 )
tanktracktool.autotracks.render( controller, controller.autotracks_matrix )
tanktracktool.autotracks.render( controller, matrix )
end
end
function ENT:autotracks_setMatrix()
self.autotracks_matrix = self.autotracks_chassis:GetWorldTransformMatrix()
if self.autotracks_rotate then
self.autotracks_matrix:Rotate( self.autotracks_rotate )
end
end
function ENT:autotracks_getMatrix()
if not self.autotracks_matrix then
return self.autotracks_chassis:GetPos(), self.autotracks_chassis:GetAngles()
end
return self.autotracks_matrix:GetTranslation(), self.autotracks_matrix:GetAngles()
end
function ENT:Think()
if tanktracktool.disable_autotracks then
self.netvar_syncData = nil
self.netvar_syncLink = nil
self.tanktracktool_reset = true
mode:override( self, false )
return
end
self.BaseClass.Think( self )
if self.tanktracktool_reset then
self.tanktracktool_reset = nil
if not self.netvar.entities then
local e = {}
for k, v in pairs( self.netvar.entindex ) do
if IsValid( Entity( v ) ) then
e[k] = Entity( v )
else
return
end
end
self.netvar.entities = e
return
end
self.autotracks_chassis = self.netvar.entities[1]
if not IsValid( self.autotracks_chassis ) then return end
self.autotracks_wheels = {}
for k, v in SortedPairs( self.netvar.entities ) do
if k ~= 1 and IsValid( v ) then table.insert( self.autotracks_wheels, v ) end
end
if #self.autotracks_wheels == 0 then return end
mode:init( self )
self.tanktracktool_reset = nil
return
end
mode:think( self )
end
function ENT:Draw()

View File

@ -8,6 +8,116 @@ function ENT:netvar_nme( data )
end
--[[
sort wheels based on forward position
separated by a table of wheels and a table of roller wheels
]]
local function GetSortedWheels( chassis, wheels, rollers, rotate )
local matrix = chassis:GetWorldTransformMatrix()
if rotate then matrix:Rotate( rotate ) end
local pos = matrix:GetTranslation() + matrix:GetForward() * 12345
local tbl = {}
for k, ent in pairs( wheels ) do
if not isentity( ent ) then ent = k end
if isentity( ent ) and IsValid( ent ) then
table.insert( tbl, ent )
ent.rollerTemp = nil
ent.sortPosTemp = ent:GetPos():Distance( pos )
if #tbl > 32 then break end
end
end
for k, ent in pairs( rollers ) do
if not isentity( ent ) then ent = k end
if isentity( ent ) and IsValid( ent ) then
table.insert( tbl, ent )
ent.rollerTemp = true
ent.sortPosTemp = ent:GetPos():Distance( pos )
if #tbl > 32 then break end
end
end
table.sort( tbl, function( e1, e2 )
local this = e1.rollerTemp
local that = e2.rollerTemp
if this ~= that then return that and not this end
if this then return e1.sortPosTemp > e2.sortPosTemp else return e1.sortPosTemp < e2.sortPosTemp end
end )
for k, ent in pairs( tbl ) do
ent.rollerTemp = nil
ent.sortPosTemp = nil
end
table.insert( tbl, 1, chassis )
return tbl
end
--[[
check if all ents are to one side of the chassis
optional filter function
]]
local function Filter( ent )
if not isentity( ent ) or not IsValid( ent ) or ent:IsPlayer() or ent:IsVehicle() or ent:IsNPC() or ent:IsWorld() then return true end
end
local function CheckParallelism( chassis, tbl, rotate, filter )
local matrix = chassis:GetWorldTransformMatrix()
if rotate then matrix:Rotate( rotate ) end
local pos = matrix:GetTranslation()
local dir = matrix:GetRight()
local dot
for k, ent in pairs( tbl ) do
if filter and filter( ent ) then return "invalid wheel or chassis entity " .. tostring( ent ) end
if ent ~= chassis then
local d = dir:Dot( ( ent:GetPos() - pos ):GetNormalized() ) > 0
if dot == nil then dot = d end
if dot ~= d then
return "wheels must all be on the same side of the chassis"
end
end
end
return false
end
--[[
sort wheels before sending the table to netvar linking function
prop protection is checked there
]]
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
local rotate = tobool( self.netvar.values.systemRotate ) and Angle( 0, -90, 0 )
--if istable( tbl.Wheel ) and istable( tbl.Roller ) and isentity( tbl.Chassis ) then
if isentity( tbl.Chassis ) then
tbl.Wheel = tbl.Wheel or {}
tbl.Roller = tbl.Roller or {}
tbl = GetSortedWheels( tbl.Chassis, tbl.Wheel, tbl.Roller, rotate )
end
if istable( tbl ) and table.IsSequential( tbl ) then
local isp = CheckParallelism( tbl[1], tbl, rotate, Filter )
if isp then
if IsValid( ply ) then ply:ChatPrint( isp ) end
return
end
return tanktracktool.netvar.setLinks( self, tbl, ply )
end
end
--[[
legacy... this is for ttc
]]

View File

@ -44,108 +44,3 @@ if CLIENT then
netvar:get( "trackMaterial" ).data.values = tanktracktool.autotracks.textureList()
netvar:get( "trackMaterial" ).data.images = "tanktracktool/autotracks/gui/%s"
end
--[[
sort wheels based on forward position
separated by a table of wheels and a table of roller wheels
]]
local function GetSortedWheels( chassis, wheels, rollers, rotate )
local matrix = chassis:GetWorldTransformMatrix()
if rotate then matrix:Rotate( rotate ) end
local pos = matrix:GetTranslation() + matrix:GetForward() * 12345
local tbl = {}
for k, ent in pairs( wheels ) do
if isentity( ent ) and IsValid( ent ) then
table.insert( tbl, ent )
ent.rollerTemp = nil
ent.sortPosTemp = ent:GetPos():Distance( pos )
if #tbl > 32 then break end
end
end
for k, ent in pairs( rollers ) do
if isentity( ent ) and IsValid( ent ) then
table.insert( tbl, ent )
ent.rollerTemp = true
ent.sortPosTemp = ent:GetPos():Distance( pos )
if #tbl > 32 then break end
end
end
table.sort( tbl, function( e1, e2 )
local this = e1.rollerTemp
local that = e2.rollerTemp
if this ~= that then return that and not this end
if this then return e1.sortPosTemp > e2.sortPosTemp else return e1.sortPosTemp < e2.sortPosTemp end
end )
for k, ent in pairs( tbl ) do
ent.rollerTemp = nil
ent.sortPosTemp = nil
end
table.insert( tbl, 1, chassis )
return tbl
end
--[[
check if all ents are to one side of the chassis
optional filter function
]]
local function Filter( ent )
if not isentity( ent ) or not IsValid( ent ) or ent:IsPlayer() or ent:IsVehicle() or ent:IsNPC() or ent:IsWorld() then return true end
end
local function CheckParallelism( chassis, tbl, rotate, filter )
local matrix = chassis:GetWorldTransformMatrix()
if rotate then matrix:Rotate( rotate ) end
local pos = matrix:GetTranslation()
local dir = matrix:GetRight()
local dot
for k, ent in pairs( tbl ) do
if filter and filter( ent ) then return "invalid wheel or chassis entity " .. tostring( ent ) end
if ent ~= chassis then
local d = dir:Dot( ( ent:GetPos() - pos ):GetNormalized() ) > 0
if dot == nil then dot = d end
if dot ~= d then
return "wheels must all be on the same side of the chassis"
end
end
end
return false
end
--[[
sort wheels before sending the table to netvar linking function
prop protection is checked there
]]
function ENT:netvar_setLinks( tbl, ply )
if not istable( tbl ) then
return tanktracktool.netvar.setLinks( self, {}, ply )
end
local rotate = tobool( self.netvar.values.systemRotate ) and Angle( 0, -90, 0 )
if istable( tbl.Wheel ) and istable( tbl.Roller ) and isentity( tbl.Chassis ) then
tbl = GetSortedWheels( tbl.Chassis, tbl.Wheel, tbl.Roller, rotate )
end
if istable( tbl ) and table.IsSequential( tbl ) then
local isp = CheckParallelism( tbl[1], tbl, rotate, Filter )
if isp then
if IsValid( ply ) then ply:ChatPrint( isp ) end
return
end
return tanktracktool.netvar.setLinks( self, tbl, ply )
end
end

View File

@ -218,9 +218,14 @@ function tanktracktool.render.mode( TYPE_ASSEM, CSENTS )
draws[controller] = bDraw and self or nil
end
function meta:setnodraw( controller, bDraw )
controller.tanktracktool_modeData_nodraw = bDraw
end
function meta:init( controller )
draws[controller] = nil
controller.tanktracktool_modeData_nodraw = nil
controller.tanktracktool_modeData_audible = true -- can think
controller.tanktracktool_modeData_visible = nil -- can draw
controller.tanktracktool_modeData = { csents = {}, parts = {}, data = {} }
@ -237,14 +242,14 @@ function tanktracktool.render.mode( TYPE_ASSEM, CSENTS )
end
function meta:draw( controller )
if not controller.tanktracktool_modeData_visible then return end
if controller.tanktracktool_modeData_nodraw or not controller.tanktracktool_modeData_visible then return end
self:onDraw( controller, eyepos, eyedir, emptyCSENT, flashlightMODE )
end
function meta:think( controller )
if not controller.tanktracktool_modeData_audible then return end
controller.tanktracktool_modeData_visible = true
self:onThink( controller )
self:onThink( controller, eyepos, eyedir )
end
function meta:addCSent( ... )

View File

@ -25,7 +25,9 @@ if SERVER then
--[[
receive specific variable edits
client sends a table of edits to server
server checks and sets the edits
server sends the changes to all clients
]]
net.Receive( netmsg_netvars_edit, function( len, ply )
local ent = Entity( net.ReadUInt( 16 ) )
@ -41,7 +43,9 @@ if SERVER then
--[[
receive full update requests
client needs a full data sync
server adds client name to list
server sends data to clients
]]
net.Receive( netmsg_netvars_data, function( len, ply )
local ent = Entity( net.ReadUInt( 16 ) )
@ -61,7 +65,23 @@ if SERVER then
--[[
receive link update requests
0
client needs a link sync
server adds client name to list
server sends links to clients
1
client wants to edit links
server checks and sends new links to clients
2
client wants to remove all links
server checks and sends new links to clients
3
client wants to copy values from controller A to controller B
server sends the changes to all clients
( this should be in the edit netfunc but oh well )
]]
net.Receive( netmsg_netvars_link, function( len, ply )
local ent = Entity( net.ReadUInt( 16 ) )
@ -106,7 +126,7 @@ if SERVER then
--[[
satisfy full update requests
servercompressees and sends all data to players
]]
function netvar.transmitData( ent, sendTo )
if not netvar.isValid( ent ) then return end
@ -124,14 +144,19 @@ if SERVER then
--[[
satisfy link update requests
server sends table of link entIndexes to players
]]
function netvar.transmitLink( ent, sendTo )
if not netvar.isValid( ent ) then return end
net.Start( netmsg_netvars_link )
net.WriteUInt( ent:EntIndex(), 16 )
net.WriteTable( ent.netvar.entities )
local valid = {}
for k, v in pairs( ent.netvar.entities ) do
if IsValid( v ) then valid[k] = v:EntIndex() end
end
net.WriteTable( valid )
if sendTo == true then net.Broadcast() else net.Send( table.GetKeys( sendTo ) ) end
end
@ -139,7 +164,7 @@ if SERVER then
else
--[[
receive specific update
client recieves a variable edit
]]
net.Receive( netmsg_netvars_edit, function( len )
local ent = Entity( net.ReadUInt( 16 ) )
@ -155,7 +180,7 @@ else
--[[
receive full update
client recieves a data sync
]]
net.Receive( netmsg_netvars_data, function( len )
local ent = Entity( net.ReadUInt( 16 ) )
@ -174,14 +199,17 @@ else
--[[
receive link update
client recieves a link sync
]]
net.Receive( netmsg_netvars_link, function( len )
local ent = Entity( net.ReadUInt( 16 ) )
if not netvar.isValid( ent ) then return end
ent.netvar.entities = net.ReadTable()
ent:netvar_callback( "netvar_syncLink", ent.netvar.entities )
local t = net.ReadTable()
ent.netvar.entities = nil
ent.netvar.entindex = t
ent:netvar_callback( "netvar_syncLink", ent.netvar.entindex )
if tanktracktool.loud( tanktracktool.loud_link ) then
tanktracktool.note( string.format( "receiving link\nent: %s\n", tostring( ent ) ) )
@ -190,7 +218,8 @@ else
--[[
send full update request
these hooks ensure a sync check on game join
handled in ENT:netvar_transmit()
]]
hook.Add( "NotifyShouldTransmit", "tanktracktool_resync", function( ent, bool )
if bool then
@ -208,7 +237,7 @@ else
--[[
send specific edit
client sends an edit request to server
]]
function netvar.transmitEdit( ent, name, index, val )
if not netvar.isValid( ent ) then return end
@ -225,7 +254,7 @@ else
--[[
send data request
client sends an data request to server
]]
function netvar.transmitData( ent )
if not netvar.isValid( ent ) then return end
@ -241,7 +270,7 @@ else
--[[
send link request
client sends an link request to server
]]
function netvar.transmitLink( ent, tbl )
if not netvar.isValid( ent ) then return end
@ -261,7 +290,7 @@ end
--[[
validators
base_tanktracktool validators and permissions
]]
function netvar.isValid( ent )
if not IsValid( ent ) then return false end
@ -282,7 +311,7 @@ end
--[[
safe setters
safe variable setters
]]
netvar.sanitizer = {}
@ -309,7 +338,8 @@ function netvar.sanitizer.float( value, data )
end
function netvar.sanitizer.string( value, data )
if data.numeric then return tostring( tonumber( value or 0 ) or 0 ) else return tostring( value or "" ) or "" end
if data.numeric then value = tostring( tonumber( value or 0 ) or 0 ) else value = tostring( value or "" ) or "" end
if string.len( value ) < 255 then return value else return string.sub( value, 1, 255 ) end
end
function netvar.sanitizer.color( value, data )
@ -449,7 +479,7 @@ function netvar.install( ent, install, default, restore )
if not istable( restore ) then restore = nil end
if not istable( default ) then default = nil end
ent.netvar = { entities = {}, values = {}, variables = install }
ent.netvar = { entindex = {}, values = {}, variables = install }
for k, var in ipairs( ent.netvar.variables.data.n ) do
local def = var.data.def
@ -475,20 +505,9 @@ function netvar.install( ent, install, default, restore )
end
end
if SERVER then ent.netvar_syncData = true end
end
if SERVER then
function netvar.copy( ent1, ent2, ply )
local check = IsValid( ply ) and netvar.canEdit or netvar.isValid
if not check( ent1, ply ) or not check( ent2, ply ) then return end
local vars = ent1.netvar.variables
local vals = ent1.netvar.values
local ents = ent1.netvar.entities
netvar.install( ent1, vars, vals, ent2.netvar.values )
ent1.netvar.entities = ents
if SERVER then
ent.netvar.entities = {}
ent.netvar_syncData = true
end
end
@ -543,78 +562,59 @@ function netvar.getVar( ent, name, index )
return ent.netvar.values[name]
end
function netvar.setLinks( ent, tbl, ply )
if not netvar.isValid( ent ) then return false end
if not istable( tbl ) then return false end
local entities = {}
for k, v in pairs( tbl ) do
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
ent.netvar.entities = entities
if SERVER then ent.netvar_syncLink = true end
return entities
end
if CLIENT then
function netvar.addToolLink( e, n1, f1, h1 )
if not isstring( n1 ) then return end
if not e.tanktracktool_linkData then e.tanktracktool_linkData = {} end
table.insert( e.tanktracktool_linkData, {
name = n1,
--tool_bind = "rmb",
tool_filter = isfunction( f1 ) and f1 or nil,
tool_hud = isfunction( h1 ) and h1 or nil,
} )
end
function netvar.addToolLinks( e, n1, f1, h1, n2, f2, h2 )
if not isstring( n1 ) then return end
if not isstring( n2 ) then return end
if not e.tanktracktool_linkData then e.tanktracktool_linkData = {} end
table.insert( e.tanktracktool_linkData, {
istable = true,
{
name = n1,
---tool_bind = "rmb",
tool_filter = isfunction( f1 ) and f1 or nil,
tool_hud = isfunction( h1 ) and h1 or nil,
},
{
name = n2,
--tool_bind = "rmb+shift",
tool_filter = isfunction( f2 ) and f2 or nil,
tool_hud = isfunction( h2 ) and h2 or nil,
},
} )
end
end
--[[
duplicator support
]]
if SERVER then
function netvar.copy( ent1, ent2, ply )
local check = IsValid( ply ) and netvar.canEdit or netvar.isValid
if not check( ent1, ply ) or not check( ent2, ply ) then return end
local vars = ent1.netvar.variables
local vals = ent1.netvar.values
local ents = ent1.netvar.entities
local eidx = ent1.netvar.entindex
netvar.install( ent1, vars, vals, ent2.netvar.values )
ent1.netvar.entities = ents
ent1.netvar.entindex = eidx
end
function netvar.setLinks( ent, tbl, ply )
if not netvar.isValid( ent ) then return false end
if not istable( tbl ) then return false end
local entities = {}
local entindex = {}
for k, v in pairs( tbl ) do
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
entindex[k] = v:EntIndex()
end
ent.netvar.entities = entities
ent.netvar.entindex = entindex
if SERVER then ent.netvar_syncLink = true end
return entities
end
--[[
duplicator support
]]
function netvar.getDupe( ent )
if not netvar.isValid( ent ) then return end
local links = {}
--if table.IsSequential( ent.netvar.entities ) then
for k, v in pairs( ent.netvar.entities ) do
if not IsValid( v ) then
links = {}
break
end
links[k] = v:EntIndex()
for k, v in pairs( ent.netvar.entities ) do
if not IsValid( v ) then
links = {}
break
end
--end
links[k] = v:EntIndex()
end
return { data = ent.netvar.values, links = links }
end
@ -663,6 +663,36 @@ if SERVER then
ent:netvar_setLinks( linked )
end
end
else
function netvar.addToolLink( e, n1, f1, h1 )
if not isstring( n1 ) then return end
if not e.tanktracktool_linkData then e.tanktracktool_linkData = {} end
table.insert( e.tanktracktool_linkData, {
name = n1,
--tool_bind = "rmb",
tool_filter = isfunction( f1 ) and f1 or nil,
tool_hud = isfunction( h1 ) and h1 or nil,
} )
end
function netvar.addToolLinks( e, n1, f1, h1, n2, f2, h2 )
if not isstring( n1 ) then return end
if not isstring( n2 ) then return end
if not e.tanktracktool_linkData then e.tanktracktool_linkData = {} end
table.insert( e.tanktracktool_linkData, {
istable = true,
{
name = n1,
tool_filter = isfunction( f1 ) and f1 or nil,
tool_hud = isfunction( h1 ) and h1 or nil,
},
{
name = n2,
tool_filter = isfunction( f2 ) and f2 or nil,
tool_hud = isfunction( h2 ) and h2 or nil,
},
} )
end
end