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,75 @@
include("shared.lua")
function ENT:Think()
end
function ENT:OnRemove()
end
function ENT:Draw()
end
function ENT:DrawTranslucent()
end
function ENT:GetAimVector()
if self:GetAI() then
return self:GetNWAimVector()
end
local Driver = self:GetDriver()
if IsValid( Driver ) then
if self._AimVectorUnlocked then
local pod = self:GetDriverSeat()
if IsValid( pod ) then
return pod:WorldToLocalAngles( Driver:EyeAngles() ):Forward()
end
end
return Driver:GetAimVector()
else
return self:GetForward()
end
end
function ENT:LVSPaintHitMarker( scr )
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
Base:LVSPaintHitMarker( scr )
end
function ENT:LVSDrawCircle( X, Y, target_radius, value )
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
Base:LVSDrawCircle( X, Y, target_radius, value )
end
function ENT:PaintCrosshairCenter( Pos2D, Col )
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
Base:PaintCrosshairCenter( Pos2D, Col )
end
function ENT:PaintCrosshairOuter( Pos2D, Col )
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
Base:PaintCrosshairOuter( Pos2D, Col )
end
function ENT:PaintCrosshairSquare( Pos2D, Col )
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
Base:PaintCrosshairSquare( Pos2D, Col )
end

View File

