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,71 @@
function LVS:CalcView( vehicle, ply, pos, angles, fov, pod )
local view = {}
view.origin = pos
view.angles = angles
view.fov = fov
view.drawviewer = false
if not pod:GetThirdPersonMode() then return view end
local mn = vehicle:OBBMins()
local mx = vehicle:OBBMaxs()
local radius = ( mn - mx ):Length()
local radius = radius + radius * pod:GetCameraDistance()
local TargetOrigin = view.origin + ( view.angles:Forward() * -radius ) + view.angles:Up() * radius * pod:GetCameraHeight()
local WallOffset = 4
local tr = util.TraceHull( {
start = view.origin,
endpos = TargetOrigin,
filter = function( e )
local c = e:GetClass()
local collide = not c:StartWith( "prop_physics" ) and not c:StartWith( "prop_dynamic" ) and not c:StartWith( "prop_ragdoll" ) and not e:IsVehicle() and not c:StartWith( "gmod_" ) and not c:StartWith( "lvs_" ) and not c:StartWith( "player" ) and not e.LVS
return collide
end,
mins = Vector( -WallOffset, -WallOffset, -WallOffset ),
maxs = Vector( WallOffset, WallOffset, WallOffset ),
} )
view.origin = tr.HitPos
view.drawviewer = true
if tr.Hit and not tr.StartSolid then
view.origin = view.origin + tr.HitNormal * WallOffset
end
return view
end
hook.Add( "CalcView", "!!!!LVS_calcview", function(ply, pos, angles, fov)
if ply:GetViewEntity() ~= ply then return end
local pod = ply:GetVehicle()
local vehicle = ply:lvsGetVehicle()
if not IsValid( pod ) or not IsValid( vehicle ) then return end
local newfov = vehicle:LVSCalcFov( fov, ply )
local base = pod:lvsGetWeapon()
if IsValid( base ) then
local weapon = base:GetActiveWeapon()
if weapon and weapon.CalcView then
return ply:lvsSetView( weapon.CalcView( base, ply, pos, angles, newfov, pod ) )
else
return ply:lvsSetView( vehicle:LVSCalcView( ply, pos, angles, newfov, pod ) )
end
else
local weapon = vehicle:GetActiveWeapon()
if weapon and weapon.CalcView then
return ply:lvsSetView( weapon.CalcView( vehicle, ply, pos, angles, newfov, pod ) )
else
return ply:lvsSetView( vehicle:LVSCalcView( ply, pos, angles, newfov, pod ) )
end
end
end )

View File

@@ -0,0 +1,44 @@
local THE_FONT = {
font = "Verdana",
extended = false,
size = 14,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = true,
additive = false,
outline = false,
}
surface.CreateFont( "LVS_VERSION", THE_FONT )
THE_FONT.extended = false
THE_FONT.size = 20
THE_FONT.weight = 2000
surface.CreateFont( "LVS_FONT", THE_FONT )
THE_FONT.size = 16
surface.CreateFont( "LVS_FONT_SWITCHER", THE_FONT )
THE_FONT.font = "Arial"
THE_FONT.size = 14
THE_FONT.weight = 1
THE_FONT.shadow = false
surface.CreateFont( "LVS_FONT_PANEL", THE_FONT )
THE_FONT.size = 20
THE_FONT.weight = 2000
surface.CreateFont( "LVS_FONT_HUD", THE_FONT )
THE_FONT.size = 40
THE_FONT.weight = 2000
THE_FONT.shadow = true
surface.CreateFont( "LVS_FONT_HUD_LARGE", THE_FONT )
THE_FONT.size = 80
surface.CreateFont( "LVS_FONT_HUD_HUMONGOUS", THE_FONT )

View File

@@ -0,0 +1,345 @@
--LVS.HudForceDefault = true
LVS.HudEditors = LVS.HudEditors or {}
LVS.HudEditorsHide = {}
local function ResetFrame( id )
if not LVS.HudEditors[ id ] then return end
LVS.HudEditors[ id ].w = LVS.HudEditors[ id ].DefaultWidth
LVS.HudEditors[ id ].h = LVS.HudEditors[ id ].DefaultHeight
LVS.HudEditors[ id ].X = LVS.HudEditors[ id ].DefaultX
LVS.HudEditors[ id ].Y = LVS.HudEditors[ id ].DefaultY
LVS.HudEditorsHide[ id ] = nil
end
local function MakeFrame( id, X, Y, w, h, minw, minh, text )
local Frame = vgui.Create("DFrame")
Frame:SetSize( w, h )
Frame:SetPos( X, Y )
Frame:SetTitle( text )
Frame:SetScreenLock( true )
Frame:MakePopup()
Frame:SetSizable( true )
Frame:SetMinWidth( minw )
Frame:SetMinHeight( minh )
Frame.id = id
Frame.OnClose = function( self )
ResetFrame( self.id )
end
Frame.Paint = function(self, w, h )
surface.SetDrawColor(0,0,0,150)
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(80,80,80,255)
surface.DrawRect(0, 0, 2, h)
surface.DrawRect(w - 2, 0, 2, h)
surface.DrawRect(0, 0, w, 2)
surface.DrawRect(0, h - 2, w, 2)
if not LVS.HudEditors[ self.id ] then return end
local Width = self:GetWide()
local Height = self:GetTall()
LVS.HudEditors[ self.id ].w = Width
LVS.HudEditors[ self.id ].h = Height
LVS.HudEditors[ self.id ].X = math.min( self:GetX(), ScrW() - Width )
LVS.HudEditors[ self.id ].Y = math.min( self:GetY(), ScrH() - Height )
if self:IsDragging() or input.IsMouseDown( MOUSE_LEFT ) then return end
local Ratio = LVS.HudEditors[ self.id ].DefaultHeight / LVS.HudEditors[ self.id ].DefaultWidth
if math.Round( Height / Width, 2 ) ~= math.Round( Ratio ,2 ) then
local NewHeight = Width * Ratio
self:SetHeight( NewHeight )
LVS.HudEditors[ self.id ].h = NewHeight
end
end
local DCheckbox = vgui.Create( "DCheckBoxLabel", Frame )
DCheckbox:Dock( RIGHT )
DCheckbox:DockMargin( 0, 0, 0, 0 )
DCheckbox:SetText("Hide")
DCheckbox:SizeToContents()
DCheckbox.id = id
DCheckbox:SetChecked( LVS.HudEditorsHide[ id ] == true )
DCheckbox.OnChange = function( self, bVal )
if not self.id then return end
if bVal then LVS.HudEditorsHide[ self.id ] = true return end
LVS.HudEditorsHide[ self.id ] = nil
end
LVS.HudEditors[ id ].Frame = Frame
return Frame
end
local ScreenWidth = ScrW()
local ScreenHeight = ScrH()
local function SaveEditors()
if LVS.HudForceDefault then return end
if ScreenWidth ~= ScrW() or ScreenHeight ~= ScrH() then return end -- player changed resolution while ingame... don't save because everything is fucked up now...
local SaveString = ""
for id, data in pairs( LVS.HudEditors ) do
local w = data.w
local h = data.h
local X = math.min( data.X / ScrW(), 1 )
local Y = math.min( data.Y / ScrH(), 1 )
local hide = LVS.HudEditorsHide[ id ] and "?" or " "
SaveString = SaveString..id.."~"..hide.."~"..w.."#"..h.."/"..X.."#"..Y.."\n"
end
file.Write( "lvs_hud_settings.txt", SaveString )
end
local function LoadEditors()
if LVS.HudForceDefault then return end
local LoadString = file.Read( "lvs_hud_settings.txt" )
if not LoadString then return end
for _, garbage in pairs( string.Explode( "\n", LoadString ) ) do
local data1 = string.Explode( "~", garbage )
if not data1[3] then continue end
local data2 = string.Explode( "/", data1[3] )
local size = string.Explode( "#", data2[1] )
local pos = string.Explode( "#", data2[2] )
local ID = data1[1]
if not LVS.HudEditors[ ID ] or not size[1] or not size[2] or not pos[1] or not pos[2] then continue end
LVS.HudEditors[ ID ].w = math.max( LVS.HudEditors[ ID ].minw, size[1] )
LVS.HudEditors[ ID ].h = math.max( LVS.HudEditors[ ID ].minh, size[2] )
LVS.HudEditors[ ID ].X = math.min( pos[1] * ScrW(), ScrW() - size[1] )
LVS.HudEditors[ ID ].Y = math.min( pos[2] * ScrH(), ScrH() - size[2] )
if data1[2] == "?" then
LVS.HudEditorsHide[ ID ] = true
end
end
end
function LVS:AddHudEditor( id, X, Y, w, h, minw, minh, text, func )
LVS.HudEditors[ id ] = {
DefaultX = X,
DefaultY = Y,
DefaultWidth = w,
DefaultHeight = h,
X = X,
Y = Y,
w = w,
h = h,
minw = minw,
minh = minh,
text = text,
func = func,
}
end
hook.Add( "OnContextMenuOpen", "!!!!!LVS_hud", function()
if not IsValid( LocalPlayer():lvsGetVehicle() ) then return end
if not GetConVar( "lvs_edit_hud" ):GetBool() then return end
LVS:OpenEditors()
return false
end )
hook.Add( "InitPostEntity", "!!!lvs_load_hud", function()
LoadEditors()
end )
function LVS:OpenEditors()
for id, editor in pairs( LVS.HudEditors ) do
if IsValid( editor.Frame ) then continue end
MakeFrame( id, editor.X, editor.Y, editor.w, editor.h, editor.minw, editor.minh, editor.text )
end
local T = CurTime()
local ply = LocalPlayer()
local pod = ply:GetVehicle()
ply.SwitcherTime = T + 9999
if not IsValid( pod ) then return end
pod._SelectActiveTime = T + 9999
end
function LVS:CloseEditors()
SaveEditors()
for id, editor in pairs( LVS.HudEditors ) do
if not IsValid( editor.Frame ) then continue end
editor.Frame:Remove()
end
local T = CurTime()
local ply = LocalPlayer()
local pod = ply:GetVehicle()
ply.SwitcherTime = T
if not IsValid( pod ) then return end
pod._SelectActiveTime = T
end
hook.Add( "OnContextMenuClose", "!!!!!LVS_hud", function()
LVS:CloseEditors()
end )
function LVS:DrawDiamond( X, Y, radius, perc )
if perc <= 0 then return end
local segmentdist = 90
draw.NoTexture()
for a = 90, 360, segmentdist do
local Xa = math.Round( math.sin( math.rad( -a ) ) * radius, 0 )
local Ya = math.Round( math.cos( math.rad( -a ) ) * radius, 0 )
local C = math.sqrt( radius ^ 2 + radius ^ 2 )
if a == 90 then
C = C * math.min(math.max(perc - 0.75,0) / 0.25,1)
elseif a == 180 then
C = C * math.min(math.max(perc - 0.5,0) / 0.25,1)
elseif a == 270 then
C = C * math.min(math.max(perc - 0.25,0) / 0.25,1)
elseif a == 360 then
C = C * math.min(math.max(perc,0) / 0.25,1)
end
if C > 0 then
local AxisMoveX = math.Round( math.sin( math.rad( -a + 135) ) * (C + 3) * 0.5, 0 )
local AxisMoveY =math.Round( math.cos( math.rad( -a + 135) ) * (C + 3) * 0.5, 0 )
surface.DrawTexturedRectRotated(X - Xa - AxisMoveX, Y - Ya - AxisMoveY,3, math.ceil( C ), a - 45)
end
end
end
local function PaintIdentifier( ent )
if not LVS.ShowIdent or LVS:IsIndicatorForced() then return end
local VehicleIdentifierRange = ent.VehicleIdentifierRange
local MyPos = ent:GetPos()
local MyTeam = ent:GetAITEAM()
for _, v in pairs( LVS:GetVehicles() ) do
if not IsValid( v ) or v == ent then continue end
local rPos = v:LocalToWorld( v:OBBCenter() )
local Pos = rPos:ToScreen()
local Dist = (MyPos - rPos):Length()
if Dist > VehicleIdentifierRange or util.TraceLine( {start = ent:LocalToWorld( ent:OBBCenter() ),endpos = rPos,mask = MASK_NPCWORLDSTATIC,} ).Hit then continue end
local Alpha = 255 * (1 - (Dist / VehicleIdentifierRange) ^ 2)
local Team = v:GetAITEAM()
local IndicatorColor = Color( 255, 0, 0, Alpha )
if Team == 0 then
if MyTeam == 0 then continue end
IndicatorColor = Color( 0, 255, 0, Alpha )
else
if Team == 1 or Team == 2 then
if Team ~= MyTeam and MyTeam ~= 0 then
IndicatorColor = Color( 255, 0, 0, Alpha )
else
IndicatorColor = Color( 0, 127, 255, Alpha )
end
end
end
if Team > 3 then continue end
v:LVSHudPaintVehicleIdentifier( Pos.x, Pos.y, IndicatorColor )
end
end
hook.Add( "HUDPaint", "!!!!!LVS_hud", function()
local ply = LocalPlayer()
if ply:GetViewEntity() ~= ply then return end
local Pod = ply:GetVehicle()
local Parent = ply:lvsGetVehicle()
if not IsValid( Pod ) or not IsValid( Parent ) then
ply._lvsoldPassengers = {}
return
end
local X = ScrW()
local Y = ScrH()
PaintIdentifier( Parent )
Parent:LVSHudPaint( X, Y, ply )
local base = Pod:lvsGetWeapon()
if IsValid( base ) then
local weapon = base:GetActiveWeapon()
if weapon and weapon.HudPaint then
weapon.HudPaint( base, X, Y, ply )
end
else
local weapon = Parent:GetActiveWeapon()
if ply == Parent:GetDriver() and weapon and weapon.HudPaint then
weapon.HudPaint( Parent, X, Y, ply )
end
end
for id, editor in pairs( LVS.HudEditors ) do
if LVS.HudEditorsHide[ id ] then continue end
local ScaleX = editor.w / editor.DefaultWidth
local ScaleY = editor.h / editor.DefaultHeight
local PosX = editor.X / ScaleX
local PosY = editor.Y / ScaleY
local Width = editor.w / ScaleX
local Height = editor.h / ScaleY
local ScrW = X / ScaleX
local ScrH = Y / ScaleY
if ScaleX == 1 and ScaleY == 1 then
editor:func( Parent, PosX, PosY, Width, Height, ScrW, ScrH, ply )
else
local m = Matrix()
m:Scale( Vector( ScaleX, ScaleY, 1 ) )
cam.PushModelMatrix( m )
editor:func( Parent, PosX, PosY, Width, Height, ScrW, ScrH, ply )
cam.PopModelMatrix()
end
end
end )

View File

