add sborka
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
|
||||
ENT._lvsSmoothFreeLook = 0
|
||||
|
||||
function ENT:CalcViewDirectInput( ply, pos, angles, fov, pod )
|
||||
local ViewPosL = pod:WorldToLocal( pos )
|
||||
|
||||
local view = {}
|
||||
view.fov = fov
|
||||
view.drawviewer = true
|
||||
view.angles = self:GetAngles()
|
||||
|
||||
local FreeLook = ply:lvsKeyDown( "FREELOOK" )
|
||||
local Zoom = ply:lvsKeyDown( "ZOOM" )
|
||||
|
||||
if not pod:GetThirdPersonMode() then
|
||||
|
||||
if FreeLook then
|
||||
view.angles = pod:LocalToWorldAngles( ply:EyeAngles() )
|
||||
end
|
||||
|
||||
local velL = self:WorldToLocal( self:GetPos() + self:GetVelocity() )
|
||||
|
||||
local Dividor = math.abs( velL.x )
|
||||
local SideForce = math.Clamp( velL.y / Dividor, -1, 1)
|
||||
local UpForce = math.Clamp( velL.z / Dividor, -1, 1)
|
||||
|
||||
local ViewPunch = Vector(0,math.Clamp(SideForce * 10,-1,1),math.Clamp(UpForce * 10,-1,1))
|
||||
if Zoom then
|
||||
ViewPunch = Vector(0,0,0)
|
||||
end
|
||||
|
||||
pod._lerpPosOffset = pod._lerpPosOffset and pod._lerpPosOffset + (ViewPunch - pod._lerpPosOffset) * RealFrameTime() * 5 or Vector(0,0,0)
|
||||
pod._lerpPos = pos
|
||||
|
||||
view.origin = pos + pod:GetForward() * -pod._lerpPosOffset.y * 0.5 + pod:GetUp() * pod._lerpPosOffset.z * 0.5
|
||||
view.angles.p = view.angles.p - pod._lerpPosOffset.z * 0.1
|
||||
view.angles.y = view.angles.y + pod._lerpPosOffset.y * 0.1
|
||||
view.drawviewer = false
|
||||
|
||||
return view
|
||||
end
|
||||
|
||||
pod._lerpPos = pod._lerpPos or self:GetPos()
|
||||
|
||||
local radius = 550
|
||||
radius = radius + radius * pod:GetCameraDistance()
|
||||
|
||||
if FreeLook then
|
||||
local velL = self:WorldToLocal( self:GetPos() + self:GetVelocity() )
|
||||
|
||||
local SideForce = math.Clamp(velL.y / 10,-250,250)
|
||||
local UpForce = math.Clamp(velL.z / 10,-250,250)
|
||||
|
||||
pod._lerpPosL = pod._lerpPosL and (pod._lerpPosL + (Vector(radius, SideForce,150 + radius * 0.1 + radius * pod:GetCameraHeight() + UpForce) - pod._lerpPosL) * RealFrameTime() * 12) or Vector(0,0,0)
|
||||
pod._lerpPos = self:LocalToWorld( pod._lerpPosL )
|
||||
|
||||
view.origin = pod._lerpPos
|
||||
view.angles = self:LocalToWorldAngles( Angle(0,180,0) )
|
||||
else
|
||||
local TargetPos = self:LocalToWorld( Vector(500,0,150 + radius * 0.1 + radius * pod:GetCameraHeight()) )
|
||||
|
||||
local Sub = TargetPos - pod._lerpPos
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Dist = Sub:Length()
|
||||
|
||||
local DesiredPos = TargetPos - self:GetForward() * (300 + radius) - Dir * 100
|
||||
|
||||
pod._lerpPos = pod._lerpPos + (DesiredPos - pod._lerpPos) * RealFrameTime() * (Zoom and 30 or 12)
|
||||
pod._lerpPosL = self:WorldToLocal( pod._lerpPos )
|
||||
|
||||
local vel = self:GetVelocity()
|
||||
|
||||
view.origin = pod._lerpPos
|
||||
view.angles = self:GetAngles()
|
||||
end
|
||||
|
||||
view.origin = view.origin + ViewPosL
|
||||
|
||||
return view
|
||||
end
|
||||
|
||||
function ENT:CalcViewMouseAim( ply, pos, angles, fov, pod )
|
||||
local cvarFocus = math.Clamp( LVS.cvarCamFocus:GetFloat() , -1, 1 )
|
||||
|
||||
self._lvsSmoothFreeLook = self._lvsSmoothFreeLook + ((ply:lvsKeyDown( "FREELOOK" ) and 0 or 1) - self._lvsSmoothFreeLook) * RealFrameTime() * 10
|
||||
|
||||
local view = {}
|
||||
view.origin = pos
|
||||
view.fov = fov
|
||||
view.drawviewer = true
|
||||
view.angles = (self:GetForward() * (1 + cvarFocus) * self._lvsSmoothFreeLook * 0.8 + ply:EyeAngles():Forward() * math.max(1 - cvarFocus, 1 - self._lvsSmoothFreeLook)):Angle()
|
||||
|
||||
if cvarFocus >= 1 then
|
||||
view.angles = LerpAngle( self._lvsSmoothFreeLook, ply:EyeAngles(), self:GetAngles() )
|
||||
else
|
||||
view.angles.r = 0
|
||||
end
|
||||
|
||||
if not pod:GetThirdPersonMode() then
|
||||
|
||||
view.drawviewer = false
|
||||
|
||||
return view
|
||||
end
|
||||
|
||||
local radius = 550
|
||||
radius = radius + radius * pod:GetCameraDistance()
|
||||
|
||||
local TargetOrigin = view.origin - view.angles:Forward() * radius + view.angles:Up() * (radius * 0.2 + 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
|
||||
|
||||
if tr.Hit and not tr.StartSolid then
|
||||
view.origin = view.origin + tr.HitNormal * WallOffset
|
||||
end
|
||||
|
||||
return view
|
||||
end
|
||||
|
||||
function ENT:CalcViewOverride( ply, pos, angles, fov, pod )
|
||||
return pos, angles, fov
|
||||
end
|
||||
|
||||
function ENT:CalcViewDriver( ply, pos, angles, fov, pod )
|
||||
if ply:lvsMouseAim() then
|
||||
return self:CalcViewMouseAim( ply, pos, angles, fov, pod )
|
||||
else
|
||||
return self:CalcViewDirectInput( ply, pos, angles, fov, pod )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CalcViewPassenger( ply, pos, angles, fov, pod )
|
||||
return LVS:CalcView( self, ply, pos, angles, fov, pod )
|
||||
end
|
||||
|
||||
function ENT:LVSCalcView( ply, original_pos, original_angles, original_fov, pod )
|
||||
local pos, angles, fov = self:CalcViewOverride( ply, original_pos, original_angles, original_fov, pod )
|
||||
|
||||
if self:GetDriverSeat() == pod then
|
||||
return self:CalcViewDriver( ply, pos, angles, fov, pod )
|
||||
else
|
||||
return self:CalcViewPassenger( ply, pos, angles, fov, pod )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
function ENT:OnDestroyed()
|
||||
if not self.DeathSound then return end
|
||||
|
||||
if self:GetVelocity():Length() <= self.MaxVelocity * 0.5 then return end
|
||||
|
||||
self._sndDeath = CreateSound( self, self.DeathSound )
|
||||
self._sndDeath:SetSoundLevel( 125 )
|
||||
self._sndDeath:PlayEx( 1, 50 + 50 * self:CalcDoppler( LocalPlayer() ) )
|
||||
end
|
||||
|
||||
function ENT:StopDeathSound()
|
||||
if not self._sndDeath then return end
|
||||
|
||||
self._sndDeath:Stop()
|
||||
end
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
ENT.FlyByAdvance = 0
|
||||
|
||||
function ENT:FlyByThink()
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if ply:lvsGetVehicle() == self then self.OldApproaching = false return end
|
||||
|
||||
local ViewEnt = ply:GetViewEntity()
|
||||
|
||||
if not IsValid( ViewEnt ) then return end
|
||||
|
||||
local Time = CurTime()
|
||||
|
||||
if (EntTable._nextflyby or 0) > Time then return end
|
||||
|
||||
EntTable._nextflyby = Time + 0.1
|
||||
|
||||
local Vel = self:GetVelocity()
|
||||
|
||||
if self:GetThrottle() <= 0.75 or Vel:Length() <= EntTable.MaxVelocity * 0.75 then return end
|
||||
|
||||
local Sub = ViewEnt:GetPos() - self:GetPos() - Vel * EntTable.FlyByAdvance
|
||||
local ToPlayer = Sub:GetNormalized()
|
||||
local VelDir = Vel:GetNormalized()
|
||||
|
||||
local ApproachAngle = math.deg( math.acos( math.Clamp( ToPlayer:Dot( VelDir ) ,-1,1) ) )
|
||||
|
||||
local Approaching = ApproachAngle < 80
|
||||
|
||||
if Approaching ~= EntTable.OldApproaching then
|
||||
EntTable.OldApproaching = Approaching
|
||||
|
||||
if Approaching then
|
||||
self:StopFlyBy()
|
||||
else
|
||||
self:OnFlyBy( 60 + 80 * math.min(ApproachAngle / 140,1) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnFlyBy( Pitch )
|
||||
if not self.FlyBySound then return end
|
||||
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
EntTable.flybysnd = CreateSound( self, EntTable.FlyBySound )
|
||||
EntTable.flybysnd:SetSoundLevel( 95 )
|
||||
EntTable.flybysnd:PlayEx( 1, Pitch )
|
||||
end
|
||||
|
||||
function ENT:StopFlyBy()
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if not EntTable.flybysnd then return end
|
||||
|
||||
EntTable.flybysnd:Stop()
|
||||
EntTable.flybysnd = nil
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
ENT.IconEngine = Material( "lvs/engine.png" )
|
||||
|
||||
function ENT:LVSHudPaintInfoText( X, Y, W, H, ScrX, ScrY, ply )
|
||||
local speed = math.Round( LVS:GetUnitValue( self:GetVelocity():Length() ) ,0)
|
||||
draw.DrawText( LVS:GetUnitName().." ", "LVS_FONT", X + 72, Y + 35, color_white, TEXT_ALIGN_RIGHT )
|
||||
draw.DrawText( speed, "LVS_FONT_HUD_LARGE", X + 72, Y + 20, color_white, TEXT_ALIGN_LEFT )
|
||||
|
||||
if ply ~= self:GetDriver() then return end
|
||||
|
||||
local Throttle = self:GetThrottle()
|
||||
local Col = Throttle <= 1 and color_white or Color(0,0,0,255)
|
||||
local hX = X + W - H * 0.5
|
||||
local hY = Y + H * 0.25 + H * 0.25
|
||||
|
||||
surface.SetMaterial( self.IconEngine )
|
||||
surface.SetDrawColor( 0, 0, 0, 200 )
|
||||
surface.DrawTexturedRectRotated( hX + 4, hY + 1, H * 0.5, H * 0.5, 0 )
|
||||
surface.SetDrawColor( color_white )
|
||||
surface.DrawTexturedRectRotated( hX + 2, hY - 1, H * 0.5, H * 0.5, 0 )
|
||||
|
||||
if not self:GetEngineActive() then
|
||||
draw.SimpleText( "X" , "LVS_FONT", hX, hY, Color(0,0,0,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
||||
end
|
||||
|
||||
self:LVSDrawCircle( hX, hY, H * 0.35, math.min( Throttle, 1 ) )
|
||||
|
||||
if Throttle > 1 then
|
||||
draw.SimpleText( "+"..math.Round((Throttle - 1) * 100,0).."%" , "LVS_FONT", hX, hY, Col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:LVSPreHudPaint( X, Y, ply )
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:LVSHudPaint( X, Y, ply )
|
||||
if not self:LVSPreHudPaint( X, Y, ply ) then return end
|
||||
|
||||
if ply ~= self:GetDriver() then return end
|
||||
|
||||
local HitPlane = self:GetEyeTrace( true ).HitPos:ToScreen()
|
||||
local HitPilot = self:GetEyeTrace().HitPos:ToScreen()
|
||||
|
||||
self:PaintCrosshairCenter( HitPlane )
|
||||
self:PaintCrosshairOuter( HitPilot )
|
||||
|
||||
if ply:lvsMouseAim() and not ply:lvsKeyDown( "FREELOOK" ) then
|
||||
self:LVSHudPaintMouseAim( HitPlane, HitPilot )
|
||||
end
|
||||
|
||||
self:LVSPaintHitMarker( HitPilot )
|
||||
end
|
||||
|
||||
function ENT:LVSHudPaintDirectInput( Pos2D )
|
||||
self:PaintCrosshairCenter( Pos2D )
|
||||
self:PaintCrosshairOuter( Pos2D )
|
||||
end
|
||||
|
||||
function ENT:LVSHudPaintMouseAim( HitPlane, HitPilot )
|
||||
local Sub = Vector(HitPilot.x,HitPilot.y,0) - Vector(HitPlane.x,HitPlane.y,0)
|
||||
local Len = Sub:Length()
|
||||
local Dir = Sub:GetNormalized()
|
||||
|
||||
surface.SetDrawColor( 255, 255, 255, 100 )
|
||||
if Len > 20 then
|
||||
surface.DrawLine( HitPlane.x + Dir.x * 5, HitPlane.y + Dir.y * 5, HitPilot.x - Dir.x * 20, HitPilot.y- Dir.y * 20 )
|
||||
|
||||
-- shadow
|
||||
surface.SetDrawColor( 0, 0, 0, 50 )
|
||||
surface.DrawLine( HitPlane.x + Dir.x * 5 + 1, HitPlane.y + Dir.y * 5 + 1, HitPilot.x - Dir.x * 20+ 1, HitPilot.y- Dir.y * 20 + 1 )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,86 @@
|
||||
include("shared.lua")
|
||||
include("cl_camera.lua")
|
||||
include("sh_camera_eyetrace.lua")
|
||||
include("cl_hud.lua")
|
||||
include("cl_flyby.lua")
|
||||
include("cl_deathsound.lua")
|
||||
|
||||
ENT.TrailAlpha = 25
|
||||
|
||||
DEFINE_BASECLASS( "lvs_base" )
|
||||
|
||||
function ENT:Think()
|
||||
BaseClass.Think( self )
|
||||
|
||||
self.EFxScale = self.EFxScale and (self.EFxScale - self.EFxScale * RealFrameTime()) or 0
|
||||
|
||||
self:CalcOnThrottle()
|
||||
end
|
||||
|
||||
function ENT:CalcOnThrottle()
|
||||
if not self:GetEngineActive() then
|
||||
self._oldOnTHR = nil
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local Throttle = self:GetThrottle()
|
||||
|
||||
if self._oldOnTHR ~= Throttle then
|
||||
if self._oldOnTHR == 0 and Throttle > 0 then
|
||||
self._IsAccelerating = true
|
||||
end
|
||||
|
||||
if Throttle > (self._oldOnTHR or 0) then
|
||||
self._IsAccelerating = true
|
||||
else
|
||||
self._IsAccelerating = false
|
||||
end
|
||||
|
||||
if self._oldOnTHR == 1 then
|
||||
self:StopBoost()
|
||||
end
|
||||
|
||||
self._oldOnTHR = Throttle
|
||||
end
|
||||
|
||||
if self._oldAccelerating ~= self._IsAccelerating then
|
||||
self._oldAccelerating = self._IsAccelerating
|
||||
|
||||
if not self._IsAccelerating then return end
|
||||
|
||||
self:StartBoost()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:StartBoost()
|
||||
local T = CurTime()
|
||||
|
||||
if (self._NextSND or 0) > T then return end
|
||||
|
||||
self._NextSND = T + 1
|
||||
|
||||
self.EFxScale = 100
|
||||
|
||||
self:OnStartBoost()
|
||||
end
|
||||
|
||||
function ENT:StopBoost()
|
||||
local T = CurTime()
|
||||
|
||||
if (self._NextSND or 0) > T then return end
|
||||
|
||||
self._NextSND = T + 1
|
||||
|
||||
self:OnStopBoost()
|
||||
end
|
||||
|
||||
function ENT:GetBoost()
|
||||
return (self.EFxScale or 0)
|
||||
end
|
||||
|
||||
function ENT:OnStartBoost()
|
||||
end
|
||||
|
||||
function ENT:OnStopBoost()
|
||||
end
|
||||
@@ -0,0 +1,210 @@
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "cl_camera.lua" )
|
||||
AddCSLuaFile( "sh_camera_eyetrace.lua" )
|
||||
AddCSLuaFile( "cl_hud.lua" )
|
||||
AddCSLuaFile( "cl_flyby.lua" )
|
||||
AddCSLuaFile( "cl_deathsound.lua" )
|
||||
include("shared.lua")
|
||||
include("sv_ai.lua")
|
||||
include("sv_mouseaim.lua")
|
||||
include("sv_components.lua")
|
||||
include("sv_vehiclespecific.lua")
|
||||
include("sh_camera_eyetrace.lua")
|
||||
|
||||
DEFINE_BASECLASS( "lvs_base" )
|
||||
|
||||
function ENT:OnDriverChanged( Old, New, VehicleIsActive )
|
||||
|
||||
if not VehicleIsActive and self:GetThrottle() == 0 then
|
||||
self:SetSteer( vector_origin )
|
||||
self:SetVtolMove( vector_origin )
|
||||
end
|
||||
|
||||
self:OnPassengerChanged( Old, New, 1 )
|
||||
end
|
||||
|
||||
function ENT:StartEngine()
|
||||
if self:GetEngineActive() or not self:IsEngineStartAllowed() then return end
|
||||
|
||||
self:GetPhysicsObject():EnableGravity( false )
|
||||
|
||||
BaseClass.StartEngine( self )
|
||||
end
|
||||
|
||||
function ENT:StopEngine()
|
||||
if not self:GetEngineActive() then return end
|
||||
|
||||
self:GetPhysicsObject():EnableGravity( true )
|
||||
|
||||
BaseClass.StopEngine( self )
|
||||
end
|
||||
|
||||
function ENT:OnCreateAI()
|
||||
self:StartEngine()
|
||||
self.COL_GROUP_OLD = self:GetCollisionGroup()
|
||||
self:SetCollisionGroup( COLLISION_GROUP_INTERACTIVE_DEBRIS )
|
||||
end
|
||||
|
||||
function ENT:OnRemoveAI()
|
||||
self:StopEngine()
|
||||
self:SetCollisionGroup( self.COL_GROUP_OLD or COLLISION_GROUP_NONE )
|
||||
end
|
||||
|
||||
function ENT:ApproachTargetAngle( TargetAngle, OverridePitch, OverrideYaw, OverrideRoll, FreeMovement )
|
||||
local LocalAngles = self:WorldToLocalAngles( TargetAngle )
|
||||
|
||||
if self:GetAI() then self:SetAIAimVector( LocalAngles:Forward() ) end
|
||||
|
||||
local LocalAngPitch = LocalAngles.p
|
||||
local LocalAngYaw = LocalAngles.y
|
||||
local LocalAngRoll = LocalAngles.r
|
||||
|
||||
local TargetForward = TargetAngle:Forward()
|
||||
local Forward = self:GetForward()
|
||||
|
||||
local AngDiff = math.deg( math.acos( math.Clamp( Forward:Dot( TargetForward ) ,-1,1) ) )
|
||||
|
||||
local WingFinFadeOut = math.max( (90 - AngDiff ) / 90, 0 )
|
||||
local RudderFadeOut = math.min( math.max( (120 - AngDiff ) / 120, 0 ) * 3, 1 )
|
||||
|
||||
local AngVel = self:GetPhysicsObject():GetAngleVelocity()
|
||||
|
||||
local SmoothPitch = math.Clamp( math.Clamp(AngVel.y / 100,-0.25,0.25) / math.abs( LocalAngPitch ), -1, 1 )
|
||||
local SmoothYaw = math.Clamp( math.Clamp(AngVel.z / 100,-0.25,0.25) / math.abs( LocalAngYaw ), -1, 1 )
|
||||
|
||||
local Pitch = math.Clamp( -LocalAngPitch / 10 + SmoothPitch, -1, 1 )
|
||||
local Yaw = math.Clamp( -LocalAngYaw / 2 + SmoothYaw,-1,1) * RudderFadeOut
|
||||
local Roll = math.Clamp( (-math.Clamp(LocalAngYaw * 16 * self:GetThrottle(),-90,90) + LocalAngRoll * RudderFadeOut * 0.75) * WingFinFadeOut / 180 , -1 , 1 )
|
||||
|
||||
if FreeMovement then
|
||||
Roll = math.Clamp( -LocalAngYaw * WingFinFadeOut / 180 , -1 , 1 )
|
||||
end
|
||||
|
||||
if OverridePitch and OverridePitch ~= 0 then
|
||||
Pitch = OverridePitch
|
||||
end
|
||||
|
||||
if OverrideYaw and OverrideYaw ~= 0 then
|
||||
Yaw = OverrideYaw
|
||||
end
|
||||
|
||||
if OverrideRoll and OverrideRoll ~= 0 then
|
||||
Roll = OverrideRoll
|
||||
end
|
||||
|
||||
self:SetSteer( Vector( math.Clamp(Roll * 1.25,-1,1), math.Clamp(-Pitch * 1.25,-1,1), -Yaw) )
|
||||
end
|
||||
|
||||
function ENT:CalcAero( phys, deltatime, EntTable )
|
||||
if not EntTable then
|
||||
EntTable = self:GetTable()
|
||||
end
|
||||
|
||||
-- mouse aim needs to run at high speed.
|
||||
if self:GetAI() then
|
||||
if EntTable._lvsAITargetAng then
|
||||
self:ApproachTargetAngle( EntTable._lvsAITargetAng )
|
||||
end
|
||||
else
|
||||
local ply = self:GetDriver()
|
||||
if IsValid( ply ) and ply:lvsMouseAim() then
|
||||
self:PlayerMouseAim( ply )
|
||||
end
|
||||
end
|
||||
|
||||
local Steer = self:GetSteer()
|
||||
|
||||
local Forward = self:GetForward()
|
||||
local Left = -self:GetRight()
|
||||
|
||||
local Vel = self:GetVelocity()
|
||||
local VelForward = Vel:GetNormalized()
|
||||
|
||||
local GravityPitch = 0
|
||||
local GravityYaw = 0
|
||||
|
||||
-- crash bebehavior
|
||||
if self:IsDestroyed() then
|
||||
local WorldGravity = self:GetWorldGravity()
|
||||
local WorldUp = self:GetWorldUp()
|
||||
|
||||
local Up = self:GetUp()
|
||||
|
||||
Steer = phys:GetAngleVelocity() / 200
|
||||
|
||||
local PitchPull = (math.deg( math.acos( math.Clamp( WorldUp:Dot( Up ) ,-1,1) ) ) - 90) / 90
|
||||
local YawPull = (math.deg( math.acos( math.Clamp( WorldUp:Dot( Left ) ,-1,1) ) ) - 90) / 90
|
||||
|
||||
local GravMul = WorldGravity / 600
|
||||
|
||||
GravityPitch = math.abs( PitchPull ) ^ 1.25 * self:Sign( PitchPull ) * GravMul
|
||||
GravityYaw = math.abs( YawPull ) ^ 1.25 * self:Sign( YawPull ) * GravMul
|
||||
|
||||
if not phys:IsGravityEnabled() then
|
||||
phys:EnableGravity( true )
|
||||
end
|
||||
end
|
||||
|
||||
local Pitch = math.Clamp(Steer.y - GravityPitch,-1,1) * EntTable.TurnRatePitch * 3
|
||||
local Yaw = math.Clamp(Steer.z * 4 + GravityYaw,-1,1) * EntTable.TurnRateYaw
|
||||
local Roll = math.Clamp(Steer.x * 1.5,-1,1) * EntTable.TurnRateRoll * 12
|
||||
|
||||
local VelL = self:WorldToLocal( self:GetPos() + Vel )
|
||||
|
||||
local MulZ = (math.max( math.deg( math.acos( math.Clamp( VelForward:Dot( Forward ) ,-1,1) ) ) - math.abs( Steer.y ), 0 ) / 90) * 0.3
|
||||
local MulY = (math.max( math.abs( math.deg( math.acos( math.Clamp( VelForward:Dot( Left ) ,-1,1) ) ) - 90 ) - math.abs( Steer.z ), 0 ) / 90) * 0.15
|
||||
|
||||
local VtolMove = self:GetVtolMove()
|
||||
|
||||
local Move = Vector( (VtolMove.x < 0) and -math.min(VelL.x * 0.15,0) or 0, -VelL.y * MulY, -VelL.z * MulZ ) + VtolMove
|
||||
|
||||
return Move, Vector( Roll, Pitch, Yaw )
|
||||
end
|
||||
|
||||
function ENT:OnSkyCollide( data, PhysObj )
|
||||
local NewVelocity = self:VectorSubtractNormal( data.HitNormal, data.OurOldVelocity ) - data.HitNormal * math.Clamp(self:GetThrustStrenght() * self.MaxThrust,250,800)
|
||||
|
||||
PhysObj:SetVelocityInstantaneous( NewVelocity )
|
||||
PhysObj:SetAngleVelocityInstantaneous( data.OurOldAngularVelocity )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:PhysicsSimulate( phys, deltatime )
|
||||
if self:GetEngineActive() then
|
||||
phys:Wake()
|
||||
else
|
||||
return vector_origin, vector_origin, SIM_NOTHING
|
||||
end
|
||||
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
local Aero, Torque = self:CalcAero( phys, deltatime, EntTable )
|
||||
|
||||
local Thrust = self:GetThrustStrenght() * EntTable.MaxThrust * 100
|
||||
|
||||
if self:IsDestroyed() then
|
||||
Thrust = math.max( Thrust, 0 ) -- dont allow braking, but allow accelerating while destroyed
|
||||
end
|
||||
|
||||
local ForceLinear = (Aero * 10000 * EntTable.ForceLinearMultiplier + Vector(Thrust,0,0)) * deltatime
|
||||
local ForceAngle = (Torque * 25 * EntTable.ForceAngleMultiplier - phys:GetAngleVelocity() * 1.5 * EntTable.ForceAngleDampingMultiplier) * deltatime * 250
|
||||
|
||||
return self:PhysicsSimulateOverride( ForceAngle, ForceLinear, phys, deltatime, SIM_LOCAL_ACCELERATION )
|
||||
end
|
||||
|
||||
function ENT:PhysicsSimulateOverride( ForceAngle, ForceLinear, phys, deltatime, simulate )
|
||||
return ForceAngle, ForceLinear, simulate
|
||||
end
|
||||
|
||||
function ENT:OnMaintenance()
|
||||
for _, Engine in pairs( self:GetEngines() ) do
|
||||
if not IsValid( Engine ) then continue end
|
||||
|
||||
if not Engine.SetHP or not Engine.GetMaxHP or not Engine.SetDestroyed then continue end
|
||||
|
||||
Engine:SetHP( Engine:GetMaxHP() )
|
||||
Engine:SetDestroyed( false )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
function ENT:GetEyeTrace( trace_forward )
|
||||
local startpos = self:LocalToWorld( self:OBBCenter() )
|
||||
|
||||
local pod = self:GetDriverSeat()
|
||||
|
||||
if IsValid( pod ) then
|
||||
startpos = pod:LocalToWorld( pod:OBBCenter() )
|
||||
end
|
||||
|
||||
local AimVector = trace_forward and self:GetForward() or self:GetAimVector()
|
||||
|
||||
local data = {
|
||||
start = startpos,
|
||||
endpos = (startpos + AimVector * 50000),
|
||||
filter = self:GetCrosshairFilterEnts(),
|
||||
}
|
||||
|
||||
local trace = util.TraceLine( data )
|
||||
|
||||
return trace
|
||||
end
|
||||
|
||||
function ENT:GetAimVector()
|
||||
if self:GetAI() then
|
||||
return self:GetAIAimVector()
|
||||
end
|
||||
|
||||
local Driver = self:GetDriver()
|
||||
|
||||
if not IsValid( Driver ) then return self:GetForward() end
|
||||
|
||||
if not Driver:lvsMouseAim() then
|
||||
if Driver:lvsKeyDown( "FREELOOK" ) then
|
||||
local pod = self:GetDriverSeat()
|
||||
|
||||
if not IsValid( pod ) then return Driver:EyeAngles():Forward() end
|
||||
|
||||
if pod:GetThirdPersonMode() then
|
||||
return -self:GetForward()
|
||||
else
|
||||
return Driver:GetAimVector()
|
||||
end
|
||||
else
|
||||
return self:GetForward()
|
||||
end
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
local pod = self:GetDriverSeat()
|
||||
|
||||
if not IsValid( pod ) then return Driver:EyeAngles():Forward() end
|
||||
|
||||
return pod:WorldToLocalAngles( Driver:EyeAngles() ):Forward()
|
||||
else
|
||||
return Driver:EyeAngles():Forward()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,194 @@
|
||||
|
||||
ENT.Base = "lvs_base"
|
||||
|
||||
ENT.PrintName = "[LVS] Base Starfighter"
|
||||
ENT.Author = "Luna"
|
||||
ENT.Information = "Luna's Vehicle Script"
|
||||
ENT.Category = "[LVS]"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
|
||||
ENT.MaxVelocity = 3000
|
||||
ENT.MaxThrust = 3000
|
||||
|
||||
ENT.ThrustVtol = 55
|
||||
ENT.ThrustRateVtol = 3
|
||||
|
||||
ENT.ThrottleRateUp = 0.6
|
||||
ENT.ThrottleRateDown = 0.6
|
||||
|
||||
ENT.TurnRatePitch = 1
|
||||
ENT.TurnRateYaw = 1
|
||||
ENT.TurnRateRoll = 1
|
||||
|
||||
ENT.ForceLinearMultiplier = 1
|
||||
|
||||
ENT.ForceAngleMultiplier = 1
|
||||
ENT.ForceAngleDampingMultiplier = 1
|
||||
|
||||
ENT.DisableBallistics = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:AddDT( "Vector", "Steer" )
|
||||
self:AddDT( "Vector", "AIAimVector" )
|
||||
self:AddDT( "Vector", "NWVtolMove" )
|
||||
self:AddDT( "Float", "NWThrottle" )
|
||||
self:AddDT( "Float", "MaxThrottle" )
|
||||
|
||||
if SERVER then
|
||||
self:SetMaxThrottle( 1 )
|
||||
end
|
||||
|
||||
self:CreateBaseDT()
|
||||
end
|
||||
|
||||
function ENT:PlayerDirectInput( ply, cmd )
|
||||
local Pod = self:GetDriverSeat()
|
||||
|
||||
local Delta = FrameTime()
|
||||
|
||||
local KeyLeft = ply:lvsKeyDown( "-ROLL_SF" )
|
||||
local KeyRight = ply:lvsKeyDown( "+ROLL_SF" )
|
||||
local KeyPitchUp = ply:lvsKeyDown( "+PITCH_SF" )
|
||||
local KeyPitchDown = ply:lvsKeyDown( "-PITCH_SF" )
|
||||
local KeyRollRight = ply:lvsKeyDown( "+YAW_SF" )
|
||||
local KeyRollLeft = ply:lvsKeyDown( "-YAW_SF" )
|
||||
|
||||
local MouseX = cmd:GetMouseX()
|
||||
local MouseY = cmd:GetMouseY()
|
||||
|
||||
if ply:lvsKeyDown( "FREELOOK" ) and not Pod:GetThirdPersonMode() then
|
||||
MouseX = 0
|
||||
MouseY = 0
|
||||
else
|
||||
ply:SetEyeAngles( Angle(0,90,0) )
|
||||
end
|
||||
|
||||
local SensX, SensY, ReturnDelta = ply:lvsMouseSensitivity()
|
||||
|
||||
if KeyPitchDown then MouseY = (10 / SensY) * ReturnDelta end
|
||||
if KeyPitchUp then MouseY = -(10 / SensY) * ReturnDelta end
|
||||
if KeyRollRight or KeyRollLeft then
|
||||
local NewX = (KeyRollRight and 10 or 0) - (KeyRollLeft and 10 or 0)
|
||||
|
||||
MouseX = (NewX / SensX) * ReturnDelta
|
||||
end
|
||||
|
||||
local Input = Vector( MouseX * 0.4 * SensX, MouseY * SensY, 0 )
|
||||
|
||||
local Cur = self:GetSteer()
|
||||
|
||||
local Rate = Delta * 3 * ReturnDelta
|
||||
|
||||
local New = Vector(Cur.x, Cur.y, 0) - Vector( math.Clamp(Cur.x * Delta * 5 * ReturnDelta,-Rate,Rate), math.Clamp(Cur.y * Delta * 5 * ReturnDelta,-Rate,Rate), 0)
|
||||
|
||||
local Target = New + Input * Delta * 0.8
|
||||
|
||||
local Fx = math.Clamp( Target.x, -1, 1 )
|
||||
local Fy = math.Clamp( Target.y, -1, 1 )
|
||||
|
||||
local TargetFz = (KeyLeft and 1 or 0) - (KeyRight and 1 or 0)
|
||||
local Fz = Cur.z + math.Clamp(TargetFz - Cur.z,-Rate * 3,Rate * 3)
|
||||
|
||||
local F = Cur + (Vector( Fx, Fy, Fz ) - Cur) * math.min(Delta * 100,1)
|
||||
|
||||
self:SetSteer( F )
|
||||
end
|
||||
|
||||
function ENT:CalcThrottle( ply, cmd )
|
||||
if CLIENT then return end
|
||||
|
||||
local Delta = FrameTime()
|
||||
|
||||
local ThrottleUp = ply:lvsKeyDown( "+THRUST_SF" ) and self.ThrottleRateUp or 0
|
||||
local ThrottleDown = ply:lvsKeyDown( "-THRUST_SF" ) and -self.ThrottleRateDown or 0
|
||||
|
||||
local Throttle = (ThrottleUp + ThrottleDown) * Delta
|
||||
|
||||
self:SetThrottle( self:GetThrottle() + Throttle )
|
||||
end
|
||||
|
||||
function ENT:CalcVtolThrottle( ply, cmd )
|
||||
local Delta = FrameTime()
|
||||
|
||||
local ThrottleZero = self:GetThrottle() <= 0
|
||||
|
||||
local VtolX = ThrottleZero and (ply:lvsKeyDown( "-VTOL_X_SF" ) and -1 or 0) or 0
|
||||
local VtolY = ((ply:lvsKeyDown( "+VTOL_Y_SF" ) and 1 or 0) - (ply:lvsKeyDown( "-VTOL_Y_SF" ) and 1 or 0))
|
||||
local VtolZ = ((ply:lvsKeyDown( "+VTOL_Z_SF" ) and 1 or 0) - (ply:lvsKeyDown( "-VTOL_Z_SF" ) and 1 or 0))
|
||||
|
||||
local DesiredVtol = Vector(VtolX,VtolY,VtolZ)
|
||||
local NewVtolMove = self:GetNWVtolMove() + (DesiredVtol - self:GetNWVtolMove()) * self.ThrustRateVtol * Delta
|
||||
|
||||
if not ThrottleZero or self:WorldToLocal( self:GetPos() + self:GetVelocity() ).x > 100 then
|
||||
NewVtolMove.x = 0
|
||||
end
|
||||
|
||||
self:SetVtolMove( NewVtolMove )
|
||||
end
|
||||
|
||||
function ENT:SetVtolMove( NewMove )
|
||||
if self:GetEngineActive() then
|
||||
self:SetNWVtolMove( NewMove )
|
||||
else
|
||||
self:SetNWVtolMove( Vector(0,0,0) )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SetThrottle( NewThrottle )
|
||||
if self:GetEngineActive() then
|
||||
self:SetNWThrottle( math.Clamp(NewThrottle,0,self:GetMaxThrottle()) )
|
||||
else
|
||||
self:SetNWThrottle( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:GetThrottle()
|
||||
if self:GetEngineActive() then
|
||||
return self:GetNWThrottle()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:GetVtolMove()
|
||||
if self:GetEngineActive() and not self:GetAI() then
|
||||
return self:GetNWVtolMove() * self.ThrustVtol * (1 - math.min( self:GetThrottle(), 1 ))
|
||||
else
|
||||
return Vector(0,0,0)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:StartCommand( ply, cmd )
|
||||
if self:GetDriver() ~= ply then return end
|
||||
|
||||
if SERVER then
|
||||
local KeyJump = ply:lvsKeyDown( "VSPEC" )
|
||||
|
||||
if self._lvsOldKeyJump ~= KeyJump then
|
||||
self._lvsOldKeyJump = KeyJump
|
||||
|
||||
if KeyJump then
|
||||
self:ToggleVehicleSpecific()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not ply:lvsMouseAim() then
|
||||
self:PlayerDirectInput( ply, cmd )
|
||||
end
|
||||
|
||||
self:CalcThrottle( ply, cmd )
|
||||
self:CalcVtolThrottle( ply, cmd )
|
||||
end
|
||||
|
||||
function ENT:GetThrustStrenght()
|
||||
local ForwardVelocity = self:WorldToLocal( self:GetPos() + self:GetVelocity() ).x
|
||||
|
||||
return (self.MaxVelocity * self:GetThrottle() - ForwardVelocity) / self.MaxVelocity
|
||||
end
|
||||
|
||||
function ENT:GetVehicleType()
|
||||
return "starfighter"
|
||||
end
|
||||
@@ -0,0 +1,192 @@
|
||||
|
||||
function ENT:OnCreateAI()
|
||||
self:StartEngine()
|
||||
end
|
||||
|
||||
function ENT:OnRemoveAI()
|
||||
self:StopEngine()
|
||||
end
|
||||
|
||||
function ENT:RunAI()
|
||||
local RangerLength = 15000
|
||||
local mySpeed = self:GetVelocity():Length()
|
||||
local MinDist = 600 + mySpeed
|
||||
|
||||
local StartPos = self:LocalToWorld( self:OBBCenter() )
|
||||
|
||||
local TraceFilter = self:GetCrosshairFilterEnts()
|
||||
|
||||
local FrontLeft = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(0,20,0) ):Forward() * RangerLength } )
|
||||
local FrontRight = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(0,-20,0) ):Forward() * RangerLength } )
|
||||
|
||||
local FrontLeft2 = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(25,65,0) ):Forward() * RangerLength } )
|
||||
local FrontRight2 = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(25,-65,0) ):Forward() * RangerLength } )
|
||||
|
||||
local FrontLeft3 = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(-25,65,0) ):Forward() * RangerLength } )
|
||||
local FrontRight3 = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(-25,-65,0) ):Forward() * RangerLength } )
|
||||
|
||||
local FrontUp = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(-20,0,0) ):Forward() * RangerLength } )
|
||||
local FrontDown = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:LocalToWorldAngles( Angle(20,0,0) ):Forward() * RangerLength } )
|
||||
|
||||
local TraceForward = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + self:GetForward() * RangerLength } )
|
||||
local TraceDown = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + Vector(0,0,-RangerLength) } )
|
||||
local TraceUp = util.TraceLine( { start = StartPos, filter = TraceFilter, endpos = StartPos + Vector(0,0,RangerLength) } )
|
||||
|
||||
local cAvoid = Vector(0,0,0)
|
||||
|
||||
local myRadius = self:BoundingRadius()
|
||||
local myPos = self:GetPos()
|
||||
local myDir = self:GetForward()
|
||||
for _, v in pairs( LVS:GetVehicles() ) do
|
||||
if v == self then continue end
|
||||
|
||||
local theirRadius = v:BoundingRadius()
|
||||
local Sub = (myPos - v:GetPos())
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Dist = Sub:Length()
|
||||
|
||||
if Dist < (theirRadius + myRadius + 200) then
|
||||
if math.deg( math.acos( math.Clamp( myDir:Dot( -Dir ) ,-1,1) ) ) < 90 then
|
||||
cAvoid = cAvoid + Dir * (theirRadius + myRadius + 500)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local FLp = FrontLeft.HitPos + FrontLeft.HitNormal * MinDist + cAvoid * 8
|
||||
local FRp = FrontRight.HitPos + FrontRight.HitNormal * MinDist + cAvoid * 8
|
||||
|
||||
local FL2p = FrontLeft2.HitPos + FrontLeft2.HitNormal * MinDist
|
||||
local FR2p = FrontRight2.HitPos + FrontRight2.HitNormal * MinDist
|
||||
|
||||
local FL3p = FrontLeft3.HitPos + FrontLeft3.HitNormal * MinDist
|
||||
local FR3p = FrontRight3.HitPos + FrontRight3.HitNormal * MinDist
|
||||
|
||||
local FUp = FrontUp.HitPos + FrontUp.HitNormal * MinDist
|
||||
local FDp = FrontDown.HitPos + FrontDown.HitNormal * MinDist
|
||||
|
||||
local Up = TraceUp.HitPos + TraceUp.HitNormal * MinDist
|
||||
local Dp = TraceDown.HitPos + TraceDown.HitNormal * MinDist
|
||||
|
||||
local TargetPos = (FLp+FRp+FL2p+FR2p+FL3p+FR3p+FUp+FDp+Up+Dp) / 10
|
||||
|
||||
local alt = (StartPos - TraceDown.HitPos):Length()
|
||||
local ceiling = (StartPos - TraceUp.HitPos):Length()
|
||||
|
||||
local WallDist = (StartPos - TraceForward.HitPos):Length()
|
||||
|
||||
local Throttle = math.min( WallDist / mySpeed, 1 )
|
||||
|
||||
self._AIFireInput = false
|
||||
|
||||
if alt < 600 or ceiling < 600 or WallDist < (MinDist * 3 * (math.deg( math.acos( math.Clamp( Vector(0,0,1):Dot( myDir ) ,-1,1) ) ) / 180) ^ 2) then
|
||||
Throttle = 1
|
||||
|
||||
if self:HitGround() then
|
||||
TargetPos.z = StartPos.z + 750
|
||||
end
|
||||
else
|
||||
if IsValid( self:GetHardLockTarget() ) then
|
||||
TargetPos = self:GetHardLockTarget():GetPos() + cAvoid * 8
|
||||
else
|
||||
if alt > mySpeed then
|
||||
local Target = self._LastAITarget
|
||||
|
||||
if not IsValid( self._LastAITarget ) or not self:AITargetInFront( self._LastAITarget, 135 ) or not self:AICanSee( self._LastAITarget ) then
|
||||
Target = self:AIGetTarget()
|
||||
end
|
||||
|
||||
if IsValid( Target ) then
|
||||
if self:AITargetInFront( Target, 65 ) then
|
||||
local T = CurTime() + self:EntIndex() * 1337
|
||||
TargetPos = Target:GetPos() + cAvoid * 8 + Vector(0,0, math.sin( T * 5 ) * 500 ) + Target:GetVelocity() * math.abs( math.cos( T * 13.37 ) ) * 5
|
||||
|
||||
Throttle = math.min( (StartPos - TargetPos):Length() / mySpeed, 1 )
|
||||
|
||||
local tr = util.TraceHull( {
|
||||
start = StartPos,
|
||||
endpos = (StartPos + self:GetForward() * 50000),
|
||||
mins = Vector( -50, -50, -50 ),
|
||||
maxs = Vector( 50, 50, 50 ),
|
||||
filter = TraceFilter
|
||||
} )
|
||||
|
||||
local CanShoot = (IsValid( tr.Entity ) and tr.Entity.LVS and tr.Entity.GetAITEAM) and (tr.Entity:GetAITEAM() ~= self:GetAITEAM() or tr.Entity:GetAITEAM() == 0) or true
|
||||
|
||||
if CanShoot and self:AITargetInFront( Target, 22 ) then
|
||||
local CurHeat = self:GetNWHeat()
|
||||
local CurWeapon = self:GetSelectedWeapon()
|
||||
|
||||
if CurWeapon > 2 then
|
||||
self:AISelectWeapon( 1 )
|
||||
else
|
||||
if CurHeat > 0.9 then
|
||||
if CurWeapon == 1 and self:AIHasWeapon( 2 ) then
|
||||
self:AISelectWeapon( 2 )
|
||||
|
||||
elseif CurWeapon == 2 then
|
||||
self:AISelectWeapon( 1 )
|
||||
end
|
||||
else
|
||||
if CurHeat == 0 and math.cos( T ) > 0 then
|
||||
self:AISelectWeapon( 1 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self._AIFireInput = true
|
||||
end
|
||||
else
|
||||
self:AISelectWeapon( 1 )
|
||||
|
||||
if alt > 6000 and self:AITargetInFront( Target, 90 ) then
|
||||
TargetPos = Target:GetPos()
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
TargetPos.z = StartPos.z + 2000
|
||||
|
||||
self:EnableVehicleSpecific()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:SetThrottle( Throttle )
|
||||
|
||||
self.smTargetPos = self.smTargetPos and self.smTargetPos + (TargetPos - self.smTargetPos) * FrameTime() or self:GetPos()
|
||||
|
||||
self._lvsAITargetAng = (self.smTargetPos - self:GetPos()):GetNormalized():Angle()
|
||||
end
|
||||
|
||||
function ENT:AISelectWeapon( ID )
|
||||
if ID == self:GetSelectedWeapon() then return end
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if (self._nextAISwitchWeapon or 0) > T then return end
|
||||
|
||||
self._nextAISwitchWeapon = T + math.random(3,6)
|
||||
|
||||
self:SelectWeapon( ID )
|
||||
end
|
||||
|
||||
function ENT:OnAITakeDamage( dmginfo )
|
||||
local attacker = dmginfo:GetAttacker()
|
||||
|
||||
if not IsValid( attacker ) then return end
|
||||
|
||||
if not self:AITargetInFront( attacker, IsValid( self:AIGetTarget() ) and 120 or 45 ) then
|
||||
self:SetHardLockTarget( attacker )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SetHardLockTarget( target )
|
||||
self._HardLockTarget = target
|
||||
self._HardLockTime = CurTime() + 4
|
||||
end
|
||||
|
||||
function ENT:GetHardLockTarget()
|
||||
if (self._HardLockTime or 0) < CurTime() then return NULL end
|
||||
|
||||
return self._HardLockTarget
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
|
||||
function ENT:AddEngine( pos, ang, mins, maxs, health )
|
||||
local Engine = ents.Create( "lvs_starfighter_engine" )
|
||||
|
||||
if not IsValid( Engine ) then
|
||||
self:Remove()
|
||||
|
||||
print("LVS: Failed to create engine entity. Vehicle terminated.")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
Engine:SetPos( self:LocalToWorld( pos ) )
|
||||
Engine:SetAngles( self:GetAngles() )
|
||||
Engine:Spawn()
|
||||
Engine:Activate()
|
||||
Engine:SetParent( self )
|
||||
Engine:SetBase( self )
|
||||
|
||||
if not health then
|
||||
health = self.MaxHealth / 8
|
||||
end
|
||||
|
||||
Engine:SetMaxHP( health )
|
||||
Engine:SetHP( health )
|
||||
self:DeleteOnRemove( Engine )
|
||||
self:TransferCPPI( Engine )
|
||||
|
||||
self:AddDS( {
|
||||
pos = pos,
|
||||
ang = (ang or Angle(0,0,0)),
|
||||
mins = (mins or Vector(-40,-20,-30)),
|
||||
maxs = (maxs or Vector(40,20,30)),
|
||||
Callback = function( tbl, ent, dmginfo )
|
||||
if dmginfo:GetDamage() <= 0 then return end
|
||||
|
||||
Engine:TakeDamageInfo( dmginfo )
|
||||
end
|
||||
} )
|
||||
|
||||
|
||||
if not istable( self._lvsEngines ) then
|
||||
self._lvsEngines = {}
|
||||
end
|
||||
|
||||
table.insert( self._lvsEngines, Engine )
|
||||
|
||||
return Engine
|
||||
end
|
||||
|
||||
function ENT:GetEngines()
|
||||
return self._lvsEngines or {}
|
||||
end
|
||||
|
||||
function ENT:AddEngineSound( pos )
|
||||
local EngineSND = ents.Create( "lvs_starfighter_soundemitter" )
|
||||
|
||||
if not IsValid( EngineSND ) then
|
||||
self:Remove()
|
||||
|
||||
print("LVS: Failed to create engine sound entity. Vehicle terminated.")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
EngineSND:SetPos( self:LocalToWorld( pos ) )
|
||||
EngineSND:SetAngles( self:GetAngles() )
|
||||
EngineSND:Spawn()
|
||||
EngineSND:Activate()
|
||||
EngineSND:SetParent( self )
|
||||
EngineSND:SetBase( self )
|
||||
|
||||
self:DeleteOnRemove( EngineSND )
|
||||
|
||||
self:TransferCPPI( EngineSND )
|
||||
|
||||
return EngineSND
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
function ENT:PlayerMouseAim( ply )
|
||||
local Pod = self:GetDriverSeat()
|
||||
|
||||
local PitchUp = ply:lvsKeyDown( "+PITCH_SF" )
|
||||
local PitchDown = ply:lvsKeyDown( "-PITCH_SF" )
|
||||
local YawRight = ply:lvsKeyDown( "+YAW_SF" )
|
||||
local YawLeft = ply:lvsKeyDown( "-YAW_SF" )
|
||||
local RollRight = ply:lvsKeyDown( "+ROLL_SF" )
|
||||
local RollLeft = ply:lvsKeyDown( "-ROLL_SF" )
|
||||
|
||||
local FreeLook = ply:lvsKeyDown( "FREELOOK" )
|
||||
|
||||
local EyeAngles = Pod:WorldToLocalAngles( ply:EyeAngles() )
|
||||
|
||||
if FreeLook then
|
||||
if isangle( self.StoredEyeAngles ) then
|
||||
EyeAngles = self.StoredEyeAngles
|
||||
end
|
||||
else
|
||||
self.StoredEyeAngles = EyeAngles
|
||||
end
|
||||
|
||||
local OverridePitch = 0
|
||||
local OverrideYaw = 0
|
||||
local OverrideRoll = (RollRight and 1 or 0) - (RollLeft and 1 or 0)
|
||||
|
||||
if PitchUp or PitchDown then
|
||||
EyeAngles = self:GetAngles()
|
||||
|
||||
self.StoredEyeAngles = Angle(EyeAngles.p,EyeAngles.y,0)
|
||||
|
||||
OverridePitch = (PitchUp and 1 or 0) - (PitchDown and 1 or 0)
|
||||
end
|
||||
|
||||
if YawRight or YawLeft then
|
||||
EyeAngles = self:GetAngles()
|
||||
|
||||
self.StoredEyeAngles = Angle(EyeAngles.p,EyeAngles.y,0)
|
||||
|
||||
OverrideYaw = (YawRight and 1 or 0) - (YawLeft and 1 or 0)
|
||||
end
|
||||
|
||||
self:ApproachTargetAngle( EyeAngles, OverridePitch, OverrideYaw, OverrideRoll, FreeLook )
|
||||
end
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
function ENT:ToggleVehicleSpecific()
|
||||
self._VSPEC = not self._VSPEC
|
||||
|
||||
self:OnVehicleSpecificToggled( self._VSPEC )
|
||||
end
|
||||
|
||||
function ENT:EnableVehicleSpecific()
|
||||
if self._VSPEC then return end
|
||||
|
||||
self._VSPEC = true
|
||||
|
||||
self:OnVehicleSpecificToggled( self._VSPEC )
|
||||
end
|
||||
|
||||
function ENT:DisableVehicleSpecific()
|
||||
if not self._VSPEC then return end
|
||||
|
||||
self._VSPEC = false
|
||||
|
||||
self:OnVehicleSpecificToggled( self._VSPEC )
|
||||
end
|
||||
|
||||
function ENT:OnVehicleSpecificToggled( IsActive )
|
||||
end
|
||||
Reference in New Issue
Block a user