mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
305 lines
6.2 KiB
Lua
305 lines
6.2 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
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()
|
|
local CurWeapon = self:GetActiveWeapon()
|
|
|
|
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
|
|
|
|
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
|
|
|
|
-- 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
|
|
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
|
|
else
|
|
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 )
|
|
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
|