add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
TOOL.Category = "LVS"
TOOL.Name = "#AI Enabler"
TOOL.Command = nil
TOOL.ConfigName = ""
TOOL.ClientConVar[ "team" ] = "-1"
if CLIENT then
language.Add( "tool.lvsaienabler.name", "AI Enabler" )
language.Add( "tool.lvsaienabler.desc", "A tool used to enable/disable AI on LVS-Vehicles" )
language.Add( "tool.lvsaienabler.0", "Left click on a LVS-Vehicle to enable AI, Right click to disable." )
language.Add( "tool.lvsaienabler.1", "Left click on a LVS-Vehicle to enable AI, Right click to disable." )
end
function TOOL:LeftClick( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS and not ent.LFS then return end
if isfunction( ent.SetAI ) then
ent:SetAI( true )
end
if SERVER then
local Team = self:GetClientNumber( "team" )
if Team ~= -1 then
ent:SetAITEAM( math.Clamp( Team, 0, 3 ) )
end
end
return true
end
function TOOL:RightClick( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS and not ent.LFS then return end
if isfunction( ent.SetAI ) then
ent:SetAI( false )
end
return true
end
function TOOL:Reload( trace )
return false
end
function TOOL.BuildCPanel( CPanel )
CPanel:AddControl( "Header", { Text = "#tool.lvsaienabler.name", Description = "#tool.lvsaienabler.desc" } )
CPanel:AddControl( "Slider", { Label = "TeamOverride", Type = "Int", Min = -1, Max = 3, Command = "lvsaienabler_team" } )
end

View File

@@ -0,0 +1,98 @@
TOOL.Category = "LVS"
TOOL.Name = "#Engine Swap"
TOOL.Information = {
{ name = "left" },
{ name = "right" },
}
if CLIENT then
language.Add( "tool.lvscarengineswap.name", "Engine Swap" )
language.Add( "tool.lvscarengineswap.desc", "A tool used to swap engine sounds on [LVS] - Cars" )
language.Add( "tool.lvscarengineswap.left", "Apply Engine Sound" )
language.Add( "tool.lvscarengineswap.right", "Copy Engine Sound" )
end
local function SwapEngine( ent, data )
if not IsValid( ent ) or not istable( data ) then return end
local originalEngine = ent:GetEngine()
if not IsValid( originalEngine ) then return end
local Engine = ents.Create( "lvs_wheeldrive_engine_swapped" )
Engine:SetPos( originalEngine:GetPos() )
Engine:SetAngles( originalEngine:GetAngles() )
Engine:Spawn()
Engine:Activate()
Engine:SetParent( ent )
Engine:SetBase( ent )
Engine.EngineSounds = data
Engine:SetDoorHandler( originalEngine:GetDoorHandler() )
ent:SetEngine( Engine )
ent:DeleteOnRemove( Engine )
ent:TransferCPPI( Engine )
originalEngine:Remove()
if not duplicator or not duplicator.StoreEntityModifier then return end
duplicator.StoreEntityModifier( ent, "lvsCarSwapEngine", data )
end
local function DuplicatorSwapEngine( ply, ent, data )
timer.Simple(0.1, function()
if not IsValid( ent ) then return end
SwapEngine( ent, data )
end )
end
if duplicator and duplicator.RegisterEntityModifier then
duplicator.RegisterEntityModifier( "lvsCarSwapEngine", DuplicatorSwapEngine )
end
function TOOL:SwapEngine( ent )
if CLIENT then return end
SwapEngine( ent, self.EngineSounds )
end
function TOOL:IsValidTarget( ent )
if not IsValid( ent ) then return false end
if not ent.LVS or not ent.lvsAllowEngineTool then return false end
return true
end
function TOOL:LeftClick( trace )
if not self.EngineSounds then return false end
local ent = trace.Entity
if not self:IsValidTarget( ent ) then return false end
self:SwapEngine( ent )
return true
end
function TOOL:RightClick( trace )
local ent = trace.Entity
if not self:IsValidTarget( ent ) then return false end
self.EngineSounds = ent.EngineSounds
return true
end
function TOOL:Reload( trace )
return false
end

View File

@@ -0,0 +1,83 @@
TOOL.Category = "LVS"
TOOL.Name = "#Tuning Remover"
TOOL.Information = {
{ name = "left" },
{ name = "right" },
}
if CLIENT then
language.Add( "tool.lvscartuningremover.name", "Tuning Remover" )
language.Add( "tool.lvscartuningremover.desc", "A tool used to remove Turbo + Compressor on [LVS-Cars]" )
language.Add( "tool.lvscartuningremover.left", "Remove Turbo" )
language.Add( "tool.lvscartuningremover.right", "Remove Compressor" )
end
function TOOL:IsValidTarget( ent )
if not IsValid( ent ) then return false end
if not ent.LVS or not ent.GetCompressor or not ent.GetTurbo then return false end
return true
end
local function DoRemoveEntity( ent )
timer.Simple( 1, function() if ( IsValid( ent ) ) then ent:Remove() end end )
ent:SetNotSolid( true )
ent:SetMoveType( MOVETYPE_NONE )
ent:SetNoDraw( true )
local ed = EffectData()
ed:SetOrigin( ent:GetPos() )
ed:SetEntity( ent )
util.Effect( "entity_remove", ed, true, true )
end
function TOOL:LeftClick( trace )
local ent = trace.Entity
if not self:IsValidTarget( ent ) then return false end
local Turbo = ent:GetTurbo()
local Compressor = ent:GetCompressor()
local Removed = false
if IsValid( Turbo ) and not Turbo._RemoveRememberThis then
Turbo._RemoveRememberThis = true
if SERVER then DoRemoveEntity( Turbo ) end
Removed = true
end
return Removed
end
function TOOL:RightClick( trace )
local ent = trace.Entity
if not self:IsValidTarget( ent ) then return false end
local Turbo = ent:GetTurbo()
local Compressor = ent:GetCompressor()
local Removed = false
if IsValid( Compressor ) and not Compressor._RemoveRememberThis then
Compressor._RemoveRememberThis = true
if SERVER then DoRemoveEntity( Compressor ) end
Removed = true
end
return Removed
end
function TOOL:Reload( trace )
return false
end

View File

@@ -0,0 +1,578 @@
TOOL.Category = "LVS"
TOOL.Name = "#Wheel Editor"
TOOL.ClientConVar[ "model" ] = "models/props_vehicles/carparts_wheel01a.mdl"
TOOL.ClientConVar[ "camber" ] = 0
TOOL.ClientConVar[ "caster" ] = 0
TOOL.ClientConVar[ "toe" ] = 0
TOOL.ClientConVar[ "height" ] = 0
TOOL.ClientConVar[ "stiffness" ] = 0
TOOL.ClientConVar[ "skin" ] = 0
TOOL.ClientConVar[ "bodygroup0" ] = 0
TOOL.ClientConVar[ "bodygroup1" ] = 0
TOOL.ClientConVar[ "bodygroup2" ] = 0
TOOL.ClientConVar[ "bodygroup3" ] = 0
TOOL.ClientConVar[ "bodygroup4" ] = 0
TOOL.ClientConVar[ "bodygroup5" ] = 0
TOOL.ClientConVar[ "bodygroup6" ] = 0
TOOL.ClientConVar[ "bodygroup7" ] = 0
TOOL.ClientConVar[ "bodygroup8" ] = 0
TOOL.ClientConVar[ "bodygroup9" ] = 0
TOOL.ClientConVar[ "pp0" ] = 0
TOOL.ClientConVar[ "pp1" ] = 0
TOOL.ClientConVar[ "pp2" ] = 0
TOOL.ClientConVar[ "pp3" ] = 0
TOOL.ClientConVar[ "pp4" ] = 0
TOOL.ClientConVar[ "pp5" ] = 0
TOOL.ClientConVar[ "pp6" ] = 0
TOOL.ClientConVar[ "pp7" ] = 0
TOOL.ClientConVar[ "pp8" ] = 0
TOOL.ClientConVar[ "pp9" ] = 0
TOOL.ClientConVar[ "r" ] = 255
TOOL.ClientConVar[ "g" ] = 255
TOOL.ClientConVar[ "b" ] = 255
TOOL.ClientConVar[ "a" ] = 255
TOOL.Information = {
{ name = "left" },
{ name = "right" },
{ name = "reload" }
}
if CLIENT then
language.Add( "tool.lvscarwheelchanger.name", "Wheel Editor" )
language.Add( "tool.lvscarwheelchanger.desc", "A tool used to edit [LVS-Cars] Wheels" )
language.Add( "tool.lvscarwheelchanger.left", "Apply wheel. Click again to flip 180 degrees" )
language.Add( "tool.lvscarwheelchanger.right", "Copy wheel" )
language.Add( "tool.lvscarwheelchanger.reload", "Apply camber/caster/toe/height/stiffness. Click again to flip camber and toe" )
local ContextMenuPanel
local skins = 0
local bodygroups = {}
local poseparameters = {}
local ConVarsDefault = TOOL:BuildConVarList()
local function BuildContextMenu()
if not IsValid( ContextMenuPanel ) then return end
ContextMenuPanel:Clear()
if IsValid( ContextMenuPanel.modelpanel ) then
ContextMenuPanel.modelpanel:Remove()
end
ContextMenuPanel:AddControl( "Header", { Text = "#tool.lvscarwheelchanger.name", Description = "#tool.lvscarwheelchanger.desc" } )
ContextMenuPanel:AddControl( "ComboBox", { MenuButton = 1, Folder = "lvswheels", Options = { [ "#preset.default" ] = ConVarsDefault }, CVars = table.GetKeys( ConVarsDefault ) } )
ContextMenuPanel:ColorPicker( "Wheel Color", "lvscarwheelchanger_r", "lvscarwheelchanger_g", "lvscarwheelchanger_b", "lvscarwheelchanger_a" )
if skins > 0 then
ContextMenuPanel:AddControl( "Label", { Text = "" } )
ContextMenuPanel:AddControl( "Label", { Text = "Skins" } )
ContextMenuPanel:AddControl("Slider", { Label = "Skin", Type = "int", Min = "0", Max = tostring( skins ), Command = "lvscarwheelchanger_skin" } )
end
local icon = vgui.Create( "DModelPanel", ContextMenuPanel )
icon:SetSize(200,200)
icon:SetFOV( 30 )
icon:SetAnimated( true )
icon:SetModel( GetConVar( "lvscarwheelchanger_model" ):GetString() )
icon:Dock( TOP )
icon:SetCamPos( Vector(80,0,0) )
icon:SetLookAt( vector_origin )
icon.Angles = angle_zero
function icon:DragMousePress()
self.PressX, self.PressY = gui.MousePos()
self.Pressed = true
end
function icon:DragMouseRelease()
self.Pressed = false
end
function icon:LayoutEntity( ent )
if self.Pressed then
local mx, my = gui.MousePos()
self.Angles:RotateAroundAxis( Vector(0,0,-1), ((self.PressX or mx) - mx) / 2 )
self.Angles:RotateAroundAxis( Vector(0,-1,0), ((self.PressY or my) - my) / 2 )
self.PressX, self.PressY = gui.MousePos()
end
ent:SetSkin( GetConVar( "lvscarwheelchanger_skin" ):GetInt() )
local R = GetConVar( "lvscarwheelchanger_r" ):GetInt()
local G = GetConVar( "lvscarwheelchanger_g" ):GetInt()
local B = GetConVar( "lvscarwheelchanger_b" ):GetInt()
local A = GetConVar( "lvscarwheelchanger_a" ):GetInt()
self:SetColor( Color(R,G,B,A) )
ent:SetAngles( self.Angles )
for id = 0, 9 do
ent:SetBodygroup( id, GetConVar( "lvscarwheelchanger_bodygroup"..id ):GetInt() )
end
for id, data in pairs( poseparameters ) do
if id > 9 then break end
if data.name == "#scale" then
local bonescale = math.Clamp( GetConVar( "lvscarwheelchanger_pp"..id ):GetFloat(), data.min, data.max )
local num = ent:GetBoneCount() - 1
for boneid = 0, num do
local bonename = ent:GetBoneName( boneid )
if not bonename or bonename == "__INVALIDBONE__" or not string.StartsWith( bonename, "#" ) then continue end
ent:ManipulateBoneScale( boneid, Vector(bonescale,bonescale,1) )
end
continue
end
ent:SetPoseParameter( data.name, GetConVar( "lvscarwheelchanger_pp"..id ):GetFloat() )
end
end
ContextMenuPanel.modelpanel = icon
if table.Count( poseparameters ) > 0 then
ContextMenuPanel:AddControl( "Label", { Text = "" } )
ContextMenuPanel:AddControl( "Label", { Text = "PoseParameters" } )
for id, data in pairs( poseparameters ) do
ContextMenuPanel:AddControl("Slider", { Label = data.name, Type = "float", Min = tostring( data.min ), Max = tostring( data.max ), Command = "lvscarwheelchanger_pp"..id } )
end
end
if #bodygroups > 0 then
ContextMenuPanel:AddControl( "Label", { Text = "" } )
ContextMenuPanel:AddControl( "Label", { Text = "BodyGroup" } )
for group, data in pairs( bodygroups ) do
local maxvalue = tostring( data.submodels )
if maxvalue == "0" then continue end
ContextMenuPanel:AddControl("Slider", { Label = data.name, Type = "int", Min = "0", Max = maxvalue, Command = "lvscarwheelchanger_bodygroup"..group } )
end
end
ContextMenuPanel:AddControl( "Label", { Text = "" } )
ContextMenuPanel:AddControl( "Label", { Text = "Alignment Specs" } )
ContextMenuPanel:AddControl( "Label", { Text = "- Wheel" } )
ContextMenuPanel:AddControl("Slider", { Label = "Camber", Type = "float", Min = "-15", Max = "15", Command = "lvscarwheelchanger_camber" } )
ContextMenuPanel:AddControl("Slider", { Label = "Caster", Type = "float", Min = "-15", Max = "15", Command = "lvscarwheelchanger_caster" } )
ContextMenuPanel:AddControl("Slider", { Label = "Toe", Type = "float", Min = "-30", Max = "30", Command = "lvscarwheelchanger_toe" } )
ContextMenuPanel:AddControl( "Label", { Text = "- Suspension" } )
ContextMenuPanel:AddControl("Slider", { Label = "Height", Type = "float", Min = "-1", Max = "1", Command = "lvscarwheelchanger_height" } )
ContextMenuPanel:AddControl("Slider", { Label = "Stiffness", Type = "float", Min = "-1", Max = "1", Command = "lvscarwheelchanger_stiffness" } )
-- purpose: avoid bullshit concommand system and avoid players abusing it
for mdl, _ in pairs( list.Get( "lvs_wheels" ) or {} ) do
list.Set( "lvs_wheels_selection", mdl, {} )
end
ContextMenuPanel:AddControl( "Label", { Text = "" } )
ContextMenuPanel:AddControl( "Label", { Text = "Wheel Models" } )
ContextMenuPanel:AddControl( "PropSelect", { Label = "", ConVar = "lvscarwheelchanger_model", Height = 0, Models = list.Get( "lvs_wheels_selection" ) } )
end
local function SetModel( name )
local ModelInfo = util.GetModelInfo( name )
if ModelInfo and ModelInfo.SkinCount then
skins = ModelInfo.SkinCount - 1
else
skins = 0
end
local bgroupmdl = ents.CreateClientProp()
bgroupmdl:SetModel( name )
bgroupmdl:Spawn()
table.Empty( bodygroups )
table.Empty( poseparameters )
for _, bgroup in pairs( bgroupmdl:GetBodyGroups() ) do
bodygroups[ bgroup.id ] = {
name = bgroup.name,
submodels = #bgroup.submodels,
}
end
local num = bgroupmdl:GetNumPoseParameters()
if num > 0 then
for i = 0, num - 1 do
local min, max = bgroupmdl:GetPoseParameterRange( i )
local name = bgroupmdl:GetPoseParameterName( i )
local pp_cvar = GetConVar( "lvscarwheelchanger_pp"..i )
if name == "#scale" and pp_cvar then
local val = pp_cvar:GetFloat()
if val > max or val < min then
pp_cvar:SetFloat( math.Clamp( 1, min, max ) )
end
end
poseparameters[ i ] = {
name = name,
min = min,
max = max,
}
end
end
bgroupmdl:Remove()
BuildContextMenu()
end
function TOOL.BuildCPanel( panel )
ContextMenuPanel = panel
BuildContextMenu()
end
cvars.AddChangeCallback( "lvscarwheelchanger_model", function( convar, oldValue, newValue )
SetModel( newValue )
end)
end
local function DuplicatorSaveCarWheels( ent )
if CLIENT then return end
local base = ent:GetBase()
if not IsValid( base ) then return end
local data = {}
for id, wheel in pairs( base:GetWheels() ) do
if not IsValid( wheel ) then continue end
local wheeldata = {}
wheeldata.ID = id
wheeldata.Model = wheel:GetModel()
wheeldata.ModelScale = wheel:GetModelScale()
wheeldata.Skin = wheel:GetSkin()
wheeldata.Camber = wheel:GetCamber()
wheeldata.Caster = wheel:GetCaster()
wheeldata.Toe = wheel:GetToe()
wheeldata.Height = wheel:GetSuspensionHeight()
wheeldata.Stiffness = wheel:GetSuspensionStiffness()
wheeldata.AlignmentAngle = wheel:GetAlignmentAngle()
wheeldata.Color = wheel:GetColor()
wheeldata.BodyGroups = {}
for id = 0, 9 do
wheeldata.BodyGroups[ id ] = wheel:GetBodygroup( id )
end
wheeldata.PoseParameters = {}
for id = 0, 9 do
wheeldata.PoseParameters[ id ] = wheel:GetPoseParameter( wheel:GetPoseParameterName( id ) )
end
table.insert( data, wheeldata )
end
if not duplicator or not duplicator.StoreEntityModifier then return end
duplicator.StoreEntityModifier( base, "lvsCarWheels", data )
end
local function DuplicatorApplyCarWheels( ply, ent, data )
if CLIENT then return end
timer.Simple(0.1, function()
if not IsValid( ent ) then return end
for id, wheel in pairs( ent:GetWheels() ) do
for _, wheeldata in pairs( data ) do
if not wheeldata or wheeldata.ID ~= id then continue end
if wheeldata.Model then wheel:SetModel( wheeldata.Model ) end
if wheeldata.ModelScale then wheel:SetModelScale( wheeldata.ModelScale ) end
if wheeldata.Skin then wheel:SetSkin( wheeldata.Skin ) end
if wheeldata.Camber then wheel:SetCamber( wheeldata.Camber ) end
if wheeldata.Caster then wheel:SetCaster( wheeldata.Caster ) end
if wheeldata.Toe then wheel:SetToe( wheeldata.Toe ) end
if wheeldata.AlignmentAngle then wheel:SetAlignmentAngle( wheeldata.AlignmentAngle ) end
if wheeldata.Color then wheel:SetColor( wheeldata.Color ) end
if wheeldata.Height then wheel:SetSuspensionHeight( wheeldata.Height ) end
if wheeldata.Stiffness then wheel:SetSuspensionStiffness( wheeldata.Stiffness ) end
timer.Simple(0, function()
if not IsValid( wheel ) then return end
if wheeldata.BodyGroups then
for group, subgroup in pairs( wheeldata.BodyGroups ) do
if subgroup == 0 then continue end
wheel:SetBodygroup( group, subgroup )
end
end
if wheeldata.PoseParameters and wheel:GetNumPoseParameters() > 0 then
for id, pose in pairs( wheeldata.PoseParameters ) do
local name = wheel:GetPoseParameterName( id )
wheel:StartThink()
wheel:SetPoseParameter( name, pose )
if name == "#scale" then
local min, max = wheel:GetPoseParameterRange( id )
local num = wheel:GetBoneCount() - 1
local bonescale = math.Clamp( pose, min, max )
for boneid = 0, num do
local bonename = wheel:GetBoneName( boneid )
if not bonename or bonename == "__INVALIDBONE__" or not string.StartsWith( bonename, "#" ) then continue end
wheel:ManipulateBoneScale( boneid, Vector(bonescale,bonescale,1) )
end
continue
end
end
end
end)
wheel:CheckAlignment()
wheel:PhysWake()
end
end
end)
end
if duplicator and duplicator.RegisterEntityModifier then
duplicator.RegisterEntityModifier( "lvsCarWheels", DuplicatorApplyCarWheels )
end
function TOOL:IsValidTarget( ent )
if not IsValid( ent ) then return false end
local class = ent:GetClass()
return class == "lvs_wheeldrive_wheel"
end
function TOOL:GetData( ent )
if CLIENT then return end
local ply = self:GetOwner()
if not IsValid( ply ) then return end
self.radius = ent:GetRadius() * (1 / ent:GetModelScale())
self.ang = ent:GetAlignmentAngle()
self.mdl = ent:GetModel()
ply:ConCommand( [[lvscarwheelchanger_model "]]..self.mdl..[["]] )
ply:ConCommand( "lvscarwheelchanger_skin "..ent:GetSkin() )
local clr = ent:GetColor()
ply:ConCommand( "lvscarwheelchanger_r " .. clr.r )
ply:ConCommand( "lvscarwheelchanger_g " .. clr.g )
ply:ConCommand( "lvscarwheelchanger_b " .. clr.b )
ply:ConCommand( "lvscarwheelchanger_a " .. clr.a )
for id = 0, 9 do
local group = ent:GetBodygroup( id ) or 0
ply:ConCommand( "lvscarwheelchanger_bodygroup"..id.." "..group )
end
for id = 0, 9 do
local pp = ent:GetPoseParameter( ent:GetPoseParameterName( id ) )
ply:ConCommand( "lvscarwheelchanger_pp"..id.." "..pp )
end
ply:ConCommand( "lvscarwheelchanger_camber "..ent:GetCamber() )
ply:ConCommand( "lvscarwheelchanger_caster "..ent:GetCaster() )
ply:ConCommand( "lvscarwheelchanger_toe "..ent:GetToe() )
ply:ConCommand( "lvscarwheelchanger_height "..ent:GetSuspensionHeight() )
ply:ConCommand( "lvscarwheelchanger_stiffness "..ent:GetSuspensionStiffness() )
end
function TOOL:SetData( ent )
if CLIENT then return end
local mdl = self:GetClientInfo("model")
if mdl ~= "" then
local data = list.Get( "lvs_wheels" )[ mdl ]
if data then
self.mdl = mdl
self.ang = data.angle
self.radius = data.radius
end
end
if not isstring( self.mdl ) or not isangle( self.ang ) or not isnumber( self.radius ) then return end
local r = self:GetClientNumber( "r", 0 )
local g = self:GetClientNumber( "g", 0 )
local b = self:GetClientNumber( "b", 0 )
local a = self:GetClientNumber( "a", 0 )
ent:SetColor( Color( r, g, b, a ) )
ent:SetSkin( self:GetClientNumber( "skin", 0 ) )
timer.Simple(0, function()
if not IsValid( ent ) then return end
for id = 0, 9 do
ent:SetBodygroup( id, self:GetClientNumber( "bodygroup"..id, 0 ) )
end
local num = ent:GetNumPoseParameters()
if num > 0 then
for id = 0, 9 do
if id > num - 1 then break end
local name = ent:GetPoseParameterName( id )
local pose = self:GetClientNumber( "pp"..id, 0 )
ent:StartThink()
ent:SetPoseParameter( name, pose )
if name == "#scale" then
local min, max = ent:GetPoseParameterRange( id )
local num = ent:GetBoneCount() - 1
local bonescale = math.Clamp( pose, min, max )
for boneid = 0, num do
local bonename = ent:GetBoneName( boneid )
if not bonename or bonename == "__INVALIDBONE__" or not string.StartsWith( bonename, "#" ) then continue end
ent:ManipulateBoneScale( boneid, Vector(bonescale,bonescale,1) )
end
continue
end
end
end
end)
if ent:GetModel() == self.mdl then
local Ang = ent:GetAlignmentAngle()
Ang:RotateAroundAxis( Vector(0,0,1), 180 )
ent:SetAlignmentAngle( Ang )
else
ent:SetModel( self.mdl )
ent:SetAlignmentAngle( self.ang )
timer.Simple(0.05, function()
if not IsValid( ent ) then return end
ent:SetModelScale( ent:GetRadius() / self.radius )
end)
end
timer.Simple(0.1, function()
if not IsValid( ent ) then return end
DuplicatorSaveCarWheels( ent )
end)
end
function TOOL:LeftClick( trace )
if not self:IsValidTarget( trace.Entity ) then return false end
self:SetData( trace.Entity )
if CLIENT then return true end
local ent = trace.Entity
timer.Simple(0, function()
if not IsValid( ent ) then return end
local effectdata = EffectData()
effectdata:SetOrigin( ent:GetPos() )
effectdata:SetEntity( ent )
util.Effect( "lvs_upgrade", effectdata )
end)
return true
end
function TOOL:RightClick( trace )
if not self:IsValidTarget( trace.Entity ) then return false end
self:GetData( trace.Entity )
if CLIENT then return true end
local ent = trace.Entity
timer.Simple(0, function()
if not IsValid( ent ) then return end
local effectdata = EffectData()
effectdata:SetOrigin( ent:GetPos() )
effectdata:SetEntity( ent )
util.Effect( "lvs_update", effectdata )
end)
return true
end
function TOOL:Reload( trace )
local ent = trace.Entity
if not self:IsValidTarget( ent ) then return false end
if CLIENT then return true end
timer.Simple(0, function()
if not IsValid( ent ) then return end
local effectdata = EffectData()
effectdata:SetOrigin( ent:GetPos() )
effectdata:SetEntity( ent )
util.Effect( "lvs_downgrade", effectdata )
end)
local camber = math.Round( self:GetClientNumber("camber",0) , 2 )
local caster = math.Round( self:GetClientNumber("caster",0) , 2 )
local toe = math.Round( self:GetClientNumber("toe",0) , 2 )
if math.Round( ent:GetCamber(), 2 ) == camber and math.Round( ent:GetToe(), 2 ) == toe and math.Round( ent:GetCaster(), 2 ) == caster then
ent:SetCamber( -camber )
ent:SetToe( -toe )
else
ent:SetCamber( camber )
ent:SetToe( toe )
end
ent:SetCaster( caster )
local NewTraction = math.min( math.Round( (ent:CheckAlignment() or 0) * 100, 0 ), 120 )
local ply = self:GetOwner()
if IsValid( ply ) and ply:IsPlayer() then
ply:ChatPrint( "Estimated Traction: "..NewTraction.."%" )
end
ent:SetSuspensionHeight( self:GetClientInfo("height") )
ent:SetSuspensionStiffness( self:GetClientInfo("stiffness") )
ent:PhysWake()
DuplicatorSaveCarWheels( ent )
return true
end
list.Set( "lvs_wheels", "models/props_vehicles/carparts_wheel01a.mdl", {angle = Angle(0,90,0), radius = 16} )

View File

@@ -0,0 +1,117 @@
TOOL.Category = "LVS"
TOOL.Name = "#tool.lvshealthshieldeditor.name"
TOOL.Command = nil
TOOL.ConfigName = ""
TOOL.ClientConVar[ "maxshield" ] = 0
TOOL.ClientConVar[ "maxhealth" ] = 5000
if CLIENT then
language.Add( "tool.lvshealthshieldeditor.name", "Max Health & Shield Editor" )
language.Add( "tool.lvshealthshieldeditor.desc", "A tool used to edit Max Health & Shield on LVS-Vehicles" )
language.Add( "tool.lvshealthshieldeditor.0", "Left click on a LVS-Vehicle to set Max Health, Right click to set Max Shield, Reload to reset." )
language.Add( "tool.lvshealthshieldeditor.1", "Left click on a LVS-Vehicle to set Max Health, Right click to set Max Shield, Reload to reset." )
language.Add( "tool.lvshealthshieldeditor.maxshield", "Max Shield" )
language.Add( "tool.lvshealthshieldeditor.maxhealth", "Max Health" )
end
function TOOL:LeftClick( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS and not ent.LFS then return end
if not ent.OGMaxHealth then
ent.OGMaxHealth = ent.MaxHealth
end
ent.MaxHealth = self:GetClientNumber( "maxhealth" )
ent:SetHP( ent.MaxHealth )
return true
end
function TOOL:RightClick( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS and not ent.LFS then return end
if not ent.OGMaxShield then
ent.OGMaxShield = ent.MaxShield
end
ent.MaxShield = self:GetClientNumber( "maxshield" )
ent:SetShield( ent.MaxShield )
return true
end
function TOOL:Reload( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS and not ent.LFS then return end
if ent.OGMaxHealth then
ent.MaxHealth = ent.OGMaxHealth
end
if ent.OGMaxShield then
ent.MaxShield = ent.OGMaxShield
end
ent:SetHP( ent.MaxHealth )
ent:SetShield( ent.MaxShield )
return true
end
function TOOL:Think()
if SERVER then return end
local ply = LocalPlayer()
local tr = ply:GetEyeTrace()
local ent = tr.Entity
if not IsValid( ent ) then return end
if not ent.LVS and not ent.LFS then return end
local Text = "Health: "..tostring( math.Round( ent:GetHP(), 0 ) ).."/"..tostring( ent.MaxHealth )
if ent:GetShield() > 0 then
Text = Text.."\nShield: "..tostring( math.Round( ent:GetShield(), 0 ) ).."/"..tostring( ent.MaxShield )
end
AddWorldTip( ent:EntIndex(), Text, SysTime() + 0.05, ent:GetPos(), ent )
end
function TOOL.BuildCPanel( panel )
panel:AddControl( "Header", { Text = "#tool.lvshealthshieldeditor.name", Description = "#tool.lvshealthshieldeditor.desc" } )
panel:AddControl( "Slider",
{
Label = "#tool.lvshealthshieldeditor.maxhealth",
Type = "Int",
Min = "1",
Max = "50000",
Command = "lvshealthshieldeditor_maxhealth",
Help = false
})
panel:AddControl( "Slider",
{
Label = "#tool.lvshealthshieldeditor.maxshield",
Type = "Int",
Min = "0",
Max = "50000",
Command = "lvshealthshieldeditor_maxshield",
Help = false
})
panel:AddControl( "Label", { Text = "NOTE: Value in Edit-Properties menu will still be the same, because they can not be updated after the vehicle is spawned!" } )
end

View File

@@ -0,0 +1,45 @@
TOOL.Category = "LVS"
TOOL.Name = "#Transmission Editor"
TOOL.Command = nil
TOOL.ConfigName = ""
if CLIENT then
language.Add( "tool.lvstransmission.name", "Transmission Editor" )
language.Add( "tool.lvstransmission.desc", "A tool used to enable/disable Manual Transmission on LVS-Cars" )
language.Add( "tool.lvstransmission.0", "Left click on a LVS-Car to enable Manual Transmission. Right click to disable." )
language.Add( "tool.lvstransmission.1", "Left click on a LVS-Car to enable Manual Transmission. Right click to disable." )
end
function TOOL:LeftClick( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS then return end
if isfunction( ent.SetNWGear ) and isfunction( ent.SetReverse ) then
ent:SetNWGear( 1 )
ent:SetReverse( false )
end
return true
end
function TOOL:RightClick( trace )
local ent = trace.Entity
if not IsValid( ent ) then return false end
if not ent.LVS then return end
if isfunction( ent.SetNWGear ) then
ent:SetNWGear( -1 )
end
return true
end
function TOOL:Reload( trace )
return false
end

View File

@@ -0,0 +1,144 @@
TOOL.Category = "LVS"
TOOL.Name = "#tool.lvsturret.name"
TOOL.Command = nil
TOOL.ConfigName = ""
cleanup.Register( "lvsturret" )
CreateConVar("sbox_maxlvsturret", 1, "FCVAR_NOTIFY")
TOOL.ClientConVar[ "delay" ] = "0.05"
TOOL.ClientConVar[ "damage" ] = "15"
TOOL.ClientConVar[ "speed" ] = "30000"
TOOL.ClientConVar[ "size" ] = "1"
TOOL.ClientConVar[ "spread" ] = "0"
TOOL.ClientConVar[ "penetration" ] = "10"
TOOL.ClientConVar[ "splashdamage" ] = "0"
TOOL.ClientConVar[ "splashradius" ] = "0"
TOOL.ClientConVar[ "tracer" ] = "lvs_tracer_orange"
TOOL.ClientConVar[ "splasheffect" ] = "lvs_bullet_impact"
if CLIENT then
language.Add( "tool.lvsturret.name", "Projectile Turret" )
language.Add( "tool.lvsturret.desc", "A Tool used to spawn Turrets" )
language.Add( "tool.lvsturret.0", "Left click to spawn or update a turret" )
language.Add( "tool.lvsturret.1", "Left click to spawn or update a turret" )
language.Add( "Cleanup_lvsturret", "[LVS] Projectile Turret" )
language.Add( "Cleaned_lvsturret", "Cleaned up all [LVS] Projectile Turrets" )
language.Add( "SBoxLimit_lvsturret", "You've reached the Projectile Turret limit!" )
end
function TOOL:LeftClick( trace )
if CLIENT then return true end
local ply = self:GetOwner()
if not istable( WireLib ) then
ply:PrintMessage( HUD_PRINTTALK, "[LVS]: WIREMOD REQUIRED" )
ply:SendLua( "gui.OpenURL( 'https://steamcommunity.com/sharedfiles/filedetails/?id=160250458' )")
end
if IsValid( trace.Entity ) and trace.Entity:GetClass():lower() == "lvs_turret" then
self:UpdateTurret( trace.Entity )
else
local turret = self:MakeTurret( ply, trace.HitPos + trace.HitNormal * 5 )
undo.Create("Turret")
undo.AddEntity( turret )
undo.SetPlayer( ply )
undo.Finish()
end
return true
end
function TOOL:RightClick( trace )
return false
end
if SERVER then
function TOOL:UpdateTurret( ent )
if not IsValid( ent ) then return end
ent:SetShootDelay( self:GetClientNumber( "delay" ) )
ent:SetDamage( math.Clamp( self:GetClientNumber( "damage" ), 0, 1000 ) )
ent:SetSpeed( math.Clamp( self:GetClientNumber( "speed" ), 10000, 100000 ) )
ent:SetSize( math.Clamp( self:GetClientNumber( "size" ), 0, 50 ) )
ent:SetSpread( math.Clamp( self:GetClientNumber( "spread" ), 0, 1 ) )
ent:SetPenetration( math.Clamp( self:GetClientNumber( "penetration" ), 0, 500 ) )
ent:SetSplashDamage( math.Clamp( self:GetClientNumber( "splashdamage" ), 0, 1000 ) )
ent:SetSplashDamageRadius( math.Clamp( self:GetClientNumber( "splashradius" ), 0, 750 ) )
ent:SetTracer( self:GetClientInfo( "tracer" ) )
ent:SetSplashDamageType( self:GetClientInfo( "splasheffect" ) )
end
function TOOL:MakeTurret( ply, Pos, Ang )
if not ply:CheckLimit( "lvsturret" ) then return NULL end
local turret = ents.Create( "lvs_turret" )
if not IsValid( turret ) then return NULL end
turret:SetPos( Pos )
turret:SetAngles( Angle(0,0,0) )
turret:Spawn()
turret.Attacker = ply
self:UpdateTurret( turret )
ply:AddCount( "lvsturret", turret )
ply:AddCleanup( "lvsturret", turret )
return turret
end
end
local ConVarsDefault = TOOL:BuildConVarList()
function TOOL.BuildCPanel( CPanel )
CPanel:AddControl( "ComboBox", { MenuButton = 1, Folder = "lvs_turrets", Options = { [ "#preset.default" ] = ConVarsDefault }, CVars = table.GetKeys( ConVarsDefault ) } )
CPanel:AddControl( "Header", { Text = "#tool.lvsturret.name", Description = "#tool.lvsturret.desc" } )
local TracerEffect = {Label = "Tracer Effect", MenuButton = 0, Options={}, CVars = {}}
local TracerOptions = {
["LaserBlue"] = "lvs_laser_blue",
["LaserRed"] = "lvs_laser_red",
["LaserGreen"] = "lvs_laser_green",
["TracerGreen"] = "lvs_tracer_green",
["TracerOrange"] = "lvs_tracer_orange",
["TracerWhite"] = "lvs_tracer_white",
["TracerYellow"] = "lvs_tracer_yellow",
["AutoCannon"] = "lvs_tracer_autocannon",
["Cannon"] = "lvs_tracer_cannon",
}
for id, name in pairs( TracerOptions ) do
if not file.Exists( "effects/"..name..".lua", "LUA" ) then continue end
TracerEffect["Options"][id] = { lvsturret_tracer = name }
end
CPanel:AddControl("ComboBox", TracerEffect )
CPanel:AddControl( "Slider", { Label = "Shoot Delay", Type = "Float", Min = 0, Max = 2.0, Command = "lvsturret_delay" } )
CPanel:AddControl( "Slider", { Label = "Damage", Type = "Float", Min = 0, Max = 1000, Command = "lvsturret_damage" } )
CPanel:AddControl( "Slider", { Label = "Bullet Speed", Type = "Float", Min = 10000, Max = 100000, Command = "lvsturret_speed" } )
CPanel:AddControl( "Slider", { Label = "Bullet Spread", Type = "Float", Min = 0, Max = 1, Command = "lvsturret_spread" } )
CPanel:AddControl( "Slider", { Label = "Hull Size", Type = "Float", Min = 0, Max = 50, Command = "lvsturret_size" } )
CPanel:AddControl( "Slider", { Label = "Armor Penetration (mm)", Type = "Float", Min = 0, Max = 500, Command = "lvsturret_penetration" } )
CPanel:AddControl( "Slider", { Label = "Splash Damage", Type = "Float", Min = 0, Max = 1000, Command = "lvsturret_splashdamage" } )
CPanel:AddControl( "Slider", { Label = "Splash Radius", Type = "Float", Min = 0, Max = 750, Command = "lvsturret_splashradius" } )
local SplashType = {Label = "Splash Type", MenuButton = 0, Options={}, CVars = {}}
SplashType["Options"][ "Shrapnel" ] = { lvsturret_splasheffect = "lvs_bullet_impact" }
SplashType["Options"][ "Explosive" ] = { lvsturret_splasheffect = "lvs_bullet_impact_explosive" }
CPanel:AddControl("ComboBox", SplashType )
end

View File

@@ -0,0 +1,198 @@
AddCSLuaFile()
SWEP.Category = "[LVS]"
SWEP.Spawnable = true
SWEP.AdminSpawnable = false
SWEP.ViewModel = "models/weapons/c_scrubriglvs.mdl"
SWEP.WorldModel = "models/blu/lvsmine.mdl"
SWEP.UseHands = true
SWEP.ViewModelFlip = false
SWEP.ViewModelFOV = 60
SWEP.AutoSwitchTo = true
SWEP.AutoSwitchFrom = true
SWEP.HoldType = "slam"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = 3
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "slam"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
cleanup.Register( "lvsmine" )
CreateConVar("sbox_maxlvsmine", 10, "FCVAR_NOTIFY")
if CLIENT then
SWEP.PrintName = "Mines"
SWEP.Slot = 4
SWEP.SlotPos = 1
SWEP.DrawWeaponInfoBox = false
SWEP.pViewModel = ClientsideModel("models/blu/lvsmine.mdl", RENDERGROUP_OPAQUE)
SWEP.pViewModel:SetNoDraw( true )
function SWEP:ViewModelDrawn()
local ply = self:GetOwner()
if not IsValid( ply ) then return end
local vm = ply:GetViewModel()
local bm = vm:GetBoneMatrix( 1 )
if not bm then return end
local pos = bm:GetTranslation()
local ang = bm:GetAngles()
pos = pos + ang:Up() * 25
pos = pos + ang:Right() * 1
pos = pos + ang:Forward() * -3
ang:RotateAroundAxis(ang:Forward(),60)
ang:RotateAroundAxis(ang:Right(),170)
ang:RotateAroundAxis(ang:Up(),65)
self.pViewModel:SetModelScale( 0.75 )
self.pViewModel:SetPos( pos )
self.pViewModel:SetAngles( ang )
self.pViewModel:DrawModel()
end
function SWEP:DrawWorldModel()
local ply = self:GetOwner()
if not IsValid( ply ) then self:DrawModel() return end
local id = ply:LookupAttachment("anim_attachment_rh")
local attachment = ply:GetAttachment( id )
if not attachment then return end
local pos = attachment.Pos + attachment.Ang:Forward() * 2
local ang = attachment.Ang
ang:RotateAroundAxis(attachment.Ang:Up(), 20)
ang:RotateAroundAxis(attachment.Ang:Right(), -30)
ang:RotateAroundAxis(attachment.Ang:Forward(), 0)
self:SetRenderOrigin( pos )
self:SetRenderAngles( ang )
self:DrawModel()
end
function SWEP:DrawWeaponSelection( x, y, wide, tall, alpha )
draw.SimpleText( "z", "WeaponIcons", x + wide/2, y + tall*0.2, Color( 255, 210, 0, 255 ), TEXT_ALIGN_CENTER )
end
end
function SWEP:Initialize()
self:SetHoldType( self.HoldType )
end
function SWEP:OwnerChanged()
end
function SWEP:Think()
end
function SWEP:TakePrimaryAmmo( num )
local ply = self:GetOwner()
if self:Clip1() <= 0 then
if self:Ammo1() <= 0 then return end
ply:RemoveAmmo( num, self:GetPrimaryAmmoType() )
return
end
self:SetClip1( math.max(self:Clip1() - num,0) )
end
function SWEP:CanPrimaryAttack()
self.NextFire = self.NextFire or 0
return self.NextFire <= CurTime() and self:Ammo1() > 0
end
function SWEP:SetNextPrimaryFire( time )
self.NextFire = time
end
function SWEP:ThrowMine()
if CLIENT then return end
local ply = self:GetOwner()
if not ply:CheckLimit( "lvsmine" ) then return end
ply:EmitSound( "npc/zombie/claw_miss1.wav" )
local ent = ents.Create( "lvs_item_mine" )
if not IsValid( ent ) then return end
ent:SetPos( ply:GetShootPos() - Vector(0,0,10) )
ent:Spawn()
ent:Activate()
ent:SetAttacker( ply )
ply:AddCount( "lvsmine", ent )
ply:AddCleanup( "lvsmine", ent )
undo.Create("Mine")
undo.AddEntity( ent )
undo.SetPlayer( ply )
undo.Finish()
local PhysObj = ent:GetPhysicsObject()
if not IsValid( PhysObj ) then return end
PhysObj:SetVelocityInstantaneous( ply:GetAimVector() * 200 + Vector(0,0,150) )
PhysObj:AddAngleVelocity( VectorRand() * 20 )
end
function SWEP:PrimaryAttack()
if not self:CanPrimaryAttack() then return end
local ply = self:GetOwner()
ply:SetAnimation( PLAYER_ATTACK1 )
self:ThrowMine()
self:SetNextPrimaryFire( CurTime() + 1.5 )
self:TakePrimaryAmmo( 1 )
if SERVER then
if self:Ammo1() <= 0 then
ply:StripWeapon( "weapon_lvsmines" )
end
end
end
function SWEP:SecondaryAttack()
return false
end
function SWEP:Deploy()
self:SendWeaponAnim( ACT_SLAM_STICKWALL_DRAW )
return true
end
function SWEP:Holster()
return true
end

View File

@@ -0,0 +1,168 @@
AddCSLuaFile()
SWEP.Category = "[LVS]"
SWEP.Spawnable = true
SWEP.AdminSpawnable = false
SWEP.ViewModel = "models/weapons/c_scrubriglvs.mdl"
SWEP.WorldModel = "models/diggercars/shared/spikestrip_fold.mdl"
SWEP.UseHands = true
SWEP.ViewModelFlip = false
SWEP.ViewModelFOV = 60
SWEP.AutoSwitchTo = true
SWEP.AutoSwitchFrom = true
SWEP.HoldType = "physgun"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
cleanup.Register( "lvsspikestrip" )
if CLIENT then
SWEP.PrintName = "Spike Strip"
SWEP.Slot = 4
SWEP.SlotPos = 2
SWEP.DrawWeaponInfoBox = false
SWEP.pViewModel = ClientsideModel("models/diggercars/shared/spikestrip_fold.mdl", RENDERGROUP_OPAQUE)
SWEP.pViewModel:SetNoDraw( true )
function SWEP:ViewModelDrawn()
local ply = self:GetOwner()
if not IsValid( ply ) then return end
local vm = ply:GetViewModel()
local bm = vm:GetBoneMatrix(0)
if not bm then return end
local pos = bm:GetTranslation()
local ang = bm:GetAngles()
pos = pos + ang:Up() * 28
pos = pos + ang:Right() * 8
pos = pos + ang:Forward() * -5
ang:RotateAroundAxis(ang:Forward(), -210)
ang:RotateAroundAxis(ang:Right(),-60)
ang:RotateAroundAxis(ang:Up(), 90)
self.pViewModel:SetPos( pos )
self.pViewModel:SetAngles( ang )
self.pViewModel:DrawModel()
self.pViewModel:SetModelScale( 0.5 )
end
function SWEP:DrawWorldModel()
local ply = self:GetOwner()
if not IsValid( ply ) then self:DrawModel() return end
local id = ply:LookupAttachment("anim_attachment_rh")
local attachment = ply:GetAttachment( id )
if not attachment then return end
local pos = attachment.Pos + attachment.Ang:Forward() * 3 - attachment.Ang:Up() * 30
local ang = attachment.Ang
ang:RotateAroundAxis(attachment.Ang:Up(), -40)
ang:RotateAroundAxis(attachment.Ang:Right(), -90)
ang:RotateAroundAxis(attachment.Ang:Forward(), 0)
self:SetRenderOrigin( pos )
self:SetRenderAngles( ang )
self:DrawModel()
end
function SWEP:DrawWeaponSelection( x, y, wide, tall, alpha )
draw.SimpleText( "P", "WeaponIcons", x + wide/2, y + tall*0.2, Color( 255, 210, 0, 255 ), TEXT_ALIGN_CENTER )
end
end
function SWEP:Initialize()
self:SetHoldType( self.HoldType )
end
function SWEP:OwnerChanged()
end
function SWEP:Think()
end
if SERVER then
function SWEP:PlaceStrip()
local ply = self:GetOwner()
ply:EmitSound( "npc/zombie/claw_miss1.wav" )
local ent = ents.Create( "lvs_item_spikestrip_foldable" )
if not IsValid( ent ) then return end
ent:SetAngles( Angle(0,180 + ply:EyeAngles().y,0) )
ent:SetPos( ply:GetShootPos() - Vector(0,0,10) )
ent:Spawn()
ent:Activate()
ent:SetAttacker( ply )
ent:SetOwner( ply )
ply:AddCleanup( "lvsspikestrip", ent )
undo.Create("Spike Strip")
undo.AddEntity( ent )
undo.SetPlayer( ply )
undo.Finish()
local PhysObj = ent:GetPhysicsObject()
if not IsValid( PhysObj ) then return end
PhysObj:SetVelocityInstantaneous( ply:GetAimVector() * 200 + Vector(0,0,75) )
end
end
function SWEP:PrimaryAttack()
local ply = self:GetOwner()
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
ply:SetAnimation( PLAYER_ATTACK1 )
self:SetNextPrimaryFire( CurTime() + 1.5 )
if SERVER then
self:PlaceStrip()
ply:StripWeapon( "weapon_lvsspikestrip" )
end
end
function SWEP:SecondaryAttack()
return false
end
function SWEP:Deploy()
self:SendWeaponAnim( ACT_VM_DRAW )
return true
end
function SWEP:Holster()
return true
end
function SWEP:OnRemove()
end