Files
wnsrc/lua/drive/drive_sandbox.lua

224 lines
5.5 KiB
Lua
Raw Normal View History

2024-08-04 23:12:27 +03:00
--[[
| 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()
--
--
-- This is the default drive type for when you right click -> drive in sandbox
--
--
DEFINE_BASECLASS( "drive_base" )
drive.Register( "drive_sandbox",
{
--
-- Called on creation
--
Init = function( self )
self.CameraDist = 4
self.CameraDistVel = 0.1
end,
--
-- Calculates the view when driving the entity
--
CalcView = function( self, view )
--
-- Use the utility method on drive_base.lua to give us a 3rd person view
--
local idealdist = math.max( 10, self.Entity:BoundingRadius() ) * self.CameraDist
self:CalcView_ThirdPerson( view, idealdist, 2, { self.Entity } )
view.angles.roll = 0
end,
SetupControls = function( self, cmd )
--
-- If we're holding the reload key down then freeze the view angles
--
if ( cmd:KeyDown( IN_RELOAD ) ) then
self.CameraForceViewAngles = self.CameraForceViewAngles or cmd:GetViewAngles()
cmd:SetViewAngles( self.CameraForceViewAngles )
else
self.CameraForceViewAngles = nil
end
--
-- Zoom out when we use the mouse wheel (this is completely clientside, so it's ok to use a lua var!!)
--
self.CameraDistVel = self.CameraDistVel + cmd:GetMouseWheel() * -0.5
self.CameraDist = self.CameraDist + self.CameraDistVel * FrameTime()
self.CameraDist = math.Clamp( self.CameraDist, 2, 20 )
self.CameraDistVel = math.Approach( self.CameraDistVel, 0, self.CameraDistVel * FrameTime() * 2 )
end,
--
-- Called before each move. You should use your entity and cmd to
-- fill mv with information you need for your move.
--
StartMove = function( self, mv, cmd )
--
-- Set the observer mode to chase so that the entity is drawn
--
self.Player:SetObserverMode( OBS_MODE_CHASE )
--
-- Use (E) was pressed - stop it.
--
if ( mv:KeyReleased( IN_USE ) ) then
self:Stop()
end
--
-- Update move position and velocity from our entity
--
mv:SetOrigin( self.Entity:GetNetworkOrigin() )
mv:SetVelocity( self.Entity:GetAbsVelocity() )
mv:SetMoveAngles( mv:GetAngles() ) -- Always move relative to the player's eyes
local entity_angle = mv:GetAngles()
entity_angle.roll = self.Entity:GetAngles().roll
--
-- Right mouse button is down, don't change the angle of the object
--
if ( mv:KeyDown( IN_ATTACK2 ) or mv:KeyReleased( IN_ATTACK2 ) ) then
entity_angle = self.Entity:GetAngles()
end
--
-- If reload is down then spin the object around
--
if ( mv:KeyDown( IN_RELOAD ) ) then
entity_angle.roll = entity_angle.roll + cmd:GetMouseX() * 0.01
end
--
-- Right mouse button was released
--
if ( mv:KeyReleased( IN_ATTACK2 ) ) then
self.Player:SetEyeAngles( self.Entity:GetAngles() )
end
mv:SetAngles( entity_angle )
end,
--
-- Runs the actual move. On the client when there's
-- prediction errors this can be run multiple times.
-- You should try to only change mv.
--
Move = function( self, mv )
--
-- Set up a speed, go faster if shift is held down
--
local speed = 0.0005 * FrameTime()
if ( mv:KeyDown( IN_SPEED ) ) then speed = 0.005 * FrameTime() end
if ( mv:KeyDown( IN_DUCK ) ) then speed = 0.00005 * FrameTime() end
-- Simulate noclip's action when holding space
if ( mv:KeyDown( IN_JUMP ) ) then mv:SetUpSpeed( 10000 ) end
--
-- Get information from the movedata
--
local ang = mv:GetMoveAngles()
local pos = mv:GetOrigin()
local vel = mv:GetVelocity()
-- Cancel out the roll
ang.roll = 0
--
-- Add velocities. This can seem complicated. On the first line
-- we're basically saying get the forward vector, then multiply it
-- by our forward speed (which will be > 0 if we're holding W, < 0 if we're
-- holding S and 0 if we're holding neither) - and add that to velocity.
-- We do that for right and up too, which gives us our free movement.
--
vel = vel + ang:Forward() * mv:GetForwardSpeed() * speed
vel = vel + ang:Right() * mv:GetSideSpeed() * speed
vel = vel + ang:Up() * mv:GetUpSpeed() * speed
--
-- We don't want our velocity to get out of hand so we apply
-- a little bit of air resistance. If no keys are down we apply
-- more resistance so we slow down more.
--
if ( math.abs( mv:GetForwardSpeed() ) + math.abs( mv:GetSideSpeed() ) + math.abs( mv:GetUpSpeed() ) < 0.1 ) then
vel = vel * 0.90
else
vel = vel * 0.99
end
--
-- Add the velocity to the position (this is the movement)
--
pos = pos + vel
--
-- We don't set the newly calculated values on the entity itself
-- we instead store them in the movedata. These get applied in FinishMove.
--
mv:SetVelocity( vel )
mv:SetOrigin( pos )
end,
--
-- The move is finished. Use mv to set the new positions
-- on your entities/players.
--
FinishMove = function( self, mv )
--
-- Update our entity!
--
self.Entity:SetNetworkOrigin( mv:GetOrigin() )
self.Entity:SetAbsVelocity( mv:GetVelocity() )
self.Entity:SetAngles( mv:GetAngles() )
--
-- If we have a physics object update that too. But only on the server.
--
if ( SERVER && IsValid( self.Entity:GetPhysicsObject() ) ) then
self.Entity:GetPhysicsObject():EnableMotion( true )
self.Entity:GetPhysicsObject():SetPos( mv:GetOrigin() )
self.Entity:GetPhysicsObject():Wake()
self.Entity:GetPhysicsObject():EnableMotion( false )
end
end
}, "drive_base" )