This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 8064ba84d8
commit 73479cff9e
7338 changed files with 1718883 additions and 14 deletions

View File

@@ -0,0 +1,854 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
TOOL.Category = "simfphys"
TOOL.Name = "#Vehicle Duplicator"
TOOL.Command = nil
TOOL.ConfigName = ""
if SERVER then
util.AddNetworkString( "sphys_dupe" )
local recv_interval_start = 0 -- first second of current interval
local recv_interval_len = 1 -- in seconds, length of interval before resetting recv_interval_(start,count)
local recv_interval_count = 0 -- current count of messages received in interval
local recv_max = 500 -- maximum number of messages to receive during one interval
local recv_stop = 0 -- is the net.Receive stopped (activates short-circuit)
local recv_delay_after_stop = 3600 -- how long to wait (in seconds) before allowing messages again
net.Receive("sphys_dupe", function( length, ply )
if (recv_stop == 1) then -- if stopped,
return -- short-circuit
end
-- check if a new interval has come
if (recv_interval_start + recv_interval_len < os.time()) then
recv_interval_start = os.time() -- reset time
recv_interval_count = 0 -- reset message count
end
recv_interval_count = recv_interval_count + 1
-- check if below threshold
if (recv_interval_count > recv_max) then
-- if over threshold, activate short-circuit
recv_stop = 1
-- and create a timer to deactivate the short-circuit in recv_delay_after_stop seconds
timer.Simple(recv_delay_after_stop, function()
recv_stop = 0
end)
-- warn server about attack
PrintMessage(HUD_PRINTTALK, "WARNING: " .. ply:Nick() .. " [" .. ply:SteamID() .. "] is attacking sphys_dupe. simfphys duplicator is disabled for " .. tostring(recv_delay_after_stop) .. " seconds.")
end
ply.TOOLMemory = net.ReadTable()
ply:SelectWeapon( "gmod_tool" )
end)
end
if CLIENT then
language.Add( "tool.simfphysduplicator.name", "Vehicle Duplicator" )
language.Add( "tool.simfphysduplicator.desc", "Copy, Paste or Save your Vehicles" )
language.Add( "tool.simfphysduplicator.0", "Left click to spawn or update. Right click to copy" )
language.Add( "tool.simfphysduplicator.1", "Left click to spawn or update. Right click to copy" )
local selecteditem = nil
local TOOLMemory = {}
net.Receive("sphys_dupe", function( length )
TOOLMemory = net.ReadTable()
end)
local function GetSaves( panel )
local saved_vehicles = file.Find("saved_vehicles/*.txt", "DATA")
local index = 0
local highlight = false
local offset = 22
for k,v in pairs(saved_vehicles) do
local printname = v
if not selecteditem then
selecteditem = printname
end
local Button = vgui.Create( "DButton", panel )
Button:SetText( printname )
Button:SetTextColor( Color( 255, 255, 255 ) )
Button:SetPos( 0,index * offset)
Button:SetSize( 280, offset )
Button.highlight = highlight
Button.printname = printname
Button.Paint = function( self, w, h )
local c_selected = Color( 128, 185, 128, 255 )
local c_normal = self.highlight and Color( 108, 111, 114, 200 ) or Color( 77, 80, 82, 200 )
local c_hovered = Color( 41, 128, 185, 255 )
local c_ = (selecteditem == self.printname) and c_selected or (self:IsHovered() and c_hovered or c_normal)
draw.RoundedBox( 5, 1, 1, w - 2, h - 1, c_ )
end
Button.DoClick = function( self )
selecteditem = self.printname
end
index = index + 1
highlight = not highlight
end
end
function TOOL.BuildCPanel( panel )
if not file.Exists( "saved_vehicles", "DATA" ) then
file.CreateDir( "saved_vehicles" )
end
local Frame = vgui.Create( "DFrame", panel )
Frame:SetPos( 10, 30 )
Frame:SetSize( 280, 320 )
Frame:SetTitle( "" )
Frame:SetVisible( true )
Frame:ShowCloseButton( false )
Frame:SetDraggable( false )
Frame.Paint = function( self, w, h )
draw.RoundedBox( 5, 0, 0, w, h, Color( 115, 115, 115, 255 ) )
draw.RoundedBox( 5, 1, 1, w - 2, h - 2, Color( 234, 234, 234, 255 ) )
end
local ScrollPanel = vgui.Create( "DScrollPanel", Frame )
ScrollPanel:SetSize( 280, 320 )
ScrollPanel:SetPos( 0, 0 )
GetSaves( ScrollPanel )
local Button = vgui.Create( "DButton", panel )
Button:SetText( "Save" )
Button:SetPos( 10, 350)
Button:SetSize( 280, 20 )
Button.DoClick = function( self )
if isstring(TOOLMemory.SpawnName) then
local Frame = vgui.Create( "DFrame" )
Frame:SetPos( gui.MouseX() - 100, gui.MouseY() - 30 )
Frame:SetSize( 280, 50 )
Frame:SetTitle( "Save As..." )
Frame:SetVisible( true )
Frame:ShowCloseButton( true )
Frame:MakePopup()
Frame:SetDraggable( true )
local TextEntry = vgui.Create( "DTextEntry", Frame )
TextEntry:SetPos( 5, 25 )
TextEntry:SetSize( 270, 20 )
TextEntry.OnEnter = function()
local Name = TextEntry:GetValue()
if Name ~= "" then
local DataString = ""
for k,v in pairs(TOOLMemory) do
if k == "SubMaterials" then
local mats = ""
local first = true
for k, v in pairs( v ) do
if first then
first = false
mats = mats..v
else
mats = mats..","..v
end
end
DataString = DataString..k.."="..mats.."#"
else
DataString = DataString..k.."="..tostring( v ).."#"
end
end
local words = string.Explode( "", DataString )
local shit = {}
for k, v in pairs( words ) do
shit[k] = string.char( string.byte( v ) + 20 )
end
file.Write("saved_vehicles/"..Name..".txt", string.Implode("",shit) )
ScrollPanel:Clear()
selecteditem = Name..".txt"
GetSaves( ScrollPanel )
end
Frame:Close()
end
end
end
local Button = vgui.Create( "DButton", panel )
Button:SetText( "Load" )
Button:SetPos( 10, 370)
Button:SetSize( 280, 20 )
Button.DoClick = function( self )
if isstring(selecteditem) then
if not file.Exists( "saved_vehicles/"..selecteditem, "DATA" ) then
ScrollPanel:Clear()
selecteditem = nil
GetSaves( ScrollPanel )
return
end
local DataString = file.Read( "saved_vehicles/"..selecteditem, "DATA" )
local words = string.Explode( "", DataString )
local shit = {}
for k, v in pairs( words ) do
shit[k] = string.char( string.byte( v ) - 20 )
end
local Data = string.Explode( "#", string.Implode("",shit) )
table.Empty( TOOLMemory )
for _,v in pairs(Data) do
local Var = string.Explode( "=", v )
local name = Var[1]
local variable = Var[2]
if name and variable then
if name == "SubMaterials" then
TOOLMemory[name] = {}
local submats = string.Explode( ",", variable )
for i = 0, (table.Count( submats ) - 1) do
TOOLMemory[name][i] = submats[i+1]
end
else
TOOLMemory[name] = variable
end
end
end
net.Start("sphys_dupe")
net.WriteTable( TOOLMemory )
net.SendToServer()
end
end
local Button = vgui.Create( "DButton", panel )
Button:SetText( "Delete" )
Button:SetPos( 10, 430)
Button:SetSize( 280, 20 )
Button.DoClick = function( self )
if isstring(selecteditem) then
file.Delete( "saved_vehicles/"..selecteditem )
end
ScrollPanel:Clear()
selecteditem = nil
GetSaves( ScrollPanel )
end
local Button = vgui.Create( "DButton", panel )
Button:SetText( "Refresh" )
Button:SetPos( 10, 390)
Button:SetSize( 280, 20 )
Button.DoClick = function( self )
ScrollPanel:Clear()
selecteditem = nil
GetSaves( ScrollPanel )
end
end
end
local function ValidateModel( model )
local v_list = list.Get( "simfphys_vehicles" )
for listname, _ in pairs( v_list ) do
if v_list[listname].Members.CustomWheels then
local FrontWheel = v_list[listname].Members.CustomWheelModel
local RearWheel = v_list[listname].Members.CustomWheelModel_R
if FrontWheel then
FrontWheel = string.lower( FrontWheel )
end
if RearWheel then
RearWheel = string.lower( RearWheel )
end
if model == FrontWheel or model == RearWheel then
return true
end
end
end
local list = list.Get( "simfphys_Wheels" )[model]
if list then
return true
end
return false
end
function TOOL:GetVehicleData( ent, ply )
if not IsValid(ent) then return end
if not istable(ply.TOOLMemory) then ply.TOOLMemory = {} end
table.Empty( ply.TOOLMemory )
ply.TOOLMemory.SpawnName = ent:GetSpawn_List()
ply.TOOLMemory.SteerSpeed = ent:GetSteerSpeed()
ply.TOOLMemory.SteerFadeSpeed = ent:GetFastSteerConeFadeSpeed()
ply.TOOLMemory.SteerAngFast = ent:GetFastSteerAngle()
ply.TOOLMemory.SoundPreset = ent:GetEngineSoundPreset()
ply.TOOLMemory.IdleRPM = ent:GetIdleRPM()
ply.TOOLMemory.MaxRPM = ent:GetLimitRPM()
ply.TOOLMemory.PowerStart = ent:GetPowerBandStart()
ply.TOOLMemory.PowerEnd = ent:GetPowerBandEnd()
ply.TOOLMemory.PeakTorque = ent:GetMaxTorque()
ply.TOOLMemory.HasTurbo = ent:GetTurboCharged()
ply.TOOLMemory.HasBlower = ent:GetSuperCharged()
ply.TOOLMemory.HasRevLimiter = ent:GetRevlimiter()
ply.TOOLMemory.HasBulletProofTires = ent:GetBulletProofTires()
ply.TOOLMemory.MaxTraction = ent:GetMaxTraction()
ply.TOOLMemory.GripOffset = ent:GetTractionBias()
ply.TOOLMemory.BrakePower = ent:GetBrakePower()
ply.TOOLMemory.PowerDistribution = ent:GetPowerDistribution()
ply.TOOLMemory.Efficiency = ent:GetEfficiency()
ply.TOOLMemory.HornSound = ent.snd_horn
ply.TOOLMemory.HasBackfire = ent:GetBackFire()
ply.TOOLMemory.DoesntStall = ent:GetDoNotStall()
ply.TOOLMemory.SoundOverride = ent:GetSoundoverride()
ply.TOOLMemory.FrontHeight = ent:GetFrontSuspensionHeight()
ply.TOOLMemory.RearHeight = ent:GetRearSuspensionHeight()
ply.TOOLMemory.Camber = ent.Camber or 0
if ent.FrontDampingOverride and ent.FrontConstantOverride and ent.RearDampingOverride and ent.RearConstantOverride then
ply.TOOLMemory.FrontDampingOverride = ent.FrontDampingOverride
ply.TOOLMemory.FrontConstantOverride = ent.FrontConstantOverride
ply.TOOLMemory.RearDampingOverride = ent.RearDampingOverride
ply.TOOLMemory.RearConstantOverride = ent.RearConstantOverride
end
if ent.CustomWheels then
if ent.GhostWheels then
if IsValid(ent.GhostWheels[1]) then
ply.TOOLMemory.FrontWheelOverride = ent.GhostWheels[1]:GetModel()
elseif IsValid(ent.GhostWheels[2]) then
ply.TOOLMemory.FrontWheelOverride = ent.GhostWheels[2]:GetModel()
end
if IsValid(ent.GhostWheels[3]) then
ply.TOOLMemory.RearWheelOverride = ent.GhostWheels[3]:GetModel()
elseif IsValid(ent.GhostWheels[4]) then
ply.TOOLMemory.RearWheelOverride = ent.GhostWheels[4]:GetModel()
end
end
end
local tsc = ent:GetTireSmokeColor()
ply.TOOLMemory.TireSmokeColor = tsc.r..","..tsc.g..","..tsc.b
local Gears = ""
for _,v in pairs(ent.Gears) do
Gears = Gears..v..","
end
local c = ent:GetColor()
ply.TOOLMemory.Color = c.r..","..c.g..","..c.b..","..c.a
local bodygroups = {}
for k,v in pairs(ent:GetBodyGroups()) do
bodygroups[k] = ent:GetBodygroup( k )
end
ply.TOOLMemory.BodyGroups = string.Implode( ",", bodygroups)
ply.TOOLMemory.Skin = ent:GetSkin()
ply.TOOLMemory.Gears = Gears
ply.TOOLMemory.FinalGear = ent:GetDifferentialGear()
if ent.WheelTool_Foffset then
ply.TOOLMemory.WheelTool_Foffset = ent.WheelTool_Foffset
end
if ent.WheelTool_Roffset then
ply.TOOLMemory.WheelTool_Roffset = ent.WheelTool_Roffset
end
if ent.snd_blowoff then
ply.TOOLMemory.snd_blowoff = ent.snd_blowoff
end
if ent.snd_spool then
ply.TOOLMemory.snd_spool = ent.snd_spool
end
if ent.snd_bloweron then
ply.TOOLMemory.snd_bloweron = ent.snd_bloweron
end
if ent.snd_bloweroff then
ply.TOOLMemory.snd_bloweroff = ent.snd_bloweroff
end
ply.TOOLMemory.backfiresound = ent:GetBackfireSound()
ply.TOOLMemory.SubMaterials = {}
for i = 0, (table.Count( ent:GetMaterials() ) - 1) do
ply.TOOLMemory.SubMaterials[i] = ent:GetSubMaterial( i )
end
if not IsValid( ply ) then return end
net.Start("sphys_dupe")
net.WriteTable( ply.TOOLMemory )
net.Send( ply )
end
local function GetRight( ent, index, WheelPos )
local Steer = ent:GetTransformedDirection()
local Right = ent.Right
if WheelPos.IsFrontWheel then
Right = (IsValid( ent.SteerMaster ) and Steer.Right or ent.Right) * (WheelPos.IsRightWheel and 1 or -1)
else
Right = (IsValid( ent.SteerMaster ) and Steer.Right2 or ent.Right) * (WheelPos.IsRightWheel and 1 or -1)
end
return Right
end
local function SetWheelOffset( ent, offset_front, offset_rear )
if not IsValid( ent ) then return end
ent.WheelTool_Foffset = offset_front
ent.WheelTool_Roffset = offset_rear
if not istable( ent.Wheels ) or not istable( ent.GhostWheels ) then return end
for i = 1, table.Count( ent.GhostWheels ) do
local Wheel = ent.Wheels[ i ]
local WheelModel = ent.GhostWheels[i]
local WheelPos = ent:LogicWheelPos( i )
if IsValid( Wheel ) and IsValid( WheelModel ) then
local Pos = Wheel:GetPos()
local Right = GetRight( ent, i, WheelPos )
local offset = WheelPos.IsFrontWheel and offset_front or offset_rear
WheelModel:SetParent( nil )
local physObj = WheelModel:GetPhysicsObject()
if IsValid( physObj ) then
physObj:EnableMotion( false )
end
WheelModel:SetPos( Pos + Right * offset )
WheelModel:SetParent( Wheel )
end
end
end
local function ApplyWheel(ent, data)
ent.CustomWheelAngleOffset = data[2]
ent.CustomWheelAngleOffset_R = data[4]
timer.Simple( 0.05, function()
if not IsValid( ent ) then return end
for i = 1, table.Count( ent.GhostWheels ) do
local Wheel = ent.GhostWheels[i]
if IsValid( Wheel ) then
local isfrontwheel = (i == 1 or i == 2)
local swap_y = (i == 2 or i == 4 or i == 6)
local angleoffset = isfrontwheel and ent.CustomWheelAngleOffset or ent.CustomWheelAngleOffset_R
local model = isfrontwheel and data[1] or data[3]
local fAng = ent:LocalToWorldAngles( ent.VehicleData.LocalAngForward )
local rAng = ent:LocalToWorldAngles( ent.VehicleData.LocalAngRight )
local Forward = fAng:Forward()
local Right = swap_y and -rAng:Forward() or rAng:Forward()
local Up = ent:GetUp()
local Camber = data[5] or 0
local ghostAng = Right:Angle()
local mirAng = swap_y and 1 or -1
ghostAng:RotateAroundAxis(Forward,angleoffset.p * mirAng)
ghostAng:RotateAroundAxis(Right,angleoffset.r * mirAng)
ghostAng:RotateAroundAxis(Up,-angleoffset.y)
ghostAng:RotateAroundAxis(Forward, Camber * mirAng)
Wheel:SetModelScale( 1 )
Wheel:SetModel( model )
Wheel:SetAngles( ghostAng )
timer.Simple( 0.05, function()
if not IsValid(Wheel) or not IsValid( ent ) then return end
local wheelsize = Wheel:OBBMaxs() - Wheel:OBBMins()
local radius = isfrontwheel and ent.FrontWheelRadius or ent.RearWheelRadius
local size = (radius * 2) / math.max(wheelsize.x,wheelsize.y,wheelsize.z)
Wheel:SetModelScale( size )
end)
end
end
end)
end
local function GetAngleFromSpawnlist( model )
if not model then print("invalid model") return Angle(0,0,0) end
model = string.lower( model )
local v_list = list.Get( "simfphys_vehicles" )
for listname, _ in pairs( v_list ) do
if v_list[listname].Members.CustomWheels then
local FrontWheel = v_list[listname].Members.CustomWheelModel
local RearWheel = v_list[listname].Members.CustomWheelModel_R
if FrontWheel then
FrontWheel = string.lower( FrontWheel )
end
if RearWheel then
RearWheel = string.lower( RearWheel )
end
if model == FrontWheel or model == RearWheel then
local Angleoffset = v_list[listname].Members.CustomWheelAngleOffset
if (Angleoffset) then
return Angleoffset
end
end
end
end
local list = list.Get( "simfphys_Wheels" )[model]
local output = list and list.Angle or Angle(0,0,0)
return output
end
function TOOL:LeftClick( trace )
if CLIENT then return true end
local Ent = trace.Entity
local ply = self:GetOwner()
if not istable(ply.TOOLMemory) then return end
local vname = ply.TOOLMemory.SpawnName
local Update = false
local VehicleList = list.Get( "simfphys_vehicles" )
local vehicle = VehicleList[ vname ]
if not vehicle then return false end
ply.LockRightClick = true
timer.Simple( 0.6, function() if IsValid( ply ) then ply.LockRightClick = false end end )
local SpawnPos = trace.HitPos + Vector(0,0,25) + (vehicle.SpawnOffset or Vector(0,0,0))
local SpawnAng = self:GetOwner():EyeAngles()
SpawnAng.pitch = 0
SpawnAng.yaw = SpawnAng.yaw + 180 + (vehicle.SpawnAngleOffset and vehicle.SpawnAngleOffset or 0)
SpawnAng.roll = 0
if simfphys.IsCar( Ent ) then
if vname ~= Ent:GetSpawn_List() then
ply:PrintMessage( HUD_PRINTTALK, vname.." is not compatible with "..Ent:GetSpawn_List() )
return
end
Update = true
else
Ent = simfphys.SpawnVehicle( ply, SpawnPos, SpawnAng, vehicle.Model, vehicle.Class, vname, vehicle )
end
if not IsValid( Ent ) then return end
undo.Create( "Vehicle" )
undo.SetPlayer( ply )
undo.AddEntity( Ent )
undo.SetCustomUndoText( "Undone " .. vehicle.Name )
undo.Finish( "Vehicle (" .. tostring( vehicle.Name ) .. ")" )
ply:AddCleanup( "vehicles", Ent )
timer.Simple( 0.5, function()
if not IsValid(Ent) then return end
local tsc = string.Explode( ",", ply.TOOLMemory.TireSmokeColor )
Ent:SetTireSmokeColor( Vector( tonumber(tsc[1]), tonumber(tsc[2]), tonumber(tsc[3]) ) )
Ent.Turbocharged = tobool( ply.TOOLMemory.HasTurbo )
Ent.Supercharged = tobool( ply.TOOLMemory.HasBlower )
Ent:SetEngineSoundPreset( math.Clamp( tonumber( ply.TOOLMemory.SoundPreset ), -1, 23) )
Ent:SetMaxTorque( math.Clamp( tonumber( ply.TOOLMemory.PeakTorque ), 20, 1000) )
Ent:SetDifferentialGear( math.Clamp( tonumber( ply.TOOLMemory.FinalGear ),0.2, 6 ) )
Ent:SetSteerSpeed( math.Clamp( tonumber( ply.TOOLMemory.SteerSpeed ), 1, 16 ) )
Ent:SetFastSteerAngle( math.Clamp( tonumber( ply.TOOLMemory.SteerAngFast ), 0, 1) )
Ent:SetFastSteerConeFadeSpeed( math.Clamp( tonumber( ply.TOOLMemory.SteerFadeSpeed ), 1, 5000 ) )
Ent:SetEfficiency( math.Clamp( tonumber( ply.TOOLMemory.Efficiency ) ,0.2,4) )
Ent:SetMaxTraction( math.Clamp( tonumber( ply.TOOLMemory.MaxTraction ) , 5,1000) )
Ent:SetTractionBias( math.Clamp( tonumber( ply.TOOLMemory.GripOffset ),-0.99,0.99) )
Ent:SetPowerDistribution( math.Clamp( tonumber( ply.TOOLMemory.PowerDistribution ) ,-1,1) )
Ent:SetBackFire( tobool( ply.TOOLMemory.HasBackfire ) )
Ent:SetDoNotStall( tobool( ply.TOOLMemory.DoesntStall ) )
Ent:SetIdleRPM( math.Clamp( tonumber( ply.TOOLMemory.IdleRPM ),1,25000) )
Ent:SetLimitRPM( math.Clamp( tonumber( ply.TOOLMemory.MaxRPM ),4,25000) )
Ent:SetRevlimiter( tobool( ply.TOOLMemory.HasRevLimiter ) )
Ent:SetPowerBandEnd( math.Clamp( tonumber( ply.TOOLMemory.PowerEnd ), 3, 25000) )
Ent:SetPowerBandStart( math.Clamp( tonumber( ply.TOOLMemory.PowerStart ) ,2 ,25000) )
Ent:SetTurboCharged( Ent.Turbocharged )
Ent:SetSuperCharged( Ent.Supercharged )
Ent:SetBrakePower( math.Clamp( tonumber( ply.TOOLMemory.BrakePower ), 0.1, 500) )
Ent:SetSoundoverride( ply.TOOLMemory.SoundOverride or "" )
Ent:SetLights_List( Ent.LightsTable or "no_lights" )
Ent:SetBulletProofTires( tobool( ply.TOOLMemory.HasBulletProofTires ) )
Ent.snd_horn = ply.TOOLMemory.HornSound
Ent.snd_blowoff = ply.TOOLMemory.snd_blowoff
Ent.snd_spool = ply.TOOLMemory.snd_spool
Ent.snd_bloweron = ply.TOOLMemory.snd_bloweron
Ent.snd_bloweroff = ply.TOOLMemory.snd_bloweroff
Ent:SetBackfireSound( ply.TOOLMemory.backfiresound or "" )
local Gears = {}
local Data = string.Explode( ",", ply.TOOLMemory.Gears )
for i = 1, table.Count( Data ) do
local gRatio = tonumber( Data[i] )
if isnumber( gRatio ) then
if i == 1 then
Gears[i] = math.Clamp( gRatio, -5, -0.001)
elseif i == 2 then
Gears[i] = 0
else
Gears[i] = math.Clamp( gRatio, 0.001, 5)
end
end
end
Ent.Gears = Gears
if istable( ply.TOOLMemory.SubMaterials ) then
for i = 0, table.Count( ply.TOOLMemory.SubMaterials ) do
Ent:SetSubMaterial( i, ply.TOOLMemory.SubMaterials[i] )
end
end
if ply.TOOLMemory.FrontDampingOverride and ply.TOOLMemory.FrontConstantOverride and ply.TOOLMemory.RearDampingOverride and ply.TOOLMemory.RearConstantOverride then
Ent.FrontDampingOverride = tonumber( ply.TOOLMemory.FrontDampingOverride )
Ent.FrontConstantOverride = tonumber( ply.TOOLMemory.FrontConstantOverride )
Ent.RearDampingOverride = tonumber( ply.TOOLMemory.RearDampingOverride )
Ent.RearConstantOverride = tonumber( ply.TOOLMemory.RearConstantOverride )
local data = {
[1] = {Ent.FrontConstantOverride,Ent.FrontDampingOverride},
[2] = {Ent.FrontConstantOverride,Ent.FrontDampingOverride},
[3] = {Ent.RearConstantOverride,Ent.RearDampingOverride},
[4] = {Ent.RearConstantOverride,Ent.RearDampingOverride},
[5] = {Ent.RearConstantOverride,Ent.RearDampingOverride},
[6] = {Ent.RearConstantOverride,Ent.RearDampingOverride}
}
local elastics = Ent.Elastics
if elastics then
for i = 1, table.Count( elastics ) do
local elastic = elastics[i]
if Ent.StrengthenSuspension == true then
if IsValid( elastic ) then
elastic:Fire( "SetSpringConstant", data[i][1] * 0.5, 0 )
elastic:Fire( "SetSpringDamping", data[i][2] * 0.5, 0 )
end
local elastic2 = elastics[i * 10]
if IsValid( elastic2 ) then
elastic2:Fire( "SetSpringConstant", data[i][1] * 0.5, 0 )
elastic2:Fire( "SetSpringDamping", data[i][2] * 0.5, 0 )
end
else
if IsValid( elastic ) then
elastic:Fire( "SetSpringConstant", data[i][1], 0 )
elastic:Fire( "SetSpringDamping", data[i][2], 0 )
end
end
end
end
end
Ent:SetFrontSuspensionHeight( tonumber( ply.TOOLMemory.FrontHeight ) )
Ent:SetRearSuspensionHeight( tonumber( ply.TOOLMemory.RearHeight ) )
local groups = string.Explode( ",", ply.TOOLMemory.BodyGroups)
for i = 1, table.Count( groups ) do
Ent:SetBodygroup(i, tonumber(groups[i]) )
end
Ent:SetSkin( ply.TOOLMemory.Skin )
local c = string.Explode( ",", ply.TOOLMemory.Color )
local Color = Color( tonumber(c[1]), tonumber(c[2]), tonumber(c[3]), tonumber(c[4]) )
local dot = Color.r * Color.g * Color.b * Color.a
Ent.OldColor = dot
Ent:SetColor( Color )
local data = {
Color = Color,
RenderMode = 0,
RenderFX = 0
}
duplicator.StoreEntityModifier( Ent, "colour", data )
if Update then
local PhysObj = Ent:GetPhysicsObject()
if not IsValid( PhysObj ) then return end
local freezeWhenDone = PhysObj:IsMotionEnabled()
local freezeWheels = {}
PhysObj:EnableMotion( false )
Ent:SetNotSolid( true )
local ResetPos = Ent:GetPos()
local ResetAng = Ent:GetAngles()
Ent:SetPos( ResetPos + Vector(0,0,30) )
Ent:SetAngles( Angle(0,ResetAng.y,0) )
for i = 1, table.Count( Ent.Wheels ) do
local Wheel = Ent.Wheels[ i ]
if IsValid( Wheel ) then
local wPObj = Wheel:GetPhysicsObject()
if IsValid( wPObj ) then
freezeWheels[ i ] = {}
freezeWheels[ i ].dofreeze = wPObj:IsMotionEnabled()
freezeWheels[ i ].pos = Wheel:GetPos()
freezeWheels[ i ].ang = Wheel:GetAngles()
Wheel:SetNotSolid( true )
wPObj:EnableMotion( true )
wPObj:Wake()
end
end
end
timer.Simple( 0.5, function()
if not IsValid( Ent ) then return end
if not IsValid( PhysObj ) then return end
PhysObj:EnableMotion( freezeWhenDone )
Ent:SetNotSolid( false )
Ent:SetPos( ResetPos )
Ent:SetAngles( ResetAng )
for i = 1, table.Count( freezeWheels ) do
local Wheel = Ent.Wheels[ i ]
if IsValid( Wheel ) then
local wPObj = Wheel:GetPhysicsObject()
Wheel:SetNotSolid( false )
if IsValid( wPObj ) then
wPObj:EnableMotion( freezeWheels[i].dofreeze )
end
Wheel:SetPos( freezeWheels[ i ].pos )
Wheel:SetAngles( freezeWheels[ i ].ang )
end
end
end)
end
if Ent.CustomWheels then
if Ent.GhostWheels then
timer.Simple( Update and 0.25 or 0, function()
if not IsValid( Ent ) then return end
if ply.TOOLMemory.WheelTool_Foffset and ply.TOOLMemory.WheelTool_Roffset then
SetWheelOffset( Ent, ply.TOOLMemory.WheelTool_Foffset, ply.TOOLMemory.WheelTool_Roffset )
end
if not ply.TOOLMemory.FrontWheelOverride and not ply.TOOLMemory.RearWheelOverride then return end
local front_model = ply.TOOLMemory.FrontWheelOverride or vehicle.Members.CustomWheelModel
local front_angle = GetAngleFromSpawnlist(front_model)
local camber = ply.TOOLMemory.Camber or 0
local rear_model = ply.TOOLMemory.RearWheelOverride or (vehicle.Members.CustomWheelModel_R and vehicle.Members.CustomWheelModel_R or front_model)
local rear_angle = GetAngleFromSpawnlist(rear_model)
if not front_model or not rear_model or not front_angle or not rear_angle then return end
if ValidateModel( front_model ) and ValidateModel( rear_model ) then
Ent.Camber = camber
ApplyWheel(Ent, {front_model,front_angle,rear_model,rear_angle,camber})
else
ply:PrintMessage( HUD_PRINTTALK, "selected wheel does not exist on the server")
end
end)
end
end
end)
return true
end
function TOOL:RightClick( trace )
if CLIENT then return true end
local ent = trace.Entity
local ply = self:GetOwner()
if ply.LockRightClick then ply:PrintMessage( HUD_PRINTTALK, "Duplicator is busy") return end
if not istable(ply.TOOLMemory) then
ply.TOOLMemory = {}
end
if not IsValid(ent) then
table.Empty( ply.TOOLMemory )
net.Start("sphys_dupe")
net.WriteTable( ply.TOOLMemory )
net.Send( ply )
return false
end
if not simfphys.IsCar( ent ) then return false end
self:GetVehicleData( ent, ply )
return true
end
function TOOL:Reload( trace )
return false
end