@@ -0,0 +1,327 @@
AddCSLuaFile( "shared.lua" )
AddCSLuaFile( "cl_init.lua" )
include("shared.lua")
include("sv_ai.lua")
function ENT:Initialize()
self:SetMoveType( MOVETYPE_NONE )
self:SetSolid( SOLID_NONE )
self:DrawShadow( false )
end
function ENT:Think()
self:HandleActive()
self:WeaponsThink()
if self:GetAI() then
self:RunAI()
end
self:NextThink( CurTime() )
return true
end
function ENT:HandleActive()
local Pod = self:GetDriverSeat()
if not IsValid( Pod ) then
return
end
local Driver = Pod:GetDriver()
if Driver ~= self:GetDriver() then
local NewDriver = Driver
local OldDriver = self:GetDriver()
self:SetDriver( Driver )
local Base = self:GetVehicle()
if IsValid( Base ) then
Base:OnPassengerChanged( OldDriver, NewDriver, Pod:GetNWInt( "pPodIndex", -1 ) )
end
if IsValid( Driver ) then
Driver:lvsBuildControls()
else
self:WeaponsFinish()
end
end
end
function ENT:OnRemove()
end
function ENT:UpdateTransmitState()
return TRANSMIT_ALWAYS
end
function ENT:WeaponsFinish()
if not self._activeWeapon then return end
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
local CurWeapon = Base.WEAPONS[ self:GetPodIndex() ][ self._activeWeapon ]
if not CurWeapon then return end
if CurWeapon.FinishAttack then
CurWeapon.FinishAttack( self )
end
self._activeWeapon = nil
self.OldAttack = false
end
function ENT:GetAmmo()
if self:GetAI() then return self:GetMaxAmmo() end
local CurWeapon = self:GetActiveWeapon()
if not CurWeapon then return -1 end
return CurWeapon._CurAmmo or self:GetMaxAmmo()
end
function ENT:TakeAmmo( num )
if self:GetMaxAmmo() <= 0 then return end
local CurWeapon = self:GetActiveWeapon()
CurWeapon._CurAmmo = math.max( self:GetAmmo() - (num or 1), 0 )
self:SetNWAmmo( CurWeapon._CurAmmo )
end
function ENT:GetHeat( weaponid )
local CurWeapon
if isnumber( weaponid ) and weaponid > 0 then
local Base = self:GetVehicle()
if IsValid( Base ) then
CurWeapon = Base.WEAPONS[ self:GetPodIndex() ][ weaponid ]
else
CurWeapon = self:GetActiveWeapon()
end
else
CurWeapon = self:GetActiveWeapon()
end
if not CurWeapon then return 0 end
return (CurWeapon._CurHeat or 0)
end
function ENT:GetOverheated()
local CurWeapon = self:GetActiveWeapon()
if not CurWeapon then return false end
return CurWeapon.Overheated == true
end
function ENT:SetOverheated( overheat )
if self:GetOverheated() == overheat then return end
local CurWeapon = self:GetActiveWeapon()
if not CurWeapon then return end
CurWeapon.Overheated = overheat
self:SetNWOverheated( overheat )
if self:GetHeat() == 0 then return end
if CurWeapon.OnOverheat then
CurWeapon.OnOverheat( self )
end
end
function ENT:SetHeat( heat )
local CurWeapon = self:GetActiveWeapon()
if not CurWeapon then return end
heat = math.Clamp( heat, 0, 1 )
CurWeapon._CurHeat = heat
if self:GetNWHeat() == heat then return end
self:SetNWHeat( heat )
end
function ENT:CanAttack()
local CurWeapon = self:GetActiveWeapon()
return (CurWeapon._NextFire or 0) < CurTime()
end
function ENT:SetNextAttack( time )
local CurWeapon = self:GetActiveWeapon()
CurWeapon._NextFire = time
end
function ENT:WeaponsShouldFire()
if self:GetAI() then return self._AIFireInput end
local ply = self:GetDriver()
if not IsValid( ply ) then return false end
return ply:lvsKeyDown( "ATTACK" )
end
function ENT:WeaponsThink()
local T = CurTime()
local FT = FrameTime()
local CurWeapon, SelectedID = self:GetActiveWeapon()
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
for ID, Weapon in pairs( Base.WEAPONS[ self:GetPodIndex() ] ) do
local IsActive = ID == SelectedID
if Weapon.OnThink then Weapon.OnThink( self, IsActive ) end
if IsActive then continue end
if Weapon.HeatIsClip and not Weapon.Overheated and Weapon._CurHeat ~= 0 then
Weapon.Overheated = true
Weapon._CurHeat = 1
if Weapon.OnReload then Weapon.OnReload( self ) end
end
-- cool all inactive weapons down
Weapon._CurHeat = Weapon._CurHeat and Weapon._CurHeat - math.min( Weapon._CurHeat, (Weapon.HeatRateDown or 0.25) * FT ) or 0
end
if not CurWeapon then return end
local ShouldFire = self:WeaponsShouldFire()
local CurHeat = self:GetHeat()
if self:GetOverheated() then
if CurHeat <= 0 then
self:SetOverheated( false )
else
ShouldFire = false
end
else
if CurHeat >= 1 then
self:SetOverheated( true )
ShouldFire = false
if CurWeapon.OnReload then CurWeapon.OnReload( self ) end
end
end
if self:GetMaxAmmo() > 0 then
if self:GetAmmo() <= 0 then
ShouldFire = false
end
end
if ShouldFire ~= self.OldAttack then
self.OldAttack = ShouldFire
if ShouldFire then
if CurWeapon.StartAttack then
CurWeapon.StartAttack( self )
end
self._activeWeapon = SelectedID
else
self:WeaponsFinish()
end
end
if ShouldFire then
if not self:CanAttack() then return end
local ShootDelay = (CurWeapon.Delay or 0)
self:SetNextAttack( T + ShootDelay )
self:SetHeat( CurHeat + (CurWeapon.HeatRateUp or 0.2) * math.max(ShootDelay, FT) )
if not CurWeapon.Attack then return end
if CurWeapon.Attack( self ) then
self:SetHeat( CurHeat - math.min( self:GetHeat(), (CurWeapon.HeatRateDown or 0.25) * FT ) )
self:SetNextAttack( T )
end
self._lvsNextActiveWeaponCoolDown = T + 0.25
else
if (self._lvsNextActiveWeaponCoolDown or 0) > T then return end
if CurWeapon.HeatIsClip and not CurWeapon.Overheated then
self:SetHeat( self:GetHeat() )
return
end
self:SetHeat( self:GetHeat() - math.min( self:GetHeat(), (CurWeapon.HeatRateDown or 0.25) * FT ) )
end
end
function ENT:SelectWeapon( ID )
if not isnumber( ID ) then return end
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
if Base.WEAPONS[ self:GetPodIndex() ][ ID ] then
self:SetSelectedWeapon( ID )
end
local ply = self:GetDriver()
if not IsValid( ply ) then return end
net.Start( "lvs_select_weapon" )
net.Send( ply )
end
function ENT:OnWeaponChanged( name, old, new)
if new == old then return end
self:WeaponsFinish()
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
local PrevWeapon = Base.WEAPONS[ self:GetPodIndex() ][ old ]
if PrevWeapon and PrevWeapon.OnDeselect then
PrevWeapon.OnDeselect( self )
end
local NextWeapon = Base.WEAPONS[ self:GetPodIndex() ][ new ]
if NextWeapon and NextWeapon.OnSelect then
NextWeapon.OnSelect( self )
self:SetNWAmmo( NextWeapon._CurAmmo or NextWeapon.Ammo or -1 )
self:SetNWOverheated( NextWeapon.Overheated == true )
end
end
function ENT:LVSFireBullet( data )
local Base = self:GetVehicle()
if not IsValid( Base ) then return end
data.Entity = Base
data.Velocity = data.Velocity + self:GetVelocity():Length()
data.SrcEntity = Base:WorldToLocal( data.Src )
LVS:FireBullet( data )
end