@@ -0,0 +1,800 @@
local icon_load_version = Material("gui/html/refresh")
local bgMat = Material( "lvs/controlpanel_bg.png" )
local adminMat = Material( "icon16/shield.png" )
local gradient_mat = Material( "gui/gradient" )
local gradient_down = Material( "gui/gradient_down" )
local FrameSizeX = 600
local FrameSizeY = 400
local function ClientSettings( Canvas )
local TopPanel = vgui.Create( "DPanel", Canvas )
TopPanel:SetSize( FrameSizeX, FrameSizeY * 0.35 )
TopPanel.Paint = function( self, w, h )
surface.SetDrawColor( 80, 80, 80, 255 )
surface.SetMaterial( gradient_mat )
surface.DrawTexturedRect( 1, 0, w, 1 )
draw.DrawText( "Mouse", "LVS_FONT", 4, 4, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
end
TopPanel:Dock( BOTTOM )
local RightPanel = vgui.Create( "DPanel", Canvas )
RightPanel:SetSize( FrameSizeX * 0.5, FrameSizeY )
RightPanel.Paint = function( self, w, h )
surface.SetDrawColor( 80, 80, 80, 255 )
surface.SetMaterial( gradient_down )
surface.DrawTexturedRect( 0, 0, 1, h )
draw.DrawText( "Misc/Performance", "LVS_FONT", 4, 4, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
end
RightPanel:Dock( RIGHT )
local RightPanelRight = vgui.Create( "DPanel", RightPanel )
RightPanelRight:SetSize( FrameSizeX * 0.25, FrameSizeY )
RightPanelRight.Paint = function() end
RightPanelRight:Dock( RIGHT )
local LeftPanel = vgui.Create( "DPanel", Canvas )
LeftPanel:SetSize( FrameSizeX * 0.5, FrameSizeY )
LeftPanel.Paint = function( self, w, h )
draw.DrawText( "Preferences", "LVS_FONT", 4, 4, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
end
LeftPanel:Dock( LEFT )
local CheckBoxPanel = vgui.Create( "DPanel", TopPanel )
CheckBoxPanel:DockMargin( 0, 0, 0, 0 )
CheckBoxPanel:SetSize( FrameSizeX, 55 )
CheckBoxPanel.Paint = function() end
CheckBoxPanel:Dock( TOP )
if GetConVar( "lvs_mouseaim_type" ):GetInt() == 1 and not LVS:IsDirectInputForced() then
local CheckBoxType = vgui.Create( "DCheckBoxLabel", CheckBoxPanel )
CheckBoxType:SetSize( FrameSizeX * 0.5, 55 )
CheckBoxType:DockMargin( 16, 36, 0, 0 )
CheckBoxType:Dock( LEFT )
CheckBoxType:SetText( "Mouse-Aim for:" )
CheckBoxType:SetConVar("lvs_mouseaim_type")
CheckBoxType.OnChange = function( self, bVal )
if not isbool( self.first ) then self.first = true return end
timer.Simple(0.1, function() LVS:OpenMenu( true ) end )
end
local DScrollPanel = vgui.Create("DScrollPanel", CheckBoxPanel )
DScrollPanel:SetSize( FrameSizeX * 0.25, 55 )
DScrollPanel:DockMargin( 8, 0, 8, 0 )
DScrollPanel:Dock( LEFT )
for _, vehicletype in pairs( LVS:GetVehicleTypes() ) do
local ScrollOption = vgui.Create( "DCheckBoxLabel", DScrollPanel )
ScrollOption:SetText( vehicletype )
ScrollOption:Dock( TOP )
ScrollOption:DockMargin( 0, 0, 0, 5 )
ScrollOption:SetConVar("lvs_mouseaim_type_"..vehicletype)
end
else
local CheckBox = vgui.Create( "DCheckBoxLabel", CheckBoxPanel )
CheckBox:SetSize( FrameSizeX * 0.5, 55 )
CheckBox:DockMargin( 16, 36, 0, 0 )
CheckBox:Dock( LEFT )
CheckBox:SetText( "Mouse-Aim Steering" )
CheckBox:SetConVar("lvs_mouseaim")
CheckBox.OnChange = function( self, bVal )
if not isbool( self.first ) then self.first = true return end
timer.Simple(0.1, function() LVS:OpenMenu( true ) end )
end
if LVS:IsDirectInputForced() then
CheckBox:SetText( "[DISABLED] Use Mouse-Aim Steering" )
CheckBox:SetDisabled( true )
end
if not LVS:IsDirectInputForced() then
local CheckBoxType = vgui.Create( "DCheckBoxLabel", CheckBoxPanel )
CheckBoxType:SetSize( FrameSizeX * 0.5, 55 )
CheckBoxType:DockMargin( 16, 36, 0, 0 )
CheckBoxType:Dock( LEFT )
CheckBoxType:SetText( "Edit Mouse-Aim per Type" )
CheckBoxType:SetConVar("lvs_mouseaim_type")
CheckBoxType.OnChange = function( self, bVal )
if not isbool( self.first ) then self.first = true return end
timer.Simple(0.1, function() LVS:OpenMenu( true ) end )
end
end
end
if GetConVar( "lvs_mouseaim" ):GetInt() == 0 or LVS:IsDirectInputForced() then
local L = vgui.Create( "DPanel", TopPanel )
L:SetSize( FrameSizeX * 0.5, FrameSizeY )
L.Paint = function() end
L:Dock( LEFT )
local R = vgui.Create( "DPanel", TopPanel )
R:SetSize( FrameSizeX * 0.5, FrameSizeY )
R.Paint = function() end
R:Dock( RIGHT )
local slider = vgui.Create( "DNumSlider", R )
slider:DockMargin( 16, 4, 16, 4 )
slider:Dock( TOP )
slider:SetText( "Y Sensitivity" )
slider:SetMin( -10 )
slider:SetMax( 10 )
slider:SetDecimals( 3 )
slider:SetConVar( "lvs_sensitivity_y" )
local slider = vgui.Create( "DNumSlider", L )
slider:DockMargin( 16, 4, 16, 4 )
slider:Dock( TOP )
slider:SetText( "X Sensitivity" )
slider:SetMin( 0 )
slider:SetMax( 10 )
slider:SetDecimals( 3 )
slider:SetConVar( "lvs_sensitivity_x" )
local slider = vgui.Create( "DNumSlider", L )
slider:DockMargin( 16, 4, 16, 4 )
slider:Dock( TOP )
slider:SetText( "Return Delta" )
slider:SetMin( 0 )
slider:SetMax( 10 )
slider:SetDecimals( 3 )
slider:SetConVar( "lvs_return_delta" )
else
local slider = vgui.Create( "DNumSlider", TopPanel )
slider:DockMargin( 16, 4, 16, 4 )
slider:Dock( TOP )
slider:SetText( "Camera Focus" )
slider:SetMin( -1 )
slider:SetMax( 1 )
slider:SetDecimals( 2 )
slider:SetConVar( "lvs_camerafocus" )
end
local slider = vgui.Create( "DNumSlider", LeftPanel )
slider:DockMargin( 16, 36, 16, 4 )
slider:Dock( TOP )
slider:SetText( "Engine Volume" )
slider:SetMin( 0 )
slider:SetMax( 1 )
slider:SetDecimals( 2 )
slider:SetConVar( "lvs_volume" )
local DLabel = vgui.Create("DLabel", LeftPanel )
DLabel:SetPos( 16, 72 )
DLabel:SetSize( 60, 20 )
DLabel:SetText( "Speed Unit" )
local DComboBox = vgui.Create( "DComboBox", LeftPanel )
DComboBox:SetPos( 130, 72 )
DComboBox:SetSize( 160, 20 )
DComboBox:SetValue( LVS.SpeedUnit )
for unit, _ in pairs( LVS.SPEEDUNITS ) do
DComboBox:AddChoice( unit )
end
DComboBox.OnSelect = function( self, index, value )
RunConsoleCommand("lvs_speedunit", value)
end
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanel )
CheckBox:DockMargin( 16, 43, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Show Team Identifier" )
CheckBox:SetConVar("lvs_show_identifier")
if LVS:IsIndicatorForced() then
CheckBox:SetText( "[DISABLED] Team Identifier" )
CheckBox:SetDisabled( true )
end
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanel )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Show Hit/Kill Marker" )
CheckBox:SetConVar("lvs_hitmarker")
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanel )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Enable HUD Editor" )
CheckBox:SetConVar("lvs_edit_hud")
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanel )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Show Door Info" )
CheckBox:SetConVar("lvs_show_doorinfo")
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanelRight )
CheckBox:DockMargin( 16, 43, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Trail Effects" )
CheckBox:SetConVar("lvs_show_traileffects")
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanelRight )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Wind/Dust FX/SFX" )
CheckBox:SetConVar("lvs_show_effects")
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanelRight )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Scrape/Impact FX" )
CheckBox:SetConVar("lvs_show_physicseffects")
local CheckBox = vgui.Create( "DCheckBoxLabel", RightPanelRight )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Bullet near miss SFX" )
CheckBox:SetConVar("lvs_bullet_nearmiss")
end
local function ClientControls( Canvas )
local TextHint = vgui.Create("DPanel", Canvas)
TextHint:DockMargin( 4, 20, 4, 2 )
TextHint:SetText("")
TextHint:Dock( TOP )
TextHint.Paint = function(self, w, h )
draw.DrawText( "You need to re-enter the vehicle in order for the changes to take effect!", "LVS_FONT_PANEL", w * 0.5, -1, Color( 255, 50, 50, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local DScrollPanel = vgui.Create("DScrollPanel", Canvas)
DScrollPanel:DockMargin( 0, 0, 0, 24 )
DScrollPanel:Dock( FILL )
for category, _ in pairs( LVS.KEYS_CATEGORIES ) do
local Header = vgui.Create("DPanel", DScrollPanel )
Header:DockMargin( 0, 4, 4, 2 )
Header:SetText("")
Header:Dock( TOP )
Header.Paint = function(self, w, h )
surface.SetMaterial( gradient_mat )
surface.SetDrawColor( 80, 80, 80, 255 )
surface.DrawTexturedRect( 0, 0, w, 1 )
draw.DrawText( category, "LVS_FONT", 4, 0, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER )
end
for _, entry in pairs( LVS.KEYS_REGISTERED ) do
if entry.category ~= category then continue end
local DPanel = vgui.Create( "DPanel", DScrollPanel )
DPanel.Paint = function(self, w, h ) end
DPanel:DockMargin( 4, 2, 4, 2 )
DPanel:SetSize( FrameSizeX, 25 )
DPanel:Dock( TOP )
local ConVar = GetConVar( entry.cmd )
local DLabel = vgui.Create("DLabel", DPanel)
DLabel:DockMargin( 16, 0, 0, 0 )
DLabel:SetText( entry.printname )
DLabel:SetSize( FrameSizeX * 0.5, 32 )
DLabel:Dock( LEFT )
local DBinder = vgui.Create("DBinder", DPanel)
DBinder:DockMargin( 0, 0, 0, 0 )
DBinder:SetValue( ConVar:GetInt() )
DBinder:SetSize( FrameSizeX * 0.5, 32 )
DBinder:Dock( RIGHT )
DBinder.ConVar = ConVar
DBinder.OnChange = function(self,iNum)
self.ConVar:SetInt(iNum)
LocalPlayer():lvsBuildControls()
end
end
end
local Header = vgui.Create("DPanel", DScrollPanel )
Header:DockMargin( 0, 16, 0, 0 )
Header:SetText("")
Header:Dock( TOP )
Header.Paint = function(self, w, h )
surface.SetMaterial( gradient_mat )
surface.SetDrawColor( 80, 80, 80, 255 )
surface.DrawTexturedRect( 0, 0, w, 1 )
end
local DButton = vgui.Create("DButton",DScrollPanel)
DButton:SetText("Reset")
DButton:DockMargin( 4, 0, 4, 4 )
DButton:SetSize( FrameSizeX, 32 )
DButton:Dock( TOP )
DButton.DoClick = function()
surface.PlaySound( "buttons/button14.wav" )
for _, entry in pairs( LVS.KEYS_REGISTERED ) do
GetConVar( entry.cmd ):SetInt( entry.default )
end
LocalPlayer():lvsBuildControls()
LVS:OpenClientControls()
end
end
local function ServerSettings( Canvas )
local slider = vgui.Create( "DNumSlider", Canvas )
slider:DockMargin( 16, 32, 16, 4 )
slider:Dock( TOP )
slider:SetText( "Player Default AI-Team" )
slider:SetMin( 0 )
slider:SetMax( 3 )
slider:SetDecimals( 0 )
slider:SetConVar( "lvs_default_teams" )
function slider:OnValueChanged( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_default_teams")
net.WriteString( tostring( math.Round(val,0) ) )
net.SendToServer()
end
local slider = vgui.Create( "DNumSlider", Canvas )
slider:DockMargin( 16, 8, 16, 4 )
slider:Dock( TOP )
slider:SetText("Fuel tank size multiplier")
slider:SetMin( 0 )
slider:SetMax( 10 )
slider:SetDecimals( 2 )
slider:SetConVar( "lvs_fuelscale" )
function slider:OnValueChanged( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_fuelscale")
net.WriteString( tostring( val ) )
net.SendToServer()
end
local CheckBox = vgui.Create( "DCheckBoxLabel", Canvas )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Freeze Player AI-Team" )
CheckBox:SetValue( GetConVar( "lvs_freeze_teams" ):GetInt() )
CheckBox:SizeToContents()
function CheckBox:OnChange( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_freeze_teams")
net.WriteString( tostring( val and 1 or 0 ) )
net.SendToServer()
end
local CheckBox = vgui.Create( "DCheckBoxLabel", Canvas )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Only allow Players of matching AI-Team to enter Vehicles" )
CheckBox:SetValue( GetConVar( "lvs_teampassenger" ):GetInt() )
CheckBox:SizeToContents()
function CheckBox:OnChange( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_teampassenger")
net.WriteString( tostring( val and 1 or 0 ) )
net.SendToServer()
end
local CheckBox = vgui.Create( "DCheckBoxLabel", Canvas )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "LVS-AI ignore NPC's" )
CheckBox:SetValue( GetConVar( "lvs_ai_ignorenpcs" ):GetInt() )
CheckBox:SizeToContents()
function CheckBox:OnChange( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_ai_ignorenpcs")
net.WriteString( tostring( val and 1 or 0 ) )
net.SendToServer()
end
local CheckBox = vgui.Create( "DCheckBoxLabel", Canvas )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "LVS-AI ignore Players's" )
CheckBox:SetValue( GetConVar( "lvs_ai_ignoreplayers" ):GetInt() )
CheckBox:SizeToContents()
function CheckBox:OnChange( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_ai_ignoreplayers")
net.WriteString( tostring( val and 1 or 0 ) )
net.SendToServer()
end
local CheckBox = vgui.Create( "DCheckBoxLabel", Canvas )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Disable Mouse Aim" )
CheckBox:SetValue( GetConVar( "lvs_force_directinput" ):GetInt() )
CheckBox:SizeToContents()
function CheckBox:OnChange( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_force_directinput")
net.WriteString( tostring( val and 1 or 0 ) )
net.SendToServer()
end
local CheckBox = vgui.Create( "DCheckBoxLabel", Canvas )
CheckBox:DockMargin( 16, 16, 4, 4 )
CheckBox:SetSize( FrameSizeX, 30 )
CheckBox:Dock( TOP )
CheckBox:SetText( "Hide Team Identifier" )
CheckBox:SetValue( GetConVar( "lvs_force_forceindicator" ):GetInt() )
CheckBox:SizeToContents()
function CheckBox:OnChange( val )
net.Start("lvs_admin_setconvar")
net.WriteString("lvs_force_forceindicator")
net.WriteString( tostring( val and 1 or 0 ) )
net.SendToServer()
end
end
function LVS:OpenClientSettings()
if not IsValid( LVS.Frame ) then return end
local BasePanel = LVS.Frame:CreatePanel()
local DPanel = vgui.Create( "DPanel", BasePanel )
DPanel.Paint = function(self, w, h ) end
DPanel:DockMargin( 0, 0, 0, 0 )
DPanel:SetSize( FrameSizeX, 25 )
DPanel:Dock( TOP )
local TabPanel = vgui.Create( "DPanel", BasePanel )
TabPanel.Paint = function(self, w, h ) end
TabPanel:DockMargin( 0, 0, 0, 0 )
TabPanel:SetSize( FrameSizeX, 25 )
TabPanel:Dock( TOP )
local SettingsPanel = vgui.Create( "DPanel", TabPanel )
SettingsPanel:DockMargin( 0, 0, 0, 0 )
SettingsPanel:SetSize( FrameSizeX * 0.5, 32 )
SettingsPanel:Dock( LEFT )
SettingsPanel.Paint = function(self, w, h )
draw.DrawText( "SETTINGS", "LVS_FONT", w * 0.5, 0, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local DButton = vgui.Create( "DButton", TabPanel )
DButton:DockMargin( 0, 0, 0, 0 )
DButton:SetText( "" )
DButton:SetSize( FrameSizeX * 0.5, 32 )
DButton:Dock( RIGHT )
DButton.DoClick = function()
surface.PlaySound( "buttons/button14.wav" )
LVS:OpenClientControls()
end
DButton.Paint = function(self, w, h )
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
local Hovered = self:IsHovered()
if Hovered then
surface.SetDrawColor( 120, 120, 120, 255 )
else
surface.SetDrawColor( 80, 80, 80, 255 )
end
surface.DrawRect(1, 0, w-2, h-1)
local Col = Hovered and Color( 255, 255, 255, 255 ) or Color( 150, 150, 150, 255 )
draw.DrawText( "CONTROLS", "LVS_FONT", w * 0.5, 0, Col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local DButton = vgui.Create( "DButton", DPanel )
DButton:DockMargin( 0, 0, 0, 0 )
DButton:SetText( "" )
DButton:SetSize( FrameSizeX * 0.5, 32 )
DButton:Dock( RIGHT )
DButton.DoClick = function()
if LocalPlayer():IsSuperAdmin() then
surface.PlaySound( "buttons/button14.wav" )
LVS:OpenServerMenu()
else
surface.PlaySound( "buttons/button11.wav" )
end
end
DButton.Paint = function(self, w, h )
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
local Hovered = self:IsHovered()
if Hovered then
draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 120, 120, 120, 255 ) )
else
draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 80, 80, 80, 255 ) )
end
surface.SetDrawColor( 255, 255, 255, Hovered and 255 or 50 )
surface.SetMaterial( adminMat )
surface.DrawTexturedRect( 3, 2, 16, 16 )
local Col = Hovered and Color( 255, 255, 255, 255 ) or Color( 150, 150, 150, 255 )
draw.DrawText( "SERVER", "LVS_FONT", w * 0.5, 0, Col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local ClientPanel = vgui.Create( "DPanel", DPanel )
ClientPanel.Paint = function(self, w, h ) end
ClientPanel:DockMargin( 0, 0, 0, 0 )
ClientPanel:SetSize( FrameSizeX * 0.5, 32 )
ClientPanel:Dock( LEFT )
ClientPanel.Paint = function(self, w, h )
draw.DrawText( "CLIENT", "LVS_FONT", w * 0.5, 0, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local Canvas = vgui.Create( "DPanel", BasePanel )
Canvas.Paint = function(self, w, h ) end
Canvas:DockMargin( 0, 0, 0, 0 )
Canvas:SetSize( FrameSizeX, 25 )
Canvas:Dock( FILL )
ClientSettings( Canvas )
end
function LVS:OpenClientControls()
if not IsValid( LVS.Frame ) then return end
local BasePanel = LVS.Frame:CreatePanel()
local DPanel = vgui.Create( "DPanel", BasePanel )
DPanel.Paint = function(self, w, h ) end
DPanel:DockMargin( 0, 0, 0, 0 )
DPanel:SetSize( FrameSizeX, 25 )
DPanel:Dock( TOP )
local TabPanel = vgui.Create( "DPanel", BasePanel )
TabPanel.Paint = function(self, w, h ) end
TabPanel:DockMargin( 0, 0, 0, 0 )
TabPanel:SetSize( FrameSizeX, 25 )
TabPanel:Dock( TOP )
local SettingsPanel = vgui.Create( "DPanel", TabPanel )
SettingsPanel:DockMargin( 0, 0, 0, 0 )
SettingsPanel:SetSize( FrameSizeX * 0.5, 32 )
SettingsPanel:Dock( RIGHT )
SettingsPanel.Paint = function(self, w, h )
draw.DrawText( "CONTROLS", "LVS_FONT", w * 0.5, 0, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local DButton = vgui.Create( "DButton", TabPanel )
DButton:DockMargin( 0, 0, 0, 0 )
DButton:SetText( "" )
DButton:SetSize( FrameSizeX * 0.5, 32 )
DButton:Dock( LEFT )
DButton.DoClick = function()
surface.PlaySound( "buttons/button14.wav" )
LVS:OpenClientSettings()
end
DButton.Paint = function(self, w, h )
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
local Hovered = self:IsHovered()
if Hovered then
surface.SetDrawColor( 120, 120, 120, 255 )
else
surface.SetDrawColor( 80, 80, 80, 255 )
end
surface.DrawRect(1, 1, w-2, h-2)
local Col = Hovered and Color( 255, 255, 255, 255 ) or Color( 150, 150, 150, 255 )
draw.DrawText( "SETTINGS", "LVS_FONT", w * 0.5, 0, Col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local DButton = vgui.Create( "DButton", DPanel )
DButton:DockMargin( 0, 0, 0, 0 )
DButton:SetText( "" )
DButton:SetSize( FrameSizeX * 0.5, 32 )
DButton:Dock( RIGHT )
DButton.DoClick = function()
if LocalPlayer():IsSuperAdmin() then
surface.PlaySound( "buttons/button14.wav" )
LVS:OpenServerMenu()
else
surface.PlaySound( "buttons/button11.wav" )
end
end
DButton.Paint = function(self, w, h )
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
local Hovered = self:IsHovered()
if Hovered then
draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 120, 120, 120, 255 ) )
else
draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 80, 80, 80, 255 ) )
end
surface.SetDrawColor( 255, 255, 255, Hovered and 255 or 50 )
surface.SetMaterial( adminMat )
surface.DrawTexturedRect( 3, 2, 16, 16 )
local Col = Hovered and Color( 255, 255, 255, 255 ) or Color( 150, 150, 150, 255 )
draw.DrawText( "SERVER", "LVS_FONT", w * 0.5, 0, Col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local ClientPanel = vgui.Create( "DPanel", DPanel )
ClientPanel.Paint = function(self, w, h ) end
ClientPanel:DockMargin( 0, 0, 0, 0 )
ClientPanel:SetSize( FrameSizeX * 0.5, 32 )
ClientPanel:Dock( LEFT )
ClientPanel.Paint = function(self, w, h )
draw.DrawText( "CLIENT", "LVS_FONT", w * 0.5, 0, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local Canvas = vgui.Create( "DPanel", BasePanel )
Canvas.Paint = function(self, w, h ) end
Canvas:DockMargin( 0, 0, 0, 0 )
Canvas:SetSize( FrameSizeX, 25 )
Canvas:Dock( FILL )
ClientControls( Canvas )
end
function LVS:OpenServerMenu()
if not IsValid( LVS.Frame ) then return end
local BasePanel = LVS.Frame:CreatePanel()
local DPanel = vgui.Create( "DPanel", BasePanel )
DPanel.Paint = function(self, w, h ) end
DPanel:DockMargin( 0, 0, 0, 0 )
DPanel:SetSize( FrameSizeX, 25 )
DPanel:Dock( TOP )
local ServerPanel = vgui.Create( "DPanel", DPanel )
ServerPanel.Paint = function(self, w, h ) end
ServerPanel:DockMargin( 0, 0, 0, 0 )
ServerPanel:SetSize( FrameSizeX * 0.5, 32 )
ServerPanel:Dock( RIGHT )
ServerPanel.Paint = function(self, w, h )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( adminMat )
surface.DrawTexturedRect( 3, 2, 16, 16 )
draw.DrawText( "SERVER", "LVS_FONT", w * 0.5, 0, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local DButton = vgui.Create( "DButton", DPanel )
DButton:DockMargin( 0, 0, 0, 0 )
DButton:SetText( "" )
DButton:SetSize( FrameSizeX * 0.5, 32 )
DButton:Dock( LEFT )
DButton.DoClick = function()
surface.PlaySound( "buttons/button14.wav" )
LVS:OpenClientSettings()
end
DButton.Paint = function(self, w, h )
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
local Hovered = self:IsHovered()
if Hovered then
draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 120, 120, 120, 255 ) )
else
draw.RoundedBox( 4, 1, 1, w-2, h-2, Color( 80, 80, 80, 255 ) )
end
local Col = Hovered and Color( 255, 255, 255, 255 ) or Color( 150, 150, 150, 255 )
draw.DrawText( "CLIENT", "LVS_FONT", w * 0.5, 0, Col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
local Canvas = vgui.Create( "DPanel", BasePanel )
Canvas.Paint = function(self, w, h ) end
Canvas:DockMargin( 0, 0, 0, 0 )
Canvas:SetSize( FrameSizeX, 25 )
Canvas:Dock( FILL )
ServerSettings( Canvas )
end
function LVS:CloseMenu()
if not IsValid( LVS.Frame ) then return end
LVS.Frame:Close()
LVS.Frame = nil
end
function LVS:OpenMenu( keep_position )
local xPos
local yPos
if IsValid( LVS.Frame ) then
if keep_position then
xPos = LVS.Frame:GetX()
yPos = LVS.Frame:GetY()
end
LVS:CloseMenu()
end
LVS.Frame = vgui.Create( "DFrame" )
LVS.Frame:SetSize( FrameSizeX, FrameSizeY )
LVS.Frame:SetTitle( "" )
LVS.Frame:SetDraggable( true )
LVS.Frame:SetScreenLock( true )
LVS.Frame:MakePopup()
LVS.Frame:Center()
if keep_position and xPos and yPos then
LVS.Frame:SetPos( xPos, yPos )
end
LVS.Frame.Paint = function(self, w, h )
draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 0, 0, 255 ) )
draw.RoundedBoxEx( 8, 1, 26, w-2, h-27, Color( 120, 120, 120, 255 ), false, false, true, true )
draw.RoundedBoxEx( 8, 0, 0, w, 25, LVS.ThemeColor, true, true )
draw.SimpleText( "[LVS] - Control Panel ", "LVS_FONT", 5, 11, Color(255,255,255,255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER )
surface.SetDrawColor( 255, 255, 255, 50 )
surface.SetMaterial( bgMat )
surface.DrawTexturedRect( 0, -50, w, w )
end
LVS.Frame.CreatePanel = function( self )
if IsValid( self.OldPanel ) then
self.OldPanel:Remove()
self.OldPanel = nil
end
local DPanel = vgui.Create( "DPanel", LVS.Frame )
DPanel:SetPos( 0, 25 )
DPanel:SetSize( FrameSizeX, FrameSizeY - 25 )
DPanel.Paint = function(self, w, h )
local Col = Color( 255, 191, 0, 255 )
if LVS.VERSION_GITHUB == 0 then
surface.SetMaterial( icon_load_version )
surface.SetDrawColor( Col )
surface.DrawTexturedRectRotated( w - 14, h - 14, 16, 16, -CurTime() * 200 )
draw.SimpleText( "v"..LVS:GetVersion()..LVS.VERSION_TYPE, "LVS_VERSION", w - 23, h - 14, Col, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER )
return
end
local Current = LVS:GetVersion()
local Latest = LVS.VERSION_GITHUB
local Pref = "v"
if Current >= Latest and not LVS.VERSION_ADDONS_OUTDATED then
Col = Color(0,255,0,255)
else
Col = Color(255,0,0,255)
Pref = "OUTDATED v"
end
draw.SimpleText( Pref..LVS:GetVersion()..LVS.VERSION_TYPE, "LVS_VERSION", w - 7, h - 14, Col, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER )
end
self.OldPanel = DPanel
return DPanel
end
LVS:OpenClientSettings()
end
list.Set( "DesktopWindows", "LVSMenu", {
title = "[LVS] Settings",
icon = "icon64/iconlvs.png",
init = function( icon, window )
LVS:OpenMenu()
end
} )
concommand.Add( "lvs_openmenu", function( ply, cmd, args ) LVS:OpenMenu() end )

View File

@@ -0,0 +1,578 @@
local LVS = LVS
LVS._ActiveBullets = {}
function LVS:RemoveBullet( index )
LVS._ActiveBullets[ index ] = nil
end
function LVS:GetBullet( index )
if not LVS._ActiveBullets then return end
return LVS._ActiveBullets[ index ]
end
local NewBullet = {}
NewBullet.__index = NewBullet
function NewBullet:SetPos( pos )
self.curpos = pos
end
function NewBullet:GetBulletIndex()
return self.bulletindex
end
function NewBullet:Remove()
local index = self.bulletindex
if SERVER then
-- prevents ghost bullets if the client fails to detect the hit
net.Start( "lvs_remove_bullet", true )
net.WriteInt( index, 13 )
net.SendPVS( self:GetPos() )
end
LVS:RemoveBullet( index )
end
function NewBullet:GetPos()
if not self.curpos then return self.Src end
return self.curpos
end
function NewBullet:SetGravity( new )
self.Gravity = new
end
function NewBullet:GetGravity()
return self.Gravity or vector_origin
end
function NewBullet:GetDir()
return self.Dir or vector_origin
end
function NewBullet:SetDir( newdir )
self.Dir = newdir
end
function NewBullet:GetTimeAlive()
return CurTime() - self.StartTime
end
function NewBullet:GetSpawnTime()
if SERVER then
return self.StartTime
else
return math.min( self.StartTimeCL, CurTime() ) -- time when the bullet is received on client
end
end
function NewBullet:GetLength()
return math.min((CurTime() - self:GetSpawnTime()) * 14,1)
end
function NewBullet:HandleWaterImpact( traceStart, traceEnd, Filter )
if self.HasHitWater then return end
local traceWater = util.TraceLine( {
start = traceStart,
endpos = traceEnd,
filter = Filter,
mask = MASK_WATER,
} )
if not traceWater.Hit then return end
self.HasHitWater = true
local effectdata = EffectData()
effectdata:SetOrigin( traceWater.HitPos )
effectdata:SetScale( 10 + self.HullSize * 0.5 )
effectdata:SetFlags( 2 )
util.Effect( "WaterSplash", effectdata, true, true )
end
function NewBullet:HandleFlybySound( EarPos )
if self.Muted or not LVS.EnableBulletNearmiss then return end
local BulletPos = self:GetPos()
local EarDist = (EarPos - BulletPos):LengthSqr()
if self.OldEarDist and self.OldEarDist < EarDist then
if EarDist < 250000 then
local effectdata = EffectData()
effectdata:SetOrigin( EarPos + (BulletPos - EarPos):GetNormalized() * 20 )
effectdata:SetFlags( 2 )
util.Effect( "TracerSound", effectdata )
end
self.Muted = true
end
self.OldEarDist = EarDist
end
function NewBullet:DoBulletFlight( TimeAlive )
local StartPos = self.Src
local StartDirection = self.StartDir
local Velocity = self.Velocity
local PosOffset
-- startpos, direction and curtime of creation is networked to client.
-- the bullet position is simulated by doing startpos + dir * time * velocity
if self.EnableBallistics then
local PosTheoretical = StartDirection * TimeAlive * Velocity
PosOffset = PosTheoretical + self:GetGravity() * (TimeAlive ^ 2)
self:SetDir( (StartPos + PosOffset - StartPos):GetNormalized() )
else
PosOffset = self.Dir * TimeAlive * Velocity
end
if SERVER then
self:SetPos( StartPos + PosOffset )
else
-- "parent" the bullet to the vehicle for a very short time on client. This will give the illusion of the bullet not lagging behind even tho it is fired later on client
if IsValid( self.Entity ) and self.SrcEntity then
local mul = self:GetLength()
local inv = 1 - mul
self:SetPos( StartPos * mul + self.Entity:LocalToWorld( self.SrcEntity ) * inv + PosOffset )
return
end
-- if no parent detected, run same code as server
self:SetPos( StartPos + PosOffset )
end
end
function NewBullet:OnCollide( trace )
if CLIENT then return end
if trace.Entity == self.LastDamageTarget then return end
local Attacker = (IsValid( self.Attacker ) and self.Attacker) or (IsValid( self.Entity ) and self.Entity) or game.GetWorld()
local Inflictor = (IsValid( self.Entity ) and self.Entity) or (IsValid( self.Attacker ) and self.Attacker) or game.GetWorld()
local dmginfo = DamageInfo()
dmginfo:SetDamage( self.Damage )
dmginfo:SetAttacker( Attacker )
dmginfo:SetInflictor( Inflictor )
dmginfo:SetDamageType( DMG_AIRBOAT )
dmginfo:SetDamagePosition( trace.HitPos )
if self.Force1km then
local Mul = math.min( (self.Src - trace.HitPos):Length() / 39370, 1 )
local invMul = math.max( 1 - Mul, 0 )
dmginfo:SetDamageForce( self.Dir * (self.Force * invMul + self.Force1km * Mul) )
else
dmginfo:SetDamageForce( self.Dir * self.Force )
end
if self.Callback then
self.Callback( Attacker, trace, dmginfo )
end
if trace.Entity:GetClass() == "func_breakable_surf" then
-- this will cause the entire thing to just fall apart
dmginfo:SetDamageType( DMG_BLAST )
end
trace.Entity:DispatchTraceAttack( dmginfo, trace )
self.LastDamageTarget = trace.Entity
end
function NewBullet:DoSplashDamage( trace )
if not self.SplashDamage or not self.SplashDamageRadius then return false end
if self.SplashDamageEffect ~= "" then
local effectdata = EffectData()
effectdata:SetOrigin( trace.HitPos )
effectdata:SetNormal( trace.HitWorld and trace.HitNormal or self.Dir )
effectdata:SetMagnitude( self.SplashDamageRadius / 250 )
util.Effect( self.SplashDamageEffect, effectdata )
end
local Attacker = (IsValid( self.Attacker ) and self.Attacker) or (IsValid( self.Entity ) and self.Entity) or game.GetWorld()
local Inflictor = (IsValid( self.Entity ) and self.Entity) or (IsValid( self.Attacker ) and self.Attacker) or game.GetWorld()
LVS:BlastDamage( trace.HitPos, self.Dir, Attacker, Inflictor, self.SplashDamage, self.SplashDamageType, self.SplashDamageRadius, self.SplashDamageForce )
self.SplashDamage = nil
self.SplashDamageRadius = nil
self.SplashDamageEffect = nil
return true
end
function NewBullet:HandleCollision( traceStart, traceEnd, Filter )
local TraceMask = self.HullSize <= 1 and MASK_SHOT_PORTAL or MASK_SHOT_HULL
local traceLine
local traceHull
if self.HullTraceResult then
traceHull = self.HullTraceResult
else
traceLine = util.TraceLine( {
start = traceStart,
endpos = traceEnd,
filter = Filter,
mask = TraceMask
} )
local trace = util.TraceHull( {
start = traceStart,
endpos = traceEnd,
filter = Filter,
mins = self.Mins,
maxs = self.Maxs,
mask = TraceMask,
ignoreworld = true
} )
if traceLine.Entity == trace.Entity and trace.Hit and traceLine.Hit then
trace = traceLine
end
if trace.Hit then
self.HullTraceResult = trace
traceHull = trace
self:OnCollide( trace )
if self:DoSplashDamage( trace ) then
self:Remove()
end
else
traceHull = { Hit = false }
end
end
if not traceLine then
traceLine = util.TraceLine( {
start = traceStart,
endpos = traceEnd,
filter = Filter,
mask = TraceMask
} )
end
if not traceLine.Hit then
return
end
self:OnCollide( traceLine )
self:DoSplashDamage( traceLine )
self:Remove()
if SERVER then return end
if not traceLine.HitSky then
local effectdata = EffectData()
effectdata:SetOrigin( traceLine.HitPos )
effectdata:SetEntity( traceLine.Entity )
effectdata:SetStart( traceStart )
effectdata:SetNormal( traceLine.HitNormal )
effectdata:SetSurfaceProp( traceLine.SurfaceProps )
util.Effect( "Impact", effectdata )
end
end
local function GetEarPos()
if SERVER then return vector_origin end
local EarPos
local ply = LocalPlayer()
local ViewEnt = ply:GetViewEntity()
if ViewEnt == ply then
if IsValid( ply:lvsGetVehicle() ) then
EarPos = ply:lvsGetView()
else
EarPos = ply:GetShootPos()
end
else
EarPos = ViewEnt:GetPos()
end
return EarPos
end
local function HandleBullets()
local T = CurTime()
local FT = FrameTime()
local EarPos = GetEarPos()
for id, bullet in pairs( LVS._ActiveBullets ) do
if bullet:GetSpawnTime() + 5 < T then -- destroy all bullets older than 5 seconds
bullet:Remove()
continue
end
local TimeAlive = bullet:GetTimeAlive()
if TimeAlive < 0 then continue end -- CurTime() is predicted, this can be a negative number in some cases.
local Filter = bullet.Filter
local traceStart = bullet:GetPos()
bullet:DoBulletFlight( TimeAlive )
local traceEnd = bullet:GetPos()
if CLIENT then
--debugoverlay.Line( traceStart, traceEnd, Color( 255, 255, 255 ), true )
-- bullet flyby sounds
bullet:HandleFlybySound( EarPos )
-- bullet water impact effects
bullet:HandleWaterImpact( traceStart, traceEnd, Filter )
end
bullet:HandleCollision( traceStart, traceEnd, Filter )
end
end
local vector_one = Vector(1,1,1)
local TracerIndex = 0
local TracerToIndex = {}
local IndexToTracer = {}
if CLIENT then
hook.Add( "InitPostEntity", "lvs_bullet_sync", function()
net.Start( "lvs_bullet_tracer_lookup" )
net.SendToServer()
hook.Remove( "InitPostEntity", "lvs_bullet_sync" )
end )
net.Receive( "lvs_bullet_tracer_lookup", function( length )
local index = net.ReadInt( 32 )
local name = net.ReadString()
TracerToIndex[ name ] = index
IndexToTracer[ index ] = name
end)
else
function LVS:AddTracer( name )
if TracerToIndex[ name ] then return TracerToIndex[ name ] end
TracerIndex = TracerIndex + 1
net.Start( "lvs_bullet_tracer_lookup" )
net.WriteInt( TracerIndex, 32 )
net.WriteString( name )
net.Broadcast()
TracerToIndex[ name ] = TracerIndex
IndexToTracer[ TracerIndex ] = name
return TracerIndex
end
util.AddNetworkString( "lvs_bullet_tracer_lookup" )
net.Receive( "lvs_bullet_tracer_lookup", function( length, ply )
if ply._lvsAlreadyAskedForTracers then return end
ply._lvsAlreadyAskedForTracers = true
if TracerIndex == 0 then return end
for index, name in ipairs( IndexToTracer ) do
timer.Simple( index / 60, function()
if not IsValid( ply ) then return end
net.Start( "lvs_bullet_tracer_lookup" )
net.WriteInt( index, 32 )
net.WriteString( name )
net.Send( ply )
end )
end
end)
end
if SERVER then
util.AddNetworkString( "lvs_fire_bullet" )
util.AddNetworkString( "lvs_remove_bullet" )
hook.Add( "Tick", "!!!!lvs_bullet_handler", function( ply, ent ) -- from what i understand, think can "skip" on lag, while tick still simulates all steps
HandleBullets()
end )
local Index = 0
local MaxIndex = 4094 -- this is the util.effect limit
function LVS:FireBullet( data )
Index = Index + 1
if Index > MaxIndex then
Index = 1
end
LVS._ActiveBullets[ Index ] = nil
local bullet = {}
setmetatable( bullet, NewBullet )
bullet.TracerName = LVS:AddTracer( data.TracerName or "lvs_tracer_orange" )
bullet.Src = data.Src or vector_origin
bullet.Dir = (data.Dir + VectorRand() * (data.Spread or vector_origin) * 0.5):GetNormalized()
bullet.StartDir = bullet.Dir
bullet.Force = data.Force or 10
if data.Force1km then
bullet.Force1km = data.Force1km
end
bullet.HullSize = data.HullSize or 5
bullet.Mins = -vector_one * bullet.HullSize
bullet.Maxs = vector_one * bullet.HullSize
bullet.Velocity = math.Round( data.Velocity or 2500, 0 )
bullet.Attacker = IsValid( data.Attacker ) and data.Attacker or (IsValid( data.Entity ) and data.Entity or game.GetWorld())
bullet.Damage = data.Damage or 10
bullet.Entity = data.Entity
if IsValid( bullet.Entity ) and bullet.Entity.GetCrosshairFilterEnts then
bullet.Filter = bullet.Entity:GetCrosshairFilterEnts()
else
bullet.Filter = bullet.Entity
end
bullet.SrcEntity = data.SrcEntity or vector_origin
bullet.Callback = data.Callback
bullet.SplashDamage = data.SplashDamage
bullet.SplashDamageForce = data.SplashDamageForce or 500
bullet.SplashDamageRadius = data.SplashDamageRadius
bullet.SplashDamageEffect = data.SplashDamageEffect or "lvs_bullet_impact"
bullet.SplashDamageType = data.SplashDamageType or DMG_SONIC
bullet.StartTime = CurTime()
bullet.EnableBallistics = data.EnableBallistics == true
if bullet.EnableBallistics then
bullet:SetGravity( physenv.GetGravity() )
end
if InfMap then
for _, ply in ipairs( player.GetAll() ) do
local NewPos = Vector( bullet.Src.x, bullet.Src.y, bullet.Src.z ) - InfMap.unlocalize_vector( Vector(), ply.CHUNK_OFFSET )
net.Start( "lvs_fire_bullet", true )
net.WriteInt( Index, 13 )
net.WriteInt( bullet.TracerName, 9 )
net.WriteFloat( NewPos.x )
net.WriteFloat( NewPos.y )
net.WriteFloat( NewPos.z )
net.WriteAngle( bullet.Dir:Angle() )
net.WriteFloat( bullet.StartTime )
net.WriteFloat( bullet.HullSize )
net.WriteEntity( bullet.Entity )
net.WriteVector( bullet.SrcEntity )
net.WriteInt( bullet.Velocity, 19 )
net.WriteBool( bullet.EnableBallistics )
net.Send( ply )
end
else
net.Start( "lvs_fire_bullet", true )
net.WriteInt( Index, 13 )
net.WriteInt( bullet.TracerName, 9 )
net.WriteFloat( bullet.Src.x )
net.WriteFloat( bullet.Src.y )
net.WriteFloat( bullet.Src.z )
net.WriteAngle( bullet.Dir:Angle() )
net.WriteFloat( bullet.StartTime )
net.WriteFloat( bullet.HullSize )
net.WriteEntity( bullet.Entity )
net.WriteVector( bullet.SrcEntity )
net.WriteInt( bullet.Velocity, 19 )
net.WriteBool( bullet.EnableBallistics )
net.SendPVS( bullet.Src )
end
bullet.bulletindex = Index
LVS._ActiveBullets[ Index ] = bullet
end
else
net.Receive( "lvs_remove_bullet", function( length )
LVS:RemoveBullet( net.ReadInt( 13 ) )
end)
net.Receive( "lvs_fire_bullet", function( length )
local Index = net.ReadInt( 13 )
LVS._ActiveBullets[ Index ] = nil
local bullet = {}
setmetatable( bullet, NewBullet )
bullet.TracerName = IndexToTracer[ net.ReadInt( 9 ) ] or "lvs_tracer_orange"
bullet.Src = Vector(net.ReadFloat(),net.ReadFloat(),net.ReadFloat())
bullet.Dir = net.ReadAngle():Forward()
bullet.StartDir = bullet.Dir
bullet.StartTime = net.ReadFloat()
bullet.HullSize = net.ReadFloat()
bullet.Mins = -vector_one * bullet.HullSize
bullet.Maxs = vector_one * bullet.HullSize
bullet.Entity = net.ReadEntity()
if IsValid( bullet.Entity ) and bullet.Entity.GetCrosshairFilterEnts then
bullet.Filter = bullet.Entity:GetCrosshairFilterEnts()
else
bullet.Filter = bullet.Entity
end
bullet.SrcEntity = net.ReadVector()
if bullet.SrcEntity == vector_origin then
bullet.SrcEntity = nil
end
bullet.Velocity = net.ReadInt( 19 )
bullet.EnableBallistics = net.ReadBool()
if bullet.EnableBallistics then
bullet:SetGravity( physenv.GetGravity() )
end
bullet.StartTimeCL = CurTime() + RealFrameTime()
local ply = LocalPlayer()
if IsValid( ply ) then
bullet.Muted = bullet.Entity == ply:lvsGetVehicle() or bullet.Entity:GetOwner() == ply
end
bullet.bulletindex = Index
LVS._ActiveBullets[ Index ] = bullet
local effectdata = EffectData()
effectdata:SetOrigin( bullet.Src )
effectdata:SetNormal( bullet.Dir )
effectdata:SetMaterialIndex( Index )
util.Effect( bullet.TracerName, effectdata )
end )
hook.Add( "Think", "!!!!_lvs_bullet_think_cl", function()
HandleBullets()
end )
end

View File

@@ -0,0 +1,134 @@
-- 2022 and i still havent bothered creating a system that does this automatically
LVS.cVar_FreezeTeams = CreateConVar( "lvs_freeze_teams", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"enable/disable auto ai-team switching" )
LVS.FreezeTeams = LVS.cVar_FreezeTeams and LVS.cVar_FreezeTeams:GetBool() or false
cvars.AddChangeCallback( "lvs_freeze_teams", function( convar, oldValue, newValue )
LVS.FreezeTeams = tonumber( newValue ) ~=0
end, "lvs_freezeteams_callback" )
LVS.cVar_TeamPassenger = CreateConVar( "lvs_teampassenger", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"only allow players of matching ai-team to enter the vehicle? 1 = team only, 0 = everyone can enter" )
LVS.TeamPassenger = LVS.cVar_TeamPassenger and LVS.cVar_TeamPassenger:GetBool() or false
cvars.AddChangeCallback( "lvs_teampassenger", function( convar, oldValue, newValue )
LVS.TeamPassenger = tonumber( newValue ) ~= 0
end, "lvs_teampassenger_callback" )
LVS.cVar_PlayerDefaultTeam = CreateConVar( "lvs_default_teams", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"set default player ai-team" )
LVS.PlayerDefaultTeam = LVS.cVar_PlayerDefaultTeam and LVS.cVar_PlayerDefaultTeam:GetInt() or 0
cvars.AddChangeCallback( "lvs_default_teams", function( convar, oldValue, newValue )
LVS.PlayerDefaultTeam = math.Round( tonumber( newValue ), 0 )
end, "lvs_defaultteam_callback" )
LVS.cVar_IgnoreNPCs = CreateConVar( "lvs_ai_ignorenpcs", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"should LVS-AI ignore NPCs?" )
LVS.IgnoreNPCs = LVS.cVar_IgnoreNPCs and LVS.cVar_IgnoreNPCs:GetBool() or false
cvars.AddChangeCallback( "lvs_ai_ignoreplayers", function( convar, oldValue, newValue )
LVS.IgnorePlayers = tonumber( newValue ) ~=0
end)
LVS.cVar_playerignore = CreateConVar( "lvs_ai_ignoreplayers", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"should LVS-AI ignore Players?" )
LVS.IgnorePlayers = LVS.cVar_playerignore and LVS.cVar_playerignore:GetBool() or false
cvars.AddChangeCallback( "lvs_ai_ignorenpcs", function( convar, oldValue, newValue )
LVS.IgnoreNPCs = tonumber( newValue ) ~=0
end)
LVS.cVar_FuelScale = CreateConVar( "lvs_fuelscale", "1", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"Fuel tank size multiplier" )
LVS.FuelScale = LVS.cVar_FuelScale and LVS.cVar_FuelScale:GetFloat() or 1
cvars.AddChangeCallback( "lvs_fuelscale", function( convar, oldValue, newValue )
LVS.FuelScale = tonumber( newValue )
end )
if SERVER then
util.AddNetworkString( "lvs_admin_setconvar" )
net.Receive( "lvs_admin_setconvar", function( length, ply )
if not IsValid( ply ) or not ply:IsSuperAdmin() then return end
local ConVar = net.ReadString()
local Value = tonumber( net.ReadString() )
RunConsoleCommand( ConVar, Value )
end)
return
end
CreateClientConVar( "lvs_mouseaim", 0, true, true)
CreateClientConVar( "lvs_mouseaim_type", 1, true, false)
CreateClientConVar( "lvs_edit_hud", 1, true, false)
CreateClientConVar( "lvs_sensitivity_x", 1, true, true)
CreateClientConVar( "lvs_sensitivity_y", 1, true, true)
CreateClientConVar( "lvs_return_delta", 2, true, true)
LVS.cvarCamFocus = CreateClientConVar( "lvs_camerafocus", 0, true, false)
local cvarSpeedUnit = CreateClientConVar( "lvs_speedunit", "km/h", true, false)
LVS.SpeedUnit = cvarSpeedUnit and cvarSpeedUnit:GetString() or "km/h"
cvars.AddChangeCallback( "lvs_speedunit", function( convar, oldValue, newValue )
LVS.SpeedUnit = newValue
end)
local cvarDoorInfo = CreateClientConVar( "lvs_show_doorinfo", 1, true, false)
LVS.ShowDoorInfo = cvarDoorInfo and cvarDoorInfo:GetBool() or false
cvars.AddChangeCallback( "lvs_show_doorinfo", function( convar, oldValue, newValue )
LVS.ShowDoorInfo = tonumber( newValue ) ~=0
end)
local cvarVolume = CreateClientConVar( "lvs_volume", 0.5, true, false)
LVS.EngineVolume = cvarVolume and cvarVolume:GetFloat() or 0.5
cvars.AddChangeCallback( "lvs_volume", function( convar, oldValue, newValue )
LVS.EngineVolume = math.Clamp( tonumber( newValue ), 0, 1 )
end)
local cvarTrail = CreateClientConVar( "lvs_show_traileffects", 1, true, false)
LVS.ShowTraileffects = cvarTrail and cvarTrail:GetBool() or false
cvars.AddChangeCallback( "lvs_show_traileffects", function( convar, oldValue, newValue )
LVS.ShowTraileffects = tonumber( newValue ) ~=0
end)
local cvarEffects = CreateClientConVar( "lvs_show_effects", 1, true, false)
LVS.ShowEffects = cvarEffects and cvarEffects:GetBool() or false
cvars.AddChangeCallback( "lvs_show_effects", function( convar, oldValue, newValue )
LVS.ShowEffects = tonumber( newValue ) ~=0
end)
local cvarPhysEffects = CreateClientConVar( "lvs_show_physicseffects", 1, true, false)
LVS.ShowPhysicsEffects = cvarPhysEffects and cvarPhysEffects:GetBool() or false
cvars.AddChangeCallback( "lvs_show_physicseffects", function( convar, oldValue, newValue )
LVS.ShowPhysicsEffects = tonumber( newValue ) ~=0
end)
local cvarShowIdent = CreateClientConVar( "lvs_show_identifier", 1, true, false)
LVS.ShowIdent = cvarShowIdent and cvarShowIdent:GetBool() or false
cvars.AddChangeCallback( "lvs_show_identifier", function( convar, oldValue, newValue )
LVS.ShowIdent = tonumber( newValue ) ~=0
end)
local cvarHitMarker = CreateClientConVar( "lvs_hitmarker", 1, true, false)
LVS.ShowHitMarker = cvarHitMarker and cvarHitMarker:GetBool() or false
cvars.AddChangeCallback( "lvs_hitmarker", function( convar, oldValue, newValue )
LVS.ShowHitMarker = tonumber( newValue ) ~=0
end)
local cvarAntiAlias = GetConVar( "mat_antialias" )
LVS.AntiAliasingEnabled = cvarAntiAlias and (cvarAntiAlias:GetInt() > 3) or false
cvars.AddChangeCallback( "mat_antialias", function( convar, oldValue, newValue )
LVS.AntiAliasingEnabled = tonumber( newValue ) > 3
end)
local cvarBulletSFX = CreateClientConVar( "lvs_bullet_nearmiss", 1, true, false)
LVS.EnableBulletNearmiss = cvarBulletSFX and cvarBulletSFX:GetBool() or false
cvars.AddChangeCallback( "lvs_bullet_nearmiss", function( convar, oldValue, newValue )
LVS.EnableBulletNearmiss = tonumber( newValue ) ~=0
end)
local cvarDev = GetConVar( "developer" )
LVS.DeveloperEnabled = cvarDev and (cvarDev:GetInt() >= 1) or false
cvars.AddChangeCallback( "developer", function( convar, oldValue, newValue )
LVS.DeveloperEnabled = (tonumber( newValue ) or 0) >= 1
end)
cvars.AddChangeCallback( "lvs_mouseaim", function( convar, oldValue, newValue )
LocalPlayer():lvsBuildControls()
net.Start("lvs_toggle_mouseaim")
net.SendToServer()
end)

View File

@@ -0,0 +1,77 @@
if CLIENT then
net.Receive( "lvs_hurtmarker", function( len )
if not LVS.ShowHitMarker then return end
local ply = LocalPlayer()
local vehicle = ply:lvsGetVehicle()
if not IsValid( vehicle ) then return end
vehicle:HurtMarker( net.ReadFloat() )
end )
net.Receive( "lvs_hitmarker", function( len )
if not LVS.ShowHitMarker then return end
local ply = LocalPlayer()
local vehicle = ply:lvsGetVehicle()
local IsCrit = net.ReadBool()
if not IsValid( vehicle ) then
hook.Run( "LVS:OnHudIndicator", ply, IsCrit and "crit" or "hit" )
return
end
if IsCrit then
vehicle:CritMarker()
else
vehicle:HitMarker()
end
end )
net.Receive( "lvs_killmarker", function( len )
if not LVS.ShowHitMarker then return end
local ply = LocalPlayer()
local vehicle = ply:lvsGetVehicle()
if not IsValid( vehicle ) then
hook.Run( "LVS:OnHudIndicator", ply, "kill" )
return
end
vehicle:KillMarker()
end )
net.Receive( "lvs_armormarker", function( len )
if not LVS.ShowHitMarker then return end
local ply = LocalPlayer()
local vehicle = ply:lvsGetVehicle()
local IsDamage = net.ReadBool()
if not IsValid( vehicle ) then
hook.Run( "LVS:OnHudIndicator", ply, IsDamage and "armorcrit" or "armor" )
return
end
vehicle:ArmorMarker( IsDamage )
end )
return
end
util.AddNetworkString( "lvs_hitmarker" )
util.AddNetworkString( "lvs_hurtmarker" )
util.AddNetworkString( "lvs_killmarker" )
util.AddNetworkString( "lvs_armormarker" )

View File

@@ -0,0 +1,108 @@
LVS.VehiclesStored = LVS.VehiclesStored or {}
LVS.NPCsStored = LVS.NPCsStored or {}
function LVS:GetNPCs()
for index, ent in pairs( LVS.NPCsStored ) do
if not IsValid( ent ) then
LVS.NPCsStored[ index ] = nil
end
end
return LVS.NPCsStored
end
function LVS:GetVehicles()
for index, ent in pairs( LVS.VehiclesStored ) do
if not IsValid( ent ) then
LVS.VehiclesStored[ index ] = nil
end
end
return LVS.VehiclesStored
end
local Teams = {
["npc_breen"] = 1,
["npc_combine_s"] = 1,
["npc_combinedropship"] = 1,
["npc_combinegunship"] = 1,
["npc_crabsynth"] = 1,
["npc_cscanner"] = 1,
["npc_helicopter"] = 1,
["npc_manhack"] = 1,
["npc_metropolice"] = 1,
["npc_mortarsynth"] = 1,
["npc_sniper"] = 1,
["npc_stalker"] = 1,
["npc_strider"] = 1,
["npc_hunter"] = 1,
["monster_human_grunt"] = 1,
["monster_human_assassin"] = 1,
["monster_sentry"] = 1,
["npc_kleiner"] = 2,
["npc_monk"] = 2,
["npc_mossman"] = 2,
["npc_vortigaunt"] = 2,
["npc_alyx"] = 2,
["npc_barney"] = 2,
["npc_citizen"] = 2,
["npc_dog"] = 2,
["npc_eli"] = 2,
["monster_scientist"] = 2,
["monster_barney"] = 2,
["npc_zombine"] = 3,
["npc_fastzombie"] = 3,
["npc_headcrab"] = 3,
["npc_headcrab_black"] = 3,
["npc_headcrab_fast"] = 3,
["npc_antlion"] = 3,
["npc_antlionguard"] = 3,
["npc_zombie"] = 3,
["npc_zombie_torso"] = 3,
["npc_poisonzombie"] = 3,
["monster_alien_grunt"] = 3,
["monster_alien_slave"] = 3,
["monster_gargantua"] = 3,
["monster_bullchicken"] = 3,
["monster_headcrab"] = 3,
["monster_babycrab"] = 3,
["monster_zombie"] = 3,
["monster_houndeye"] = 3,
["monster_nihilanth"] = 3,
["monster_bigmomma"] = 3,
["monster_babycrab"] = 3,
}
function LVS:GetNPCRelationship( npc_class )
return Teams[ npc_class ] or 0
end
hook.Add( "OnEntityCreated", "!!!!lvsEntitySorter", function( ent )
timer.Simple( 2, function()
if not IsValid( ent ) then return end
if isfunction( ent.IsNPC ) and ent:IsNPC() then
table.insert( LVS.NPCsStored, ent )
if SERVER then
hook.Run( "LVS.UpdateRelationship", ent )
end
end
if ent.LVS then
if CLIENT and ent.PrintName then
language.Add( ent:GetClass(), ent.PrintName)
end
table.insert( LVS.VehiclesStored, ent )
if SERVER then
LVS:FixVelocity()
hook.Run( "LVS.UpdateRelationship", ent )
end
end
end )
end )

View File

@@ -0,0 +1,56 @@
local cVar_forcedirect = CreateConVar( "lvs_force_directinput", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"Force Direct Input Steering Method?" )
local cVar_forceindicator = CreateConVar( "lvs_force_forceindicator", "0", {FCVAR_REPLICATED , FCVAR_ARCHIVE},"Force Direct Input Steering Method?" )
function LVS:IsDirectInputForced()
return LVS.ForceDirectInput == true
end
function LVS:IsIndicatorForced()
return LVS.ForceIndicator == true
end
if SERVER then
util.AddNetworkString( "lvs_forced_input_getter" )
local function UpdateForcedSettings( ply )
net.Start( "lvs_forced_input_getter" )
net.WriteBool( LVS:IsDirectInputForced() )
net.WriteBool( LVS:IsIndicatorForced() )
if IsValid( ply ) then
net.Send( ply )
else
net.Broadcast()
end
end
LVS.ForceDirectInput = cVar_forcedirect and cVar_forcedirect:GetBool() or false
cvars.AddChangeCallback( "lvs_force_directinput", function( convar, oldValue, newValue )
LVS.ForceDirectInput = tonumber( newValue ) ~=0
UpdateForcedSettings()
end)
LVS.ForceIndicator = cVar_forceindicator and cVar_forceindicator:GetBool() or false
cvars.AddChangeCallback( "lvs_force_forceindicator", function( convar, oldValue, newValue )
LVS.ForceIndicator = tonumber( newValue ) ~=0
UpdateForcedSettings()
end)
net.Receive( "lvs_forced_input_getter", function( length, ply )
UpdateForcedSettings( ply )
end)
else
net.Receive( "lvs_forced_input_getter", function( length )
LVS.ForceDirectInput = net.ReadBool()
LVS.ForceIndicator = net.ReadBool()
end )
hook.Add( "InitPostEntity", "!11!!!lvsIsPlayerReady", function()
net.Start( "lvs_forced_input_getter" )
net.SendToServer()
end )
end

View File

@@ -0,0 +1,303 @@
hook.Add( "PhysgunPickup", "!!!!lvs_physgun_pickup", function( ply, ent )
if ent._lvsNoPhysgunInteraction then return false end
end )
hook.Add( "InitPostEntity", "!!!lvsBullshitFixer", function()
timer.Simple(1, function()
LVS.MapDoneLoading = true
end)
if SERVER then return end
local Defaults = {
["lvs_mouseaim_type_tank"] = 0,
["lvs_mouseaim_type_car"] = 0,
["lvs_mouseaim_type_repulsorlift"] = 1,
["lvs_mouseaim_type_helicopter"] = 1,
["lvs_mouseaim_type_plane"] = 1,
["lvs_mouseaim_type_walker"] = 0,
["lvs_mouseaim_type_starfighter"] = 1,
["lvs_mouseaim_type_fakehover"] = 0,
}
-- this needs to be here to make sure all sents are registered
for _, vehicletype in ipairs( LVS:GetVehicleTypes() ) do
local name = "lvs_mouseaim_type_"..vehicletype
local default = Defaults[ name ] or 0
CreateClientConVar( name, default, true, false)
end
end )
local function SetDistance( vehicle, ply )
local iWheel = ply:GetCurrentCommand():GetMouseWheel()
if iWheel == 0 or not vehicle.SetCameraDistance then return end
local newdist = math.Clamp( vehicle:GetCameraDistance() - iWheel * 0.03 * ( 1.1 + vehicle:GetCameraDistance() ), -1, 10 )
vehicle:SetCameraDistance( newdist )
end
local function SetHeight( vehicle, ply )
local iWheel = ply:GetCurrentCommand():GetMouseWheel()
if iWheel == 0 or not vehicle.SetCameraHeight then return end
local newdist = math.Clamp( vehicle:GetCameraHeight() - iWheel * 0.03 * ( 1.1 + vehicle:GetCameraHeight() ), -1, 10 )
vehicle:SetCameraHeight( newdist )
end
hook.Add( "VehicleMove", "!!!!lvs_vehiclemove", function( ply, vehicle, mv )
if not ply.lvsGetVehicle then return end
local veh = ply:lvsGetVehicle()
if not IsValid( veh ) then return end
if SERVER and ply:lvsKeyDown( "VIEWDIST" ) then
if ply:lvsKeyDown( "VIEWHEIGHT" ) then
SetHeight( vehicle, ply )
else
SetDistance( vehicle, ply )
end
end
if CLIENT and not IsFirstTimePredicted() then return end
local KeyThirdPerson = ply:lvsKeyDown("THIRDPERSON")
if ply._lvsOldThirdPerson ~= KeyThirdPerson then
ply._lvsOldThirdPerson = KeyThirdPerson
if KeyThirdPerson and vehicle.SetThirdPersonMode then
vehicle:SetThirdPersonMode( not vehicle:GetThirdPersonMode() )
end
end
return true
end )
hook.Add("CalcMainActivity", "!!!lvs_playeranimations", function(ply)
if not ply.lvsGetVehicle then return end
local Ent = ply:lvsGetVehicle()
if IsValid( Ent ) then
local A,B = Ent:CalcMainActivity( ply )
if A and B then
return A, B
end
end
end)
hook.Add("UpdateAnimation", "!!!lvs_playeranimations", function( ply, velocity, maxseqgroundspeed )
if not ply.lvsGetVehicle then return end
local Ent = ply:lvsGetVehicle()
if not IsValid( Ent ) then return end
return Ent:UpdateAnimation( ply, velocity, maxseqgroundspeed )
end)
hook.Add( "StartCommand", "!!!!LVS_grab_command", function( ply, cmd )
if not ply.lvsGetVehicle then return end
local veh = ply:lvsGetVehicle()
if not IsValid( veh ) then return end
veh:StartCommand( ply, cmd )
end )
hook.Add( "CanProperty", "!!!!lvsEditPropertiesDisabler", function( ply, property, ent )
if ent.LVS and not ply:IsAdmin() and property == "editentity" then return false end
end )
LVS.ToolsDisable = {
["rb655_easy_animation"] = true,
["rb655_easy_bonemerge"] = true,
["rb655_easy_inspector"] = true,
}
hook.Add( "CanTool", "!!!!lvsCanToolDisabler", function( ply, tr, toolname, tool, button )
if LVS.ToolsDisable[ toolname ] and IsValid( tr.Entity ) and tr.Entity.LVS then return false end
end )
if CLIENT then
local hide = {
["CHudHealth"] = true,
["CHudBattery"] = true,
["CHudAmmo"] = true,
["CHudSecondaryAmmo"] = true,
}
local function HUDShouldDrawLVS( name )
if hide[ name ] then return false end
end
hook.Add( "LVS.PlayerEnteredVehicle", "!!!!lvs_player_enter", function( ply, veh )
hook.Add( "HUDShouldDraw", "!!!!lvs_hidehud", HUDShouldDrawLVS )
if not IsValid( veh ) then return end
local cvar = GetConVar( "lvs_mouseaim_type" )
if not cvar or cvar:GetInt() ~= 1 or not veh.GetVehicleType then return end
local vehicletype = veh:GetVehicleType()
local cvar_type = GetConVar( "lvs_mouseaim_type_"..vehicletype )
local cvar_mouseaim = GetConVar( "lvs_mouseaim" )
if not cvar_type or not cvar_mouseaim then return end
cvar_mouseaim:SetInt( cvar_type:GetInt() )
end )
hook.Add( "LVS.PlayerLeaveVehicle", "!!!!lvs_player_exit", function( ply, veh )
hook.Remove( "HUDShouldDraw", "!!!!lvs_hidehud" )
end )
hook.Add( "InitPostEntity", "!!!lvs_infmap_velocity_fixer", function()
if not InfMap then
hook.Remove( "InitPostEntity", "!!!lvs_infmap_velocity_fixer" )
return
end
local meta = FindMetaTable( "Entity" )
if not InfMapOriginalGetVelocity then
InfMapOriginalGetVelocity = meta.GetVelocity
end
function meta:GetVelocity()
local Velocity = InfMapOriginalGetVelocity( self )
local EntTable = self:GetTable()
if not EntTable.LVS and not EntTable._lvsRepairToolLabel then return Velocity end
local Speed = Velocity:LengthSqr()
local T = CurTime()
if Speed > 10 then
EntTable._infmapEntityVelocity = Velocity
EntTable._infmapEntityVelocityTime = T + 0.6
else
if (EntTable._infmapEntityVelocityTime or 0) > T then
return EntTable._infmapEntityVelocity or vector_origin
end
end
return Velocity
end
end )
return
end
local DamageFix = {
["npc_hunter"] = true,
["npc_stalker"] = true,
["npc_strider"] = true,
["npc_combinegunship"] = true,
["npc_helicopter"] = true,
}
hook.Add( "EntityTakeDamage", "!!!_lvs_fix_vehicle_explosion_damage", function( target, dmginfo )
if not target:IsPlayer() then
if target.LVS then
local attacker = dmginfo:GetAttacker()
if IsValid( attacker ) and DamageFix[ attacker:GetClass() ] then
dmginfo:SetDamageType( DMG_AIRBOAT )
dmginfo:SetDamageForce( dmginfo:GetDamageForce():GetNormalized() * 15000 )
end
end
return
end
local veh = target:lvsGetVehicle()
if not IsValid( veh ) or dmginfo:IsDamageType( DMG_DIRECT ) then return end
if target:GetCollisionGroup() == COLLISION_GROUP_PLAYER then return end
dmginfo:SetDamage( 0 )
end )
hook.Add( "PlayerEnteredVehicle", "!!!!lvs_player_enter", function( ply, Pod )
local veh = ply:lvsGetVehicle()
if IsValid( veh ) then
net.Start( "lvs_player_enterexit" )
net.WriteBool( true )
net.WriteEntity( veh )
net.Send( ply )
ply._lvsIsInVehicle = true
if istable( veh.PlayerBoneManipulate ) then
local ID = Pod:lvsGetPodIndex()
local BoneManipulate = veh.PlayerBoneManipulate[ ID ]
if BoneManipulate then
ply._lvsStopBoneManipOnExit = true
ply:lvsStartBoneManip()
end
end
if LVS.FreezeTeams then
local nTeam = ply:lvsGetAITeam()
if veh:GetAITEAM() ~= nTeam then
veh:SetAITEAM( nTeam )
ply:PrintMessage( HUD_PRINTTALK, "[LVS] This Vehicle's AI-Team has been updated to: "..(LVS.TEAMS[ nTeam ] or "") )
end
end
end
if not Pod.HidePlayer then return end
ply:SetNoDraw( true )
if pac then pac.TogglePartDrawing( ply, 0 ) end
end )
hook.Add( "PlayerLeaveVehicle", "!!!!lvs_player_exit", function( ply, Pod )
if ply._lvsIsInVehicle then
net.Start( "lvs_player_enterexit" )
net.WriteBool( false )
net.WriteEntity( Pod:lvsGetVehicle() )
net.Send( ply )
ply._lvsIsInVehicle = nil
if ply._lvsStopBoneManipOnExit then
ply._lvsStopBoneManipOnExit = nil
ply:lvsStopBoneManip()
end
end
if not Pod.HidePlayer then return end
ply:SetNoDraw( false )
if pac then pac.TogglePartDrawing( ply, 1 ) end
end )
hook.Add( "PlayerDisconnected", "!!!!lvs_player_reset_bonemanip_client", function(ply)
if not ply._lvsStopBoneManipOnExit then return end
ply._lvsStopBoneManipOnExit = nil
ply:lvsStopBoneManip()
end )

View File

@@ -0,0 +1,508 @@
hook.Add( "LVS:Initialize", "!!11lvs_default_keys", function()
local KEYS = {
{
name = "ATTACK",
category = "Armament",
name_menu = "Attack",
default = MOUSE_LEFT,
cmd = "lvs_lmb"
},
{
name = "ZOOM",
category = "Armament",
name_menu = "Zoom",
default = MOUSE_RIGHT,
cmd = "lvs_rmb"
},
{
name = "~SELECT~WEAPON#1",
category = "Armament",
name_menu = "Select Weapon 1",
cmd = "lvs_select_weapon1"
},
{
name = "~SELECT~WEAPON#2",
category = "Armament",
name_menu = "Select Weapon 2",
cmd = "lvs_select_weapon2"
},
{
name = "~SELECT~WEAPON#3",
category = "Armament",
name_menu = "Select Weapon 3",
cmd = "lvs_select_weapon3"
},
{
name = "~SELECT~WEAPON#4",
category = "Armament",
name_menu = "Select Weapon 4",
cmd = "lvs_select_weapon4"
},
--[[ only adding 4 because i dont want to bloat the menu. There can be added as many keys as neededed the system should figure it out by itself
{
name = "~SELECT~WEAPON#5",
category = "Armament",
name_menu = "Select Weapon 5",
cmd = "lvs_select_weapon5"
},
]]
{
name = "EXIT",
category = "Misc",
name_menu = "Exit Vehicle",
default = "+use",
cmd = "lvs_exit"
},
{
name = "VIEWDIST",
category = "Misc",
name_menu = "Enable Mouse-Wheel Set-Camera-Distance",
default = MOUSE_MIDDLE,
cmd = "lvs_viewzoom"
},
{
name = "VIEWHEIGHT",
category = "Misc",
name_menu = "Set-Camera-Distance => Set-Camera-Height",
default = "phys_swap",
cmd = "lvs_viewheight"
},
{
name = "THIRDPERSON",
category = "Misc",
name_menu = "Toggle Thirdperson",
default = "+duck",
cmd = "lvs_thirdperson"
},
{
name = "FREELOOK",
category = "Misc",
name_menu = "Freelook (Hold)",
default = "+walk",
cmd = "lvs_freelook"
},
{
name = "ENGINE",
category = "Misc",
name_menu = "Toggle Engine",
default = "+reload",
cmd = "lvs_startengine"
},
{
name = "VSPEC",
category = "Misc",
name_menu = "Toggle Vehicle-specific Function",
default = "+jump",
cmd = "lvs_special"
},
}
for _, v in pairs( KEYS ) do
LVS:AddKey( v.name, v.category, v.name_menu, v.cmd, v.default )
end
end )
hook.Add( "LVS:Initialize", "[LVS] - Cars - Keys", function()
local KEYS = {
{
name = "CAR_THROTTLE",
category = "LVS-Car",
name_menu = "Throttle",
default = "+forward",
cmd = "lvs_car_throttle"
},
{
name = "CAR_THROTTLE_MOD",
category = "LVS-Car",
name_menu = "Throttle Modifier",
default = "+speed",
cmd = "lvs_car_speed"
},
{
name = "CAR_BRAKE",
category = "LVS-Car",
name_menu = "Brake",
default = "+back",
cmd = "lvs_car_brake"
},
{
name = "CAR_HANDBRAKE",
category = "LVS-Car",
name_menu = "Handbrake",
default = "+jump",
cmd = "lvs_car_handbrake"
},
{
name = "CAR_STEER_LEFT",
category = "LVS-Car",
name_menu = "Steer Left",
default = "+moveleft",
cmd = "lvs_car_turnleft"
},
{
name = "CAR_STEER_RIGHT",
category = "LVS-Car",
name_menu = "Steer Right",
default = "+moveright",
cmd = "lvs_car_turnright"
},
{
name = "CAR_LIGHTS_TOGGLE",
category = "LVS-Car",
name_menu = "Toggle Lights",
default = "phys_swap",
cmd = "lvs_car_toggle_lights"
},
{
name = "CAR_MENU",
category = "LVS-Car",
name_menu = "Open Signal Menu",
default = "+zoom",
cmd = "lvs_car_menu"
},
{
name = "CAR_SIREN",
category = "LVS-Car",
name_menu = "Open Siren Menu",
default = "phys_swap",
cmd = "lvs_car_siren"
},
{
name = "CAR_SWAP_AMMO",
category = "LVS-Car",
name_menu = "Change Ammo Type",
default = "+walk",
cmd = "lvs_car_swap_ammo"
},
{
name = "CAR_HYDRAULIC",
category = "LVS-Car",
name_menu = "Hydraulic",
default = KEY_PAD_5,
cmd = "lvs_hydraulic"
},
{
name = "CAR_HYDRAULIC_FRONT",
category = "LVS-Car",
name_menu = "Hydraulic Front",
default = KEY_PAD_8,
cmd = "lvs_hydraulic_front"
},
{
name = "CAR_HYDRAULIC_REAR",
category = "LVS-Car",
name_menu = "Hydraulic Rear",
default = KEY_PAD_2,
cmd = "lvs_hydraulic_rear"
},
{
name = "CAR_HYDRAULIC_LEFT",
category = "LVS-Car",
name_menu = "Hydraulic Left",
default = KEY_PAD_4,
cmd = "lvs_hydraulic_left"
},
{
name = "CAR_HYDRAULIC_RIGHT",
category = "LVS-Car",
name_menu = "Hydraulic Right",
default = KEY_PAD_6,
cmd = "lvs_hydraulic_right"
},
{
name = "CAR_SHIFT_UP",
category = "LVS-Car",
name_menu = "Shift Up",
cmd = "lvs_car_shift_up"
},
{
name = "CAR_SHIFT_DN",
category = "LVS-Car",
name_menu = "Shift Down",
cmd = "lvs_car_shift_dn"
},
}
for _, v in pairs( KEYS ) do
LVS:AddKey( v.name, v.category, v.name_menu, v.cmd, v.default )
end
end )
hook.Add( "LVS:Initialize", "[LVS] - Helicopter - Keys", function()
local KEYS = {
{
name = "+THRUST_HELI",
category = "LVS-Helicopter",
name_menu = "Throttle Increase",
default = "+forward",
cmd = "lvs_helicopter_throttle_up"
},
{
name = "-THRUST_HELI",
category = "LVS-Helicopter",
name_menu = "Throttle Decrease",
default = "+back",
cmd = "lvs_helicopter_throttle_down"
},
{
name = "+PITCH_HELI",
category = "LVS-Helicopter",
name_menu = "Pitch Up",
cmd = "lvs_helicopter_pitch_up"
},
{
name = "-PITCH_HELI",
category = "LVS-Helicopter",
name_menu = "Pitch Down",
cmd = "lvs_helicopter_pitch_down"
},
{
name = "-YAW_HELI",
category = "LVS-Helicopter",
name_menu = "Yaw Left [Roll in Direct Input]",
cmd = "lvs_helicopter_yaw_left"
},
{
name = "+YAW_HELI",
category = "LVS-Helicopter",
name_menu = "Yaw Right [Roll in Direct Input]",
cmd = "lvs_helicopter_yaw_right"
},
{
name = "-ROLL_HELI",
category = "LVS-Helicopter",
name_menu = "Roll Left [Yaw in Direct Input]",
default = "+moveleft",
cmd = "lvs_helicopter_roll_left"
},
{
name = "+ROLL_HELI",
category = "LVS-Helicopter",
name_menu = "Roll Right [Yaw in Direct Input]",
default = "+moveright",
cmd = "lvs_helicopter_roll_right"
},
{
name = "HELI_HOVER",
category = "LVS-Helicopter",
name_menu = "Hover",
default = "+speed",
cmd = "lvs_helicopter_hover"
},
}
for _, v in pairs( KEYS ) do
LVS:AddKey( v.name, v.category, v.name_menu, v.cmd, v.default )
end
end )
hook.Add( "LVS:Initialize", "[LVS] - Planes - Keys", function()
local KEYS = {
{
name = "+THROTTLE",
category = "LVS-Plane",
name_menu = "Throttle Increase",
default = "+forward",
cmd = "lvs_plane_throttle_up"
},
{
name = "-THROTTLE",
category = "LVS-Plane",
name_menu = "Throttle Decrease",
default = "+back",
cmd = "lvs_plane_throttle_down"
},
{
name = "+PITCH",
category = "LVS-Plane",
name_menu = "Pitch Up",
default = "+speed",
cmd = "lvs_plane_pitch_up"
},
{
name = "-PITCH",
category = "LVS-Plane",
name_menu = "Pitch Down",
cmd = "lvs_plane_pitch_down"
},
{
name = "-YAW",
category = "LVS-Plane",
name_menu = "Yaw Left [Roll in Direct Input]",
cmd = "lvs_plane_yaw_left"
},
{
name = "+YAW",
category = "LVS-Plane",
name_menu = "Yaw Right [Roll in Direct Input]",
cmd = "lvs_plane_yaw_right"
},
{
name = "-ROLL",
category = "LVS-Plane",
name_menu = "Roll Left [Yaw in Direct Input]",
default = "+moveleft",
cmd = "lvs_plane_roll_left"
},
{
name = "+ROLL",
category = "LVS-Plane",
name_menu = "Roll Right [Yaw in Direct Input]",
default = "+moveright",
cmd = "lvs_plane_roll_right"
},
}
for _, v in pairs( KEYS ) do
LVS:AddKey( v.name, v.category, v.name_menu, v.cmd, v.default )
end
end )
hook.Add( "LVS:Initialize", "[LVS] - Star Wars - Keys", function()
local KEYS = {
{
name = "+THRUST_SF",
category = "LVS-Starfighter",
name_menu = "Thrust Increase",
default = "+forward",
cmd = "lvs_starfighter_throttle_up"
},
{
name = "-THRUST_SF",
category = "LVS-Starfighter",
name_menu = "Thrust Decrease",
default = "+back",
cmd = "lvs_starfighter_throttle_down"
},
{
name = "+PITCH_SF",
category = "LVS-Starfighter",
name_menu = "Pitch Up",
default = "+speed",
cmd = "lvs_starfighter_pitch_up"
},
{
name = "-PITCH_SF",
category = "LVS-Starfighter",
name_menu = "Pitch Down",
cmd = "lvs_starfighter_pitch_down"
},
{
name = "-YAW_SF",
category = "LVS-Starfighter",
name_menu = "Yaw Left [Roll in Direct Input]",
cmd = "lvs_starfighter_yaw_left"
},
{
name = "+YAW_SF",
category = "LVS-Starfighter",
name_menu = "Yaw Right [Roll in Direct Input]",
cmd = "lvs_starfighter_yaw_right"
},
{
name = "-ROLL_SF",
category = "LVS-Starfighter",
name_menu = "Roll Left [Yaw in Direct Input]",
default = "+moveleft",
cmd = "lvs_starfighter_roll_left"
},
{
name = "+ROLL_SF",
category = "LVS-Starfighter",
name_menu = "Roll Right [Yaw in Direct Input]",
default = "+moveright",
cmd = "lvs_starfighter_roll_right"
},
{
name = "+VTOL_Z_SF",
category = "LVS-Starfighter",
name_menu = "VTOL Up",
cmd = "lvs_starfighter_vtol_up"
},
{
name = "-VTOL_Z_SF",
category = "LVS-Starfighter",
name_menu = "VTOL Down",
cmd = "lvs_starfighter_vtol_dn"
},
{
name = "-VTOL_Y_SF",
category = "LVS-Starfighter",
name_menu = "VTOL Right",
cmd = "lvs_starfighter_vtol_right"
},
{
name = "+VTOL_Y_SF",
category = "LVS-Starfighter",
name_menu = "VTOL Left",
cmd = "lvs_starfighter_vtol_left"
},
{
name = "-VTOL_X_SF",
category = "LVS-Starfighter",
name_menu = "VTOL Reverse",
default = "+back",
cmd = "lvs_starfighter_vtol_reverse"
},
}
for _, v in pairs( KEYS ) do
LVS:AddKey( v.name, v.category, v.name_menu, v.cmd, v.default )
end
end )
if SERVER then return end
concommand.Add( "lvs_mouseaim_toggle", function( ply, cmd, args )
local OldVar = GetConVar( "lvs_mouseaim" ):GetInt()
if OldVar == 0 then
ply:PrintMessage( HUD_PRINTTALK, "[LVS] Mouse-Aim: Enabled" )
RunConsoleCommand( "lvs_mouseaim", "1" )
else
ply:PrintMessage( HUD_PRINTTALK, "[LVS] Mouse-Aim: Disabled" )
RunConsoleCommand( "lvs_mouseaim", "0" )
end
end )
hook.Add( "PlayerBindPress", "!!!!_LVS_PlayerBindPress", function( ply, bind, pressed )
if not ply.lvsGetVehicle then return end
local vehicle = ply:lvsGetVehicle()
if not IsValid( vehicle ) then return end
if not ply:lvsKeyDown( "VIEWDIST" ) then
if string.find( bind, "invnext" ) then
vehicle:NextWeapon()
end
if string.find( bind, "invprev" ) then
vehicle:PrevWeapon()
end
end
if string.find( bind, "+zoom" ) then
if vehicle.lvsDisableZoom then
return true
end
end
end )
hook.Add( "SpawnMenuOpen", "!!!lvs_spawnmenudisable", function()
local ply = LocalPlayer()
if not ply._lvsDisableSpawnMenu or not IsValid( ply:lvsGetVehicle() ) then return end
return false
end )
hook.Add( "ContextMenuOpen", "!!!lvs_contextmenudisable", function()
local ply = LocalPlayer()
if not ply._lvsDisableContextMenu or not IsValid( ply:lvsGetVehicle() ) then return end
return false
end )

View File

@@ -0,0 +1,83 @@
if SERVER then
util.AddNetworkString( "lvs_player_request_filter" )
util.AddNetworkString( "lvs_player_enterexit" )
util.AddNetworkString( "lvs_toggle_mouseaim" )
util.AddNetworkString( "lvs_car_turnsignal" )
util.AddNetworkString( "lvs_car_break" )
net.Receive( "lvs_car_turnsignal", function( len, ply )
if not IsValid( ply ) then return end
local veh = ply:lvsGetVehicle()
if not IsValid( veh ) or veh:GetDriver() ~= ply then return end
veh:SetTurnMode( net.ReadInt( 4 ) )
end )
net.Receive( "lvs_toggle_mouseaim", function( length, ply )
ply:lvsBuildControls()
local veh = ply:lvsGetVehicle()
if not IsValid( veh ) then return end
veh:AlignView( ply )
end)
net.Receive( "lvs_player_request_filter", function( length, ply )
if not IsValid( ply ) then return end
local ent = net.ReadEntity()
if not IsValid( ent ) or not ent.GetCrosshairFilterEnts then return end -- TODO: Make this loop around and wait for ent.IsInitialized to exist and ent:IsInitialized() to return true
local CrosshairFilterEnts = table.Copy( ent:GetCrosshairFilterEnts() )
for id, entity in pairs( CrosshairFilterEnts ) do
if not IsValid( entity ) or entity:GetNoDraw() then
CrosshairFilterEnts[ id ] = nil
end
end
net.Start( "lvs_player_request_filter" )
net.WriteEntity( ent )
net.WriteTable( CrosshairFilterEnts )
net.Send( ply )
end)
else
net.Receive("lvs_car_break", function( len )
local ent = net.ReadEntity()
if not IsValid( ent ) or not isfunction( ent.OnEngineStallBroken ) then return end
ent:OnEngineStallBroken()
end)
net.Receive( "lvs_player_request_filter", function( length )
local LVSent = net.ReadEntity()
if not IsValid( LVSent ) then return end
local Filter = {}
for _, entity in pairs( net.ReadTable() ) do
if not IsValid( entity ) then continue end
table.insert( Filter, entity )
end
LVSent.CrosshairFilterEnts = Filter
end )
net.Receive( "lvs_player_enterexit", function( len )
local Enable = net.ReadBool()
local Vehicle = net.ReadEntity()
if Enable then
hook.Run( "LVS.PlayerEnteredVehicle", LocalPlayer(), Vehicle )
else
hook.Run( "LVS.PlayerLeaveVehicle", LocalPlayer(), Vehicle )
end
end )
end

View File

@@ -0,0 +1,417 @@
local meta = FindMetaTable( "Player" )
function meta:lvsGetAITeam()
return self:GetNWInt( "lvsAITeam", LVS.PlayerDefaultTeam )
end
function meta:lvsGetVehicle()
local Pod = self:GetVehicle()
if not IsValid( Pod ) then return NULL end
if Pod.LVSchecked then
return Pod.LVSBaseEnt
else
local Parent = Pod:GetParent()
if not IsValid( Parent ) then return NULL end
if not Parent.LVS then
Pod.LVSchecked = LVS.MapDoneLoading
Pod.LVSBaseEnt = NULL
return NULL
end
Pod.LVSchecked = LVS.MapDoneLoading
Pod.LVSBaseEnt = Parent
return Parent
end
end
function meta:lvsGetWeaponHandler()
local Pod = self:GetVehicle()
if not IsValid( Pod ) then return NULL end
local weapon = Pod:lvsGetWeapon()
if IsValid( weapon ) then
return weapon
else
local veh = self:lvsGetVehicle()
if not IsValid( veh ) then return NULL end
if veh:GetDriver() == self then
return veh
else
return NULL
end
end
end
function meta:lvsGetControls()
if not istable( self.LVS_BINDS ) then
self:lvsBuildControls()
end
return self.LVS_BINDS
end
function meta:lvsMouseAim()
if LVS:IsDirectInputForced() then
return false
end
return self._lvsMouseAim
end
function meta:lvsMouseSensitivity()
local X = self._lvsMouseX or 1
local Y = self._lvsMouseY or 1
local delta = self._lvsReturnDelta or 1
return X, Y, delta
end
function meta:lvsBuildControls()
if istable( self.LVS_BINDS ) then
table.Empty( self.LVS_BINDS )
end
if SERVER then
self._lvsMouseAim = self:GetInfoNum( "lvs_mouseaim", 0 ) == 1
self.LVS_BINDS = table.Copy( LVS.KEYS_CATEGORIES )
for _,v in pairs( LVS.KEYS_REGISTERED ) do
if v.id == "~SKIP~" then continue end
local ButtonID = self:GetInfoNum( v.cmd, 0 )
if not self.LVS_BINDS[v.category][ ButtonID ] then
self.LVS_BINDS[v.category][ ButtonID ] = {}
end
table.insert( self.LVS_BINDS[v.category][ ButtonID ], v.id )
end
net.Start( "lvs_buildcontrols" )
net.Send( self )
self._lvsMouseX = self:GetInfoNum( "lvs_sensitivity_x", 1 )
self._lvsMouseY = self:GetInfoNum( "lvs_sensitivity_y", 1 )
self._lvsReturnDelta = self:GetInfoNum( "lvs_return_delta", 1 )
else
self._lvsMouseAim = GetConVar( "lvs_mouseaim" ):GetInt() == 1
self._lvsMouseX = GetConVar( "lvs_sensitivity_x" ):GetFloat()
self._lvsMouseY = GetConVar( "lvs_sensitivity_y" ):GetFloat()
self._lvsReturnDelta = GetConVar( "lvs_return_delta" ):GetFloat()
self.LVS_BINDS = {}
local KeySpawnMenu = input.LookupBinding( "+menu" )
if isstring( KeySpawnMenu ) then
KeySpawnMenu = input.GetKeyCode( KeySpawnMenu )
end
local KeyContextMenu = input.LookupBinding( "+menu_context" )
if isstring( KeyContextMenu ) then
KeyContextMenu = input.GetKeyCode( KeyContextMenu )
end
self._lvsDisableSpawnMenu = nil
self._lvsDisableContextMenu = nil
for _,v in pairs( LVS.KEYS_REGISTERED ) do
if v.id == "~SKIP~" then continue end
local KeyCode = GetConVar( v.cmd ):GetInt()
self.LVS_BINDS[ v.id ] = KeyCode
if KeyCode == KeySpawnMenu then
self._lvsDisableSpawnMenu = true
end
if KeyCode == KeyContextMenu then
self._lvsDisableContextMenu = true
end
end
end
end
local IS_MOUSE_ENUM = {
[MOUSE_LEFT] = true,
[MOUSE_RIGHT] = true,
[MOUSE_MIDDLE] = true,
[MOUSE_4] = true,
[MOUSE_5] = true,
[MOUSE_WHEEL_UP] = true,
[MOUSE_WHEEL_DOWN] = true,
}
local function GetInput( ply, name )
if SERVER then
if not ply._lvsKeyDown then
ply._lvsKeyDown = {}
end
return ply._lvsKeyDown[ name ] == true
else
local Key = ply:lvsGetControls()[ name ] or 0
if IS_MOUSE_ENUM[ Key ] then
return input.IsMouseDown( Key )
else
return input.IsKeyDown( Key )
end
end
end
function meta:lvsKeyDown( name )
if not self:lvsGetInputEnabled() then return false end
local Pressed = GetInput( self, name )
local NewPressed = hook.Run( "LVS.PlayerKeyDown", self, name, Pressed )
if isbool( NewPressed ) then
return NewPressed
else
return Pressed
end
end
function meta:lvsGetInputEnabled()
return (self._lvsKeyDisabler or 0) < CurTime()
end
function meta:lvsSetInputDisabled( disable )
if CLIENT then
net.Start( "lvs_buildcontrols" )
net.WriteBool( disable )
net.SendToServer()
end
if disable then
self._lvsKeyDisabler = CurTime() + 120
else
self._lvsKeyDisabler = CurTime() + 0.25
end
end
if CLIENT then
function meta:lvsSetView( view )
self._lvsViewPos = view.origin or vector_origin
self._lvsViewAngles = view.angles or angle_zero
return view
end
function meta:lvsGetView()
local pos = self._lvsViewPos or vector_origin
local ang = self._lvsViewAngles or angle_zero
return pos, ang
end
net.Receive( "lvs_buildcontrols", function( len )
local ply = LocalPlayer()
if not IsValid( ply ) then return end
ply:lvsBuildControls()
end )
local OldVisible = false
local function KeyBlocker()
local Visible = gui.IsGameUIVisible() or vgui.CursorVisible()
if Visible ~= OldVisible then
OldVisible = Visible
local ply = LocalPlayer()
if not IsValid( ply ) then return end
if Visible then
ply:lvsSetInputDisabled( true )
else
ply:lvsSetInputDisabled( false )
end
end
end
hook.Add( "LVS.PlayerEnteredVehicle", "!!!!!lvs_keyblocker_enable", function( ply, veh )
hook.Add("PostDrawHUD", "!!!lvs_keyblocker", KeyBlocker )
end )
hook.Add( "LVS.PlayerLeaveVehicle", "!!!!!lvs_keyblocker_disable", function( ply, veh )
hook.Remove("PostDrawHUD", "!!!lvs_keyblocker" )
end )
local players_bonemanip = {}
local function StartBoneManip( id )
players_bonemanip[ id ] = true
end
local function StopBoneManip( id )
if not players_bonemanip[ id ] then return end
players_bonemanip[ id ] = nil
local ply = Entity( id )
if not IsValid( ply ) then return end
local angle_zero = Angle(0,0,0)
for i = 0, (ply:GetBoneCount() - 1) do
ply:ManipulateBoneAngles( i, angle_zero )
end
end
net.Receive( "lvs_bonemanip", function( len )
local entindex = net.ReadInt( 9 )
local enable = net.ReadBool()
if enable then
StartBoneManip( entindex )
return
end
StopBoneManip( entindex )
end )
hook.Add( "Think", "!!!!!lvs_player_bonemanip", function()
for EntID, _ in pairs( players_bonemanip ) do
local ply = Entity( EntID )
if not IsValid( ply ) or not ply:IsPlayer() then continue end
local Pod = ply:GetVehicle()
local vehicle = ply:lvsGetVehicle()
if not IsValid( Pod ) or not IsValid( vehicle ) then return end
local BoneManipulate = vehicle:GetPlayerBoneManipulation( ply, Pod:lvsGetPodIndex() )
for name, ang in pairs( BoneManipulate ) do
local bone = ply:LookupBone( name )
if not bone then continue end
ply:ManipulateBoneAngles( bone, ang )
end
end
end )
return
end
util.AddNetworkString( "lvs_buildcontrols" )
util.AddNetworkString( "lvs_bonemanip" )
function meta:lvsStartBoneManip()
net.Start( "lvs_bonemanip" )
net.WriteInt( self:EntIndex(), 9 )
net.WriteBool( true )
net.Broadcast()
end
function meta:lvsStopBoneManip()
net.Start( "lvs_bonemanip" )
net.WriteInt( self:EntIndex(), 9 )
net.WriteBool( false )
net.Broadcast()
end
net.Receive( "lvs_buildcontrols", function( len, ply )
if not IsValid( ply ) then return end
ply:lvsSetInputDisabled( net.ReadBool() )
end )
function meta:lvsSetInput( name, value )
if not self._lvsKeyDown then
self._lvsKeyDown = {}
end
self._lvsKeyDown[ name ] = value
end
LVS.TEAMS = {
[0] = "FRIENDLY TO EVERYONE",
[1] = "Team 1",
[2] = "Team 2",
[3] = "HOSTILE TO EVERYONE",
}
function meta:lvsSetAITeam( nTeam )
nTeam = nTeam or LVS.PlayerDefaultTeam
if self:lvsGetAITeam() ~= nTeam then
self:PrintMessage( HUD_PRINTTALK, "[LVS] Your AI-Team has been updated to: "..(LVS.TEAMS[ nTeam ] or "") )
end
self:SetNWInt( "lvsAITeam", nTeam )
end
hook.Add( "PlayerButtonUp", "!!!lvsButtonUp", function( ply, button )
for _, KeyBind in pairs( ply:lvsGetControls() ) do
local KeyTBL = KeyBind[ button ]
if not KeyTBL then continue end
for _, KeyName in pairs( KeyTBL ) do
ply:lvsSetInput( KeyName, false )
end
end
end )
hook.Add( "PlayerButtonDown", "!!!lvsButtonDown", function( ply, button )
if not ply:lvsGetInputEnabled() then return end
local vehicle = ply:lvsGetVehicle()
local vehValid = IsValid( vehicle )
for _, KeyBind in pairs( ply:lvsGetControls() ) do
local KeyTBL = KeyBind[ button ]
if not KeyTBL then continue end
for _, KeyName in pairs( KeyTBL ) do
ply:lvsSetInput( KeyName, true )
if not vehValid then continue end
if string.StartWith( KeyName, "~SELECT~" ) then
local exp_string = string.Explode( "#", KeyName )
local base = ply:lvsGetWeaponHandler()
if exp_string[2] and IsValid( base ) then
base:SelectWeapon( tonumber( exp_string[2] ) )
end
end
if KeyName == "EXIT" then
if vehicle:GetDriver() == ply and vehicle:GetlvsLockedStatus() then vehicle:UnLock() end
if vehicle:GetlvsLockedStatus() then continue end
local T = CurTime()
if (ply._lvsNextExit or 0) > T then continue end
ply:ExitVehicle()
end
end
end
end )
hook.Add("CanExitVehicle","!!!lvsCanExitVehicle",function(vehicle,ply)
if IsValid( ply:lvsGetVehicle() ) then return false end
end)

View File

@@ -0,0 +1,195 @@
local meta = FindMetaTable( "Vehicle" )
function meta:lvsGetVehicle()
if self.LVSchecked then
return self.LVSBaseEnt
else
local Parent = self:GetParent()
if not IsValid( Parent ) then return NULL end
if not Parent.LVS then
self.LVSchecked = LVS.MapDoneLoading
self.LVSBaseEnt = NULL
return NULL
end
self.LVSchecked = LVS.MapDoneLoading
self.LVSBaseEnt = Parent
return Parent
end
end
if CLIENT then
function meta:lvsGetPodIndex()
local id = self:GetNWInt( "pPodIndex", -1 )
if id ~= -1 then return id end
-- code below is bandaid fix for ent:GetNWInt taking up to 5 minutes to update on client...
local col = self:GetColor()
local id_by_color = col.r
-- 255 or 0 is suspicous...
if id_by_color == 255 or id_by_color == 0 then return -1 end
-- lets just assume its right... right?
if id_by_color == col.g and id_by_color == col.b then
return id_by_color
end
return -1
end
function meta:GetCameraHeight()
if not self._lvsCamHeight then
self._lvsCamHeight = 0
net.Start("lvs_camera")
net.WriteEntity( self )
net.SendToServer()
end
return self._lvsCamHeight
end
function meta:SetCameraHeight( newheight )
self._lvsCamHeight = newheight
end
function meta:lvsGetWeapon()
if self._lvsWeaponEntChecked then
return self._lvsWeaponEnt
end
local found = false
for _, ent in ipairs( self:GetChildren() ) do
if not ent.LVS_GUNNER then continue end
self._lvsWeaponEntChecked = true
self._lvsWeaponEnt = ent
found = true
break
end
return found and self._lvsWeaponEnt or NULL
end
net.Receive( "lvs_select_weapon", function( length)
local ply = LocalPlayer()
local vehicle = ply:lvsGetVehicle()
if not IsValid( vehicle ) or vehicle:GetDriver() ~= ply then return end
vehicle._SelectActiveTime = CurTime() + 2
end)
net.Receive( "lvs_camera", function( length, ply )
local pod = net.ReadEntity()
if not IsValid( pod ) then return end
pod:SetCameraHeight( net.ReadFloat() )
end)
return
end
function meta:lvsGetPodIndex()
return self:GetNWInt( "pPodIndex", -1 )
end
function meta:GetCameraHeight()
return (self._lvsCamHeight or 0)
end
util.AddNetworkString( "lvs_select_weapon" )
util.AddNetworkString( "lvs_camera" )
net.Receive( "lvs_select_weapon", function( length, ply )
if not IsValid( ply ) then return end
local ID = net.ReadInt( 5 )
local Increment = net.ReadBool()
local base = ply:lvsGetWeaponHandler()
if not IsValid( base ) then return end
if Increment then
base:SelectWeapon( base:GetSelectedWeapon() + ID )
else
base:SelectWeapon( ID )
end
end)
net.Receive( "lvs_camera", function( length, ply )
if not IsValid( ply ) then return end
local pod = net.ReadEntity()
if not IsValid( pod ) then return end
net.Start("lvs_camera")
net.WriteEntity( pod )
net.WriteFloat( pod:GetCameraHeight() )
net.Send( ply )
end)
function meta:SetCameraHeight( newheight )
self._lvsCamHeight = newheight
net.Start("lvs_camera")
net.WriteEntity( self )
net.WriteFloat( newheight )
net.Broadcast()
end
function meta:lvsAddWeapon( ID )
if IsValid( self._lvsWeaponEnt ) then
return self._lvsWeaponEnt
end
local weapon = ents.Create( "lvs_base_gunner" )
if not IsValid( weapon ) then return NULL end
weapon:SetPos( self:LocalToWorld( Vector(0,0,33.182617) ) ) -- location exactly where ply:GetShootPos() is. This will make AI-Tracing easier.
weapon:SetAngles( self:LocalToWorldAngles( Angle(0,90,0) ) )
weapon:SetOwner( self )
weapon:Spawn()
weapon:Activate()
weapon:SetParent( self )
weapon:SetPodIndex( ID )
weapon:SetDriverSeat( self )
self._lvsWeaponEnt = weapon
weapon:SetSelectedWeapon( 1 )
return weapon
end
function meta:lvsGetWeapon()
return self._lvsWeaponEnt
end
function meta:lvsSetPodIndex( index )
-- garbage networking
self:SetNWInt( "pPodIndex", index )
self:SetMaterial( "null" )
-- more reliable networking, lol
self:SetColor( Color( index, index, index, 0 ) )
end

View File

@@ -0,0 +1,194 @@
sound.Add( {
name = "LVS.Physics.Scrape",
channel = CHAN_STATIC,
level = 80,
sound = "lvs/physics/scrape_loop.wav"
} )
sound.Add( {
name = "LVS.Physics.Wind",
channel = CHAN_STATIC,
level = 140,
sound = "lvs/physics/wind_loop.wav",
} )
sound.Add( {
name = "LVS.Physics.Water",
channel = CHAN_STATIC,
level = 140,
sound = "lvs/physics/water_loop.wav",
} )
sound.Add( {
name = "LVS.DYNAMIC_EXPLOSION",
channel = CHAN_STATIC,
volume = 1.0,
level = 130,
pitch = {90, 110},
sound = "^lvs/explosion_dist.wav"
} )
sound.Add( {
name = "LVS.MISSILE_EXPLOSION",
channel = CHAN_STATIC,
volume = 1.0,
level = 130,
pitch = {90, 120},
sound = {
"ambient/levels/streetwar/city_battle17.wav",
"ambient/levels/streetwar/city_battle18.wav",
"ambient/levels/streetwar/city_battle19.wav",
}
} )
sound.Add( {
name = "LVS.BOMB_EXPLOSION_DYNAMIC",
channel = CHAN_STATIC,
volume = 1,
level = 135,
pitch = {90, 110},
sound = {
"^lvs/explosions/dyn1.wav",
"^lvs/explosions/dyn2.wav",
"^lvs/explosions/dyn3.wav",
"^lvs/explosions/dyn4.wav",
}
} )
sound.Add( {
name = "LVS.BOMB_EXPLOSION",
channel = CHAN_STATIC,
volume = 1,
level = 75,
pitch = {90, 110},
sound = {
"lvs/explosions/close1.wav",
"lvs/explosions/close2.wav",
"lvs/explosions/close3.wav",
"lvs/explosions/close4.wav",
}
} )
sound.Add( {
name = "LVS.BULLET_EXPLOSION_DYNAMIC",
channel = CHAN_STATIC,
volume = 1,
level = 135,
pitch = {90, 110},
sound = {
"^lvs/explosions/med_dyn1.wav",
"^lvs/explosions/med_dyn2.wav",
"^lvs/explosions/med_dyn3.wav",
"^lvs/explosions/med_dyn4.wav",
}
} )
sound.Add( {
name = "LVS.BULLET_EXPLOSION",
channel = CHAN_STATIC,
volume = 1,
level = 75,
pitch = {90, 110},
sound = {
"lvs/explosions/med_close1.wav",
"lvs/explosions/med_close2.wav",
"lvs/explosions/med_close3.wav",
"lvs/explosions/med_close4.wav",
}
} )
sound.Add( {
name = "LVS.EXPLOSION",
channel = CHAN_STATIC,
volume = 1.0,
level = 115,
pitch = {95, 115},
sound = "lvs/explosion.wav"
} )
sound.Add( {
name = "LVS_MISSILE_FIRE",
channel = CHAN_WEAPON,
volume = 1.0,
level = 90,
sound = {
"^lvs/weapons/missile_1.wav",
"^lvs/weapons/missile_2.wav",
"^lvs/weapons/missile_3.wav",
"^lvs/weapons/missile_4.wav",
}
} )
sound.Add( {
name = "LVS_FIGHTERPLANE_CRASH",
channel = CHAN_STATIC,
volume = 1.0,
level = 128,
sound = {
"lvs/vehicles/generic/figher_crash1.wav",
"lvs/vehicles/generic/figher_crash2.wav",
}
} )
sound.Add( {
name = "LVS_BOMBERPLANE_CRASH",
channel = CHAN_STATIC,
volume = 1.0,
level = 128,
sound = {
"lvs/vehicles/generic/bomber_crash1.wav",
"lvs/vehicles/generic/bomber_crash2.wav",
"lvs/vehicles/generic/bomber_crash3.wav",
}
} )
sound.Add( {
name = "LVS.Brake.Release",
channel = CHAN_STATIC,
level = 75,
volume = 1,
sound = {
"lvs/vehicles/generic/pneumatic_brake_release_01.wav",
"lvs/vehicles/generic/pneumatic_brake_release_02.wav",
"lvs/vehicles/generic/pneumatic_brake_release_03.wav",
"lvs/vehicles/generic/pneumatic_brake_release_04.wav",
}
} )
sound.Add( {
name = "LVS.Brake.Apply",
channel = CHAN_STATIC,
level = 75,
volume = 1,
sound = "lvs/vehicles/generic/pneumatic_brake_pull.wav",
} )
if CLIENT then
local SoundList = {}
hook.Add( "EntityEmitSound", "!!!lvs_fps_rape_fixer", function( t )
if not t.Entity.LVS and not t.Entity._LVS then return end
local SoundFile = t.SoundName
if SoundList[ SoundFile ] == true then
return true
elseif SoundList[ SoundFile ] == false then
return false
else
local File = string.Replace( SoundFile, "^", "" )
local Exists = file.Exists( "sound/"..File , "GAME" )
SoundList[ SoundFile ] = Exists
if not Exists then
print("[LVS] '"..SoundFile.."' not found. Soundfile will not be played and is filtered for this game session to avoid fps issues.")
end
end
end )
end

View File

@@ -0,0 +1,69 @@
local function ApplyTeamRules( teamVeh, IsEnemy )
if teamVeh == 0 then
IsEnemy = false
end
if teamVeh == 3 then
IsEnemy = true
end
return IsEnemy
end
function LVS:SetNPCRelationship( NPC )
for _, lvsVeh in pairs( LVS:GetVehicles() ) do
local teamVeh = lvsVeh:GetAITEAM()
local IsEnemy = ApplyTeamRules( teamVeh, lvsVeh:IsEnemy( NPC ) )
local IsActive = (lvsVeh:GetAI() or #lvsVeh:GetEveryone() > 0) and not lvsVeh:IsDestroyed()
if IsActive and IsEnemy then
NPC:AddEntityRelationship( lvsVeh, D_HT, 25 )
NPC:UpdateEnemyMemory( lvsVeh, lvsVeh:GetPos() )
else
local D_, _ = NPC:Disposition( lvsVeh )
if D_ ~= D_NU then
NPC:AddEntityRelationship( lvsVeh, D_NU )
NPC:ClearEnemyMemory( lvsVeh )
end
end
end
end
function LVS:SetVehicleRelationship( lvsVeh )
local teamVeh = lvsVeh:GetAITEAM()
local Pos = lvsVeh:GetPos()
local IsActive = (lvsVeh:GetAI() or #lvsVeh:GetEveryone() > 0) and not lvsVeh:IsDestroyed()
for _, NPC in pairs( LVS:GetNPCs() ) do
local IsEnemy = ApplyTeamRules( teamVeh, lvsVeh:IsEnemy( NPC ) )
if IsActive and IsEnemy then
NPC:AddEntityRelationship( lvsVeh, D_HT, 25 )
NPC:UpdateEnemyMemory( lvsVeh, Pos )
else
local D_, _ = NPC:Disposition( lvsVeh )
if D_ ~= D_NU then
NPC:AddEntityRelationship( lvsVeh, D_NU )
NPC:ClearEnemyMemory( lvsVeh )
end
end
end
end
hook.Add( "LVS.UpdateRelationship", "!!!!lvsEntityRelationship", function( ent )
timer.Simple(0.1, function()
if not IsValid( ent ) then return end
if isfunction( ent.IsNPC ) and ent:IsNPC() then
LVS:SetNPCRelationship( ent )
else
LVS:SetVehicleRelationship( ent )
end
end)
end )

View File

@@ -0,0 +1,154 @@
hook.Add( "PlayerUse", "!!!LVS_FIX_RE_ENTER", function( ply, ent )
if ent.LVS and (ply._lvsNextUse or 0) > CurTime() then return false end
end )
hook.Add( "PlayerLeaveVehicle", "!!LVS_Exit", function( ply, Pod )
if not ply:IsPlayer() or not IsValid( Pod ) then return end
local Vehicle = Pod:lvsGetVehicle()
if not IsValid( Vehicle ) then return end
if not LVS.FreezeTeams then
ply:lvsSetAITeam( Vehicle:GetAITEAM() )
end
ply._lvsNextUse = CurTime() + 0.25
hook.Run( "LVS.UpdateRelationship", Vehicle )
local pos = Vehicle:LocalToWorld( Vehicle:OBBCenter() )
local vel = Vehicle:GetVelocity()
local radius = Vehicle:BoundingRadius()
local mins, maxs = ply:GetHull()
local PosCenter = Pod:OBBCenter()
local StartPos = Pod:LocalToWorld( PosCenter )
local FilterPlayer = { ply }
local Filter = table.Copy( Vehicle:GetCrosshairFilterEnts() )
table.insert( Filter, ply )
local zOffset = 15
local ValidPositions = {}
if isvector( Pod.ExitPos ) and Vehicle:GetUp().z > 0.9 then
local data = {
pos = Vehicle:LocalToWorld( Pod.ExitPos ),
dist = 1,
}
table.insert( ValidPositions, data )
end
local LocalDesiredExitPosition = Vehicle:WorldToLocal( Pod:GetPos() )
if vel:Length() > (Pod.PlaceBehindVelocity or 100) then
LocalDesiredExitPosition.y = LocalDesiredExitPosition.y - radius
local traceBehind = util.TraceLine( {
start = pos,
endpos = pos - vel:GetNormalized() * (radius + 50),
filter = Filter,
} )
local tracePlayer = util.TraceHull( {
start = traceBehind.HitPos + Vector(0,0,maxs.z + zOffset),
endpos = traceBehind.HitPos + Vector(0,0,zOffset),
maxs = Vector( maxs.x, maxs.y, 0 ),
mins = Vector( mins.x, mins.y, 0 ),
filter = FilterPlayer,
} )
if not tracePlayer.Hit and util.IsInWorld( tracePlayer.HitPos ) then
local data = {
pos = traceBehind.HitPos,
dist = 0,
}
table.insert( ValidPositions, data )
end
end
local DesiredExitPosition = Pod:LocalToWorld( LocalDesiredExitPosition )
for ang = 0, 360, 15 do
local X = math.cos( math.rad( ang ) ) * radius
local Y = math.sin( math.rad( ang ) ) * radius
local Z = Pod:OBBCenter().z
local EndPos = StartPos + Vector(X,Y,Z)
local traceWall = util.TraceLine( {start = StartPos,endpos = EndPos,filter = Filter} )
local traceVehicle = util.TraceLine( {
start = traceWall.HitPos,
endpos = StartPos,
filter = FilterPlayer,
} )
local CenterWallVehicle = (traceWall.HitPos + traceVehicle.HitPos) * 0.5
if traceWall.Hit or not util.IsInWorld( CenterWallVehicle ) then continue end
local GoundPos = CenterWallVehicle - Vector(0,0,radius)
local traceGround = util.TraceLine( {start = CenterWallVehicle,endpos = GoundPos,filter = Filter} )
if not traceGround.Hit or not util.IsInWorld( traceGround.HitPos ) then continue end
local tracePlayerRoof = util.TraceHull( {
start = traceGround.HitPos + Vector(0,0,zOffset),
endpos = traceGround.HitPos + Vector(0,0,maxs.z + zOffset),
maxs = Vector( maxs.x, maxs.y, 0 ),
mins = Vector( mins.x, mins.y, 0 ),
filter = FilterPlayer,
} )
if tracePlayerRoof.Hit or not util.IsInWorld( tracePlayerRoof.HitPos ) then continue end
local tracePlayer = util.TraceHull( {
start = traceGround.HitPos + Vector(0,0,maxs.z + zOffset),
endpos = traceGround.HitPos + Vector(0,0,zOffset),
maxs = Vector( maxs.x, maxs.y, 0 ),
mins = Vector( mins.x, mins.y, 0 ),
filter = FilterPlayer,
} )
if tracePlayer.Hit then continue end
local traceBack = util.TraceLine( {
start = tracePlayer.HitPos + Vector(0,0,zOffset),
endpos = StartPos,
filter = FilterPlayer,
} )
local data = {
pos = tracePlayer.HitPos,
dist = (traceBack.HitPos - DesiredExitPosition):Length(),
}
table.insert( ValidPositions, data )
end
local ExitPos
local ExitDist
for _, data in pairs( ValidPositions ) do
if not ExitPos or not ExitDist or ExitDist > data.dist then
ExitPos = data.pos
ExitDist = data.dist
end
end
-- all my plans failed, lets just let source do its thing
if not ExitPos then return end
local ViewAngles = (StartPos - ExitPos):Angle()
ViewAngles.p = 0
ViewAngles.r = 0
ply:SetPos( ExitPos )
ply:SetEyeAngles( ViewAngles )
end )

View File

@@ -0,0 +1,77 @@
hook.Add( "PlayerButtonDown", "!!!lvsSeatSwitcherButtonDown", function( ply, button )
local vehicle = ply:lvsGetVehicle()
if not IsValid( vehicle ) then return end
local CurPod = ply:GetVehicle()
if button == KEY_1 then
if ply == vehicle:GetDriver() then
if vehicle:GetlvsLockedStatus() then
vehicle:UnLock()
else
vehicle:Lock()
end
else
if IsValid( vehicle:GetDriver() ) then return end
if vehicle:GetAI() then
vehicle:SetAI( false )
vehicle:SetAIGunners( true )
end
if hook.Run( "LVS.CanPlayerDrive", ply, vehicle ) == false then
hook.Run( "LVS.OnPlayerCannotDrive", ply, vehicle )
return
end
ply:ExitVehicle()
local DriverSeat = vehicle:GetDriverSeat()
if not IsValid( DriverSeat ) then return end
if hook.Run( "LVS.OnPlayerRequestSeatSwitch", ply, vehicle, CurPod, DriverSeat ) == false then return end
timer.Simple( 0, function()
if not IsValid( vehicle ) or not IsValid( ply ) then return end
if IsValid( vehicle:GetDriver() ) or not IsValid( DriverSeat ) or vehicle:GetAI() then return end
ply:EnterVehicle( DriverSeat )
vehicle:AlignView( ply )
vehicle:OnSwitchSeat( ply, CurPod, DriverSeat )
end)
end
else
for _, Pod in pairs( vehicle:GetPassengerSeats() ) do
if not IsValid( Pod ) or Pod:GetNWInt( "pPodIndex", 3 ) ~= LVS.pSwitchKeys[ button ] then continue end
local Driver = Pod:GetDriver()
if IsValid( Driver ) then
if Driver == ply then
for _, DoorHandler in ipairs( vehicle:GetDoorHandlers() ) do
if DoorHandler:GetLinkedSeat() ~= Pod or not DoorHandler:IsOpen() then continue end
DoorHandler:Close( ply )
end
end
continue
end
if hook.Run( "LVS.OnPlayerRequestSeatSwitch", ply, vehicle, CurPod, Pod ) == false then continue end
ply:ExitVehicle()
timer.Simple( 0, function()
if not IsValid( Pod ) or not IsValid( ply ) then return end
if IsValid( Pod:GetDriver() ) then return end
ply:EnterVehicle( Pod )
vehicle:AlignView( ply, true )
vehicle:OnSwitchSeat( ply, CurPod, Pod )
end)
end
end
end )

View File

@@ -0,0 +1,240 @@
local StartTime = SysTime()
if SERVER then
AddCSLuaFile("includes/circles/circles.lua")
end
local function FileIsEmpty( filename )
if file.Size( filename, "LUA" ) <= 1 then -- this is suspicous
local data = file.Read( filename, "LUA" )
if data and string.len( data ) <= 1 then -- confirm its empty
print("[LVS] - refusing to load '"..filename.."'! File is Empty!" )
return true
end
end
return false
end
for _, filename in pairs( file.Find("lvs_framework/autorun/*.lua", "LUA") ) do
if FileIsEmpty( "lvs_framework/autorun/"..filename ) then continue end
if string.StartWith( filename, "sv_") then -- sv_ prefix only load serverside
if SERVER then
include("lvs_framework/autorun/"..filename)
end
continue
end
if string.StartWith( filename, "cl_") then -- cl_ prefix only load clientside
if SERVER then
AddCSLuaFile("lvs_framework/autorun/"..filename)
else
include("lvs_framework/autorun/"..filename)
end
continue
end
-- everything else is shared
if SERVER then
AddCSLuaFile("lvs_framework/autorun/"..filename)
end
include("lvs_framework/autorun/"..filename)
end
hook.Run( "LVS:Initialize" )
print("[LVS] - initialized ["..math.Round((SysTime() - StartTime) * 1000,2).."ms]")
if CLIENT then
hook.Add( "InitPostEntity", "!!!lvscheckupdates", function()
timer.Simple(20, function()
LVS.CheckUpdates()
local convar = GetConVar( "no_error_hitboxes" )
if not convar then return end
convar:SetBool( false )
end)
end )
return
end
resource.AddWorkshop("2912816023")
local ValveWierdBlastDamageClass = {
["npc_strider"] = true, -- takes 70 damage for each blast damage as constant value ...
["npc_combinegunship"] = true, -- takes 44 damage as constant value ...
["func_breakable_surf"] = true, -- this entity dont care about anything that isnt a trace attack or blast damage
}
function LVS:BlastDamage( pos, forward, attacker, inflictor, damage, damagetype, radius, force )
local dmginfo = DamageInfo()
dmginfo:SetAttacker( attacker )
dmginfo:SetInflictor( inflictor )
dmginfo:SetDamage( damage )
dmginfo:SetDamageType( damagetype == DMG_BLAST and DMG_SONIC or damagetype )
if damagetype ~= DMG_BLAST then
dmginfo:SetDamagePosition( pos )
dmginfo:SetDamageForce( forward * force )
util.BlastDamageInfo( dmginfo, pos, radius )
return
end
util.BlastDamageInfo( dmginfo, pos, radius )
local FragmentAngle = 10
local NumFragments = 16
local NumFragmentsMissed = 0
local RegisteredHits = {}
local trace = util.TraceLine( {
start = pos,
endpos = pos - forward * radius,
filter = { attacker, inflictor },
} )
local startpos = trace.HitPos
for i = 1, NumFragments do
local ang = forward:Angle() + Angle( math.random(-FragmentAngle,FragmentAngle), math.random(-FragmentAngle,FragmentAngle), 0 )
local dir = ang:Forward()
local endpos = pos + dir * radius
local trace = util.TraceLine( {
start = startpos,
endpos = endpos,
filter = { attacker, inflictor },
} )
debugoverlay.Line( startpos, trace.HitPos, 10, Color( 255, 0, 0, 255 ), true )
if not trace.Hit then
NumFragmentsMissed = NumFragmentsMissed + 1
continue
end
if not IsValid( trace.Entity ) then continue end
if not RegisteredHits[ trace.Entity ] then
RegisteredHits[ trace.Entity ] = {}
end
table.insert( RegisteredHits[ trace.Entity ], {
origin = trace.HitPos,
force = forward * force,
} )
end
local Hull = Vector(10,10,10)
for _, ent in ipairs( ents.FindInSphere( pos, radius ) ) do
if not ent.LVS or ent == inflictor or ent == attacker then continue end
local trace = util.TraceHull( {
start = pos,
endpos = ent:LocalToWorld( ent:OBBCenter() ),
mins = -Hull,
maxs = Hull,
whitelist = true,
ignoreworld = true,
filter = ent,
} )
debugoverlay.Line( pos, trace.HitPos, 10, Color( 255, 0, 0, 255 ), true )
NumFragments = NumFragments + 1
if not RegisteredHits[ ent ] then
RegisteredHits[ ent ] = {}
end
table.insert( RegisteredHits[ ent ], {
origin = trace.HitPos,
force = forward * force,
} )
end
if NumFragmentsMissed == NumFragments then return end
local DamageBoost = NumFragments / ( NumFragments - NumFragmentsMissed )
for ent, data in pairs( RegisteredHits ) do
local NumHits = #data
local AverageOrigin = vector_origin
local AverageForce = vector_origin
for _, HitData in pairs( data ) do
AverageOrigin = AverageOrigin + HitData.origin
AverageForce = AverageForce + HitData.force
end
AverageOrigin = AverageOrigin / NumHits
AverageForce = AverageForce / NumHits
local TotalDamage = ( ( NumHits * DamageBoost ) / NumFragments ) * damage
--debugoverlay.Cross( AverageOrigin, 50, 10, Color( 255, 0, 255 ) )
-- hack
if ValveWierdBlastDamageClass[ ent:GetClass() ] then
util.BlastDamage( inflictor, attacker, pos, radius, damage )
continue
end
local dmginfo = DamageInfo()
dmginfo:SetAttacker( attacker )
dmginfo:SetInflictor( inflictor )
dmginfo:SetDamage( TotalDamage )
dmginfo:SetDamageForce( AverageForce )
dmginfo:SetDamagePosition( AverageOrigin )
dmginfo:SetDamageType( DMG_BLAST )
ent:TakeDamageInfo( dmginfo )
end
end
function LVS:FixVelocity()
local tbl = physenv.GetPerformanceSettings()
if tbl.MaxVelocity < 4000 then
local OldVel = tbl.MaxVelocity
tbl.MaxVelocity = 4000
physenv.SetPerformanceSettings(tbl)
print("[LVS] Low MaxVelocity detected! Increasing! "..OldVel.." => 4000")
end
if tbl.MaxAngularVelocity < 7272 then
local OldAngVel = tbl.MaxAngularVelocity
tbl.MaxAngularVelocity = 7272
physenv.SetPerformanceSettings(tbl)
print("[LVS] Low MaxAngularVelocity detected! Increasing! "..OldAngVel.." => 7272")
end
end
hook.Add( "InitPostEntity", "!!!lvscheckupdates", function()
timer.Simple(20, function()
LVS.CheckUpdates()
end)
end )