View File

@@ -0,0 +1,174 @@
ENT.Type = "anim"
ENT.PrintName = "LBaseGunner"
ENT.Author = "Luna"
ENT.Information = "Luna's Vehicle Script"
ENT.Category = "[LVS]"
ENT.Spawnable = false
ENT.AdminSpawnable = false
ENT.DoNotDuplicate = true
ENT.LVS_GUNNER = true
ENT.VectorNull = Vector(0,0,0)
function ENT:SetupDataTables()
self:NetworkVar( "Entity",0, "Driver" )
self:NetworkVar( "Entity",1, "DriverSeat" )
self:NetworkVar( "Int", 0, "PodIndex")
self:NetworkVar( "Int", 1, "NWAmmo")
self:NetworkVar( "Int", 2, "SelectedWeapon" )
self:NetworkVar( "Float", 0, "NWHeat" )
self:NetworkVar( "Bool", 0, "NWOverheated" )
self:NetworkVar( "Vector", 0, "NWAimVector" )
if SERVER then
self:NetworkVarNotify( "SelectedWeapon", self.OnWeaponChanged )
end
end
function ENT:UnlockAimVector()
self._AimVectorUnlocked = true
end
function ENT:LockAimVector()
self._AimVectorUnlocked = nil
end
function ENT:GetEyeTrace()
local startpos = self:GetPos()
local trace = util.TraceLine( {
start = startpos,
endpos = (startpos + self:GetAimVector() * 50000),
filter = self:GetCrosshairFilterEnts()
} )
return trace
end
function ENT:GetAI()
if IsValid( self:GetDriver() ) then return false end
local veh = self:GetVehicle()
if not IsValid( veh ) then return false end
return veh:GetAIGunners()
end
function ENT:GetAITEAM()
local Base = self:GetVehicle()
if not IsValid( Base ) then return 0 end
return Base:GetAITEAM()
end
function ENT:GetVehicle()
local Pod = self:GetParent()
if not IsValid( Pod ) then return NULL end
return Pod:GetParent()
end
function ENT:HasWeapon( ID )
local Base = self:GetVehicle()
if not IsValid( Base ) then return false end
return istable( Base.WEAPONS[ self:GetPodIndex() ][ ID ] )
end
function ENT:AIHasWeapon( ID )
local Base = self:GetVehicle()
if not IsValid( Base ) then return false end
local weapon = Base.WEAPONS[ self:GetPodIndex() ][ ID ]
if not istable( weapon ) then return false end
return weapon.UseableByAI
end
function ENT:GetActiveWeapon()
local SelectedID = self:GetSelectedWeapon()
local Base = self:GetVehicle()
if not IsValid( Base ) then return {}, SelectedID end
local CurWeapon = Base.WEAPONS[ self:GetPodIndex() ][ SelectedID ]
return CurWeapon, SelectedID
end
function ENT:GetMaxAmmo()
local CurWeapon = self:GetActiveWeapon()
if not CurWeapon then return -1 end
return CurWeapon.Ammo or -1
end
function ENT:GetClip()
local CurWeapon = self:GetActiveWeapon()
if not CurWeapon then return 0 end
local HeatIncrement = (CurWeapon.HeatRateUp or 0.2) * math.max(CurWeapon.Delay or 0, FrameTime())
local Ammo = self:GetNWAmmo()
if self:GetMaxAmmo() <= 0 and CurWeapon.Clip then
Ammo = CurWeapon.Clip
end
return math.min( math.ceil( math.Round( (1 - self:GetNWHeat()) / HeatIncrement, 1 ) ), Ammo )
end
function ENT:GetCrosshairFilterEnts()
local Base = self:GetVehicle()
if not IsValid( Base ) then return {} end
return Base:GetCrosshairFilterEnts()
end
function ENT:Sign( n )
if n > 0 then return 1 end
if n < 0 then return -1 end
return 0
end
function ENT:VectorSubtractNormal( Normal, Velocity )
local VelForward = Velocity:GetNormalized()
local Ax = math.acos( math.Clamp( Normal:Dot( VelForward ) ,-1,1) )
local Fx = math.cos( Ax ) * Velocity:Length()
local NewVelocity = Velocity - Normal * math.abs( Fx )
return NewVelocity
end
function ENT:VectorSplitNormal( Normal, Velocity )
return math.cos( math.acos( math.Clamp( Normal:Dot( Velocity:GetNormalized() ) ,-1,1) ) ) * Velocity:Length()
end
function ENT:AngleBetweenNormal( Dir1, Dir2 )
return math.deg( math.acos( math.Clamp( Dir1:Dot( Dir2 ) ,-1,1) ) )
end
function ENT:GetVehicleType()
return "LBaseGunner"
end

View File

@@ -0,0 +1,98 @@
function ENT:GetAimVector()
if self:GetAI() then
local Dir = self._ai_look_dir or self.VectorNull
self:SetNWAimVector( Dir )
return Dir
end
local Driver = self:GetDriver()
if IsValid( Driver ) then
if self._AimVectorUnlocked then
local pod = self:GetDriverSeat()
if IsValid( pod ) then
return pod:WorldToLocalAngles( Driver:EyeAngles() ):Forward()
end
end
return Driver:GetAimVector()
else
return self:GetForward()
end
end
function ENT:RunAI()
local EntTable = self:GetTable()
local Target = self:AIGetTarget( EntTable )
if not IsValid( Target ) then
EntTable._ai_look_dir = self:GetForward()
EntTable._AIFireInput = false
return
end
local TargetPos = Target:GetPos()
if EntTable._AIFireInput then
local T = CurTime() * 0.5 + self:EntIndex()
local X = math.cos( T ) * 32
local Y = math.sin( T ) * 32
local Z = math.sin( math.cos( T / 0.5 ) * math.pi ) * 32
TargetPos = Target:LocalToWorld( Target:OBBCenter() + Vector(X,Y,Z) )
end
EntTable._ai_look_dir = (TargetPos - self:GetPos()):GetNormalized()
local StartPos = self:GetPos()
local trace = util.TraceHull( {
start = StartPos,
endpos = (StartPos + EntTable._ai_look_dir * 50000),
mins = Vector( -50, -50, -50 ),
maxs = Vector( 50, 50, 50 ),
filter = self:GetCrosshairFilterEnts()
} )
if not self:AIHasWeapon( self:GetSelectedWeapon() ) then
EntTable._AIFireInput = false
return
end
if IsValid( trace.Entity ) and trace.Entity.GetAITEAM then
EntTable._AIFireInput = (trace.Entity:GetAITEAM() ~= self:GetAITEAM() or trace.Entity:GetAITEAM() == 0)
else
EntTable._AIFireInput = true
end
end
function ENT:AIGetTarget( EntTable )
local Base = self:GetVehicle()
if not IsValid( Base ) then return NULL end
if Base:GetAI() then
return Base:AIGetTarget()
end
if not isnumber( EntTable.ViewConeAdd ) then
EntTable.ViewConeAdd = math.min( 100 + math.abs( Base:WorldToLocalAngles( self:GetAngles() ).y ), 360 )
end
return Base:AIGetTarget( EntTable.ViewConeAdd )
end
function ENT:AITargetInFront( ent, range )
local Base = self:GetVehicle()
if not IsValid( Base ) then return NULL end
return Base:AITargetInFront( ent, range )
end