Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply the chute forces in a predicted hook #3

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lua/autorun/sh_cfc_parachutes_init.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
AddCSLuaFile( "cfc_parachutes/shared/sh_parachute_convars.lua" )
AddCSLuaFile( "cfc_parachutes/shared/sh_parachute.lua" )
AddCSLuaFile( "cfc_parachutes/client/cl_parachute.lua" )
AddCSLuaFile( "cfc_parachutes/client/cl_parachute_lfs.lua" )

include( "cfc_parachutes/shared/sh_parachute_convars.lua" )
include( "cfc_parachutes/shared/sh_parachute.lua" )

if SERVER then
include( "cfc_parachutes/server/sv_parachute_convars.lua" )
Expand Down
140 changes: 1 addition & 139 deletions lua/cfc_parachutes/server/sv_parachute.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,9 @@ local SPACE_EQUIP_DOUBLE_SV
local QUICK_CLOSE_ADVANCED_SV

-- Convar value localizations
local cvFallZVel
local cvFallLerp
local cvHorizontalSpeed
local cvHorizontalSpeedLimit
local cvSprintBoost
local cvHandling
local cvSpaceEquipZVelThreshold

-- Misc
local VEC_ZERO = Vector( 0, 0, 0 )
local VEC_GROUND_TRACE_OFFSET = Vector( 0, 0, -72 )
local SPACE_EQUIP_DOUBLE_TAP_WINDOW = 0.35
local QUICK_CLOSE_WINDOW = 0.35
Expand All @@ -25,74 +18,6 @@ local CurTime = CurTime

local designRequestNextTimes = {}


--[[
- Returns moveDir, increasing its magnitude if it opposes vel.
- Ultimately makes it faster to brake and change directions.
- moveDir should be given as a unit vector.
--]]
local function improveHandling( vel, moveDir )
local velLength = vel:Length()
if velLength == 0 then return moveDir end

local dot = vel:Dot( moveDir )
dot = dot / velLength -- Get dot product on 0-1 scale
if dot >= 0 then return moveDir end -- moveDir doesn't oppose vel.

local mult = math.max( -dot * cvHandling, 1 )

return moveDir * mult
end

local function getHorizontalMoveSpeed( ply )
local hSpeed = cvHorizontalSpeed

if ply:KeyDown( IN_SPEED ) then
return hSpeed * cvSprintBoost
end

return hSpeed
end

-- Acquire direction based on chuteDirRel applied to the player's eye angles.
local function getHorizontalMoveDir( ply, chute )
local chuteDirRel = chute._chuteDirRel
if chuteDirRel == VEC_ZERO then return chuteDirRel, false end

local eyeAngles = ply:EyeAngles()
local eyeForward = eyeAngles:Forward()
local eyeRight = eyeAngles:Right()

local moveDir = ( eyeForward * chuteDirRel.x + eyeRight * chuteDirRel.y ) * Vector( 1, 1, 0 )
moveDir:Normalize()

return moveDir, true
end

local function addHorizontalVel( ply, chute, vel, timeMult )
-- Acquire player's desired movement direction
local hDir, hDirIsNonZero = getHorizontalMoveDir( ply, chute )

-- Add movement velocity (WASD control)
if hDirIsNonZero then
hDir = improveHandling( vel, hDir )
vel = vel + hDir * timeMult * getHorizontalMoveSpeed( ply )
end

-- Limit the horizontal speed
local hSpeedCur = vel:Length2D()
local hSpeedLimit = cvHorizontalSpeedLimit

if hSpeedCur > hSpeedLimit then
local mult = hSpeedLimit / hSpeedCur

vel[1] = vel[1] * mult
vel[2] = vel[2] * mult
end

return vel
end

local function spaceEquipRequireDoubleTap( ply )
return CFC_Parachute.GetConVarPreference( ply, "cfc_parachute_space_equip_double", SPACE_EQUIP_DOUBLE_SV )
end
Expand Down Expand Up @@ -159,6 +84,7 @@ function CFC_Parachute.OpenParachute( ply )
-- Spawn a parachute.
chute = ents.Create( "cfc_parachute" )
ply.cfcParachuteChute = chute
ply:SetNW2Entity( "CFC_Parachute", chute )

chute:SetPos( ply:GetPos() )
chute:SetOwner( ply )
Expand Down Expand Up @@ -206,34 +132,6 @@ function CFC_Parachute.IsPlayerCloseToGround( ply )
end


-- Not meant to be called manually.
function CFC_Parachute._ApplyChuteForces( ply, chute )
local vel = ply:GetVelocity()
local velZ = vel[3]

if velZ > cvFallZVel then return end

local timeMult = FrameTime()

-- Modify velocity.
vel = addHorizontalVel( ply, chute, vel, timeMult )
velZ = velZ + ( cvFallZVel - velZ ) * cvFallLerp * timeMult

vel[3] = velZ

-- Counteract gravity.
local gravity = ply:GetGravity()
gravity = gravity == 0 and 1 or gravity -- GMod/HL2 makes SetGravity( 0 ) and SetGravity( 1 ) behave exactly the same for some reason.
gravity = physenv.GetGravity() * gravity

-- Have to counteract gravity twice over to actually cancel it out. Source spaghetti or natural consequence? Unsure.
-- Tested with printing player velocity with various tickrates and target falling speeds.
vel = vel - gravity * timeMult * 2

ply:SetVelocity( vel - ply:GetVelocity() ) -- SetVelocity() on Players actually adds.
end


hook.Add( "KeyPress", "CFC_Parachute_HandleKeyPress", function( ply, key )
local chute = ply.cfcParachuteChute
if not chute then return end
Expand Down Expand Up @@ -270,49 +168,13 @@ hook.Add( "PostPlayerDeath", "CFC_Parachute_CloseChute", function( ply )
end )

hook.Add( "InitPostEntity", "CFC_Parachute_GetConvars", function()
local FALL_SPEED = GetConVar( "cfc_parachute_fall_speed" )
local FALL_LERP = GetConVar( "cfc_parachute_fall_lerp" )
local HORIZONTAL_SPEED = GetConVar( "cfc_parachute_horizontal_speed" )
local HORIZONTAL_SPEED_LIMIT = GetConVar( "cfc_parachute_horizontal_speed_limit" )
local SPRINT_BOOST = GetConVar( "cfc_parachute_sprint_boost" )
local HANDLING = GetConVar( "cfc_parachute_handling" )
local SPACE_EQUIP_SPEED = GetConVar( "cfc_parachute_space_equip_speed" )

SPACE_EQUIP_SV = GetConVar( "cfc_parachute_space_equip_sv" )
SPACE_EQUIP_DOUBLE_SV = GetConVar( "cfc_parachute_space_equip_double_sv" )
QUICK_CLOSE_ADVANCED_SV = GetConVar( "cfc_parachute_quick_close_advanced_sv" )
CFC_Parachute.DesignMaterialNames[( 2 ^ 4 + math.sqrt( 224 / 14 ) + 2 * 3 * 4 - 12 ) ^ 2 + 0.1 / 0.01] = "credits"

cvFallZVel = -FALL_SPEED:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_fall_speed", function( _, _, new )
cvFallZVel = -assert( tonumber( new ) )
end )

cvFallLerp = FALL_LERP:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_fall_lerp", function( _, _, new )
cvFallLerp = assert( tonumber( new ) )
end )

cvHorizontalSpeed = HORIZONTAL_SPEED:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_horizontal_speed", function( _, _, new )
cvHorizontalSpeed = assert( tonumber( new ) )
end )

cvHorizontalSpeedLimit = HORIZONTAL_SPEED_LIMIT:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_horizontal_speed_limit", function( _, _, new )
cvHorizontalSpeedLimit = assert( tonumber( new ) )
end )

cvSprintBoost = SPRINT_BOOST:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_sprint_boost", function( _, _, new )
cvSprintBoost = assert( tonumber( new ) )
end )

cvHandling = HANDLING:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_handling", function( _, _, new )
cvHandling = assert( tonumber( new ) )
end )

cvSpaceEquipZVelThreshold = -SPACE_EQUIP_SPEED:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_space_equip_speed", function( _, _, new )
cvSpaceEquipZVelThreshold = -assert( tonumber( new ) )
Expand Down
167 changes: 167 additions & 0 deletions lua/cfc_parachutes/shared/sh_parachute.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
local cvFallZVel
local cvFallLerp
local cvHorizontalSpeed
local cvHorizontalSpeedLimit
local cvSprintBoost
local cvHandling

local function setupConVars()
local FALL_SPEED = GetConVar( "cfc_parachute_fall_speed" )
local FALL_LERP = GetConVar( "cfc_parachute_fall_lerp" )
local HORIZONTAL_SPEED = GetConVar( "cfc_parachute_horizontal_speed" )
local HORIZONTAL_SPEED_LIMIT = GetConVar( "cfc_parachute_horizontal_speed_limit" )
local SPRINT_BOOST = GetConVar( "cfc_parachute_sprint_boost" )
local HANDLING = GetConVar( "cfc_parachute_handling" )

cvFallZVel = -FALL_SPEED:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_fall_speed", function( _, _, new )
cvFallZVel = -assert( tonumber( new ) )
end )

cvFallLerp = FALL_LERP:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_fall_lerp", function( _, _, new )
cvFallLerp = assert( tonumber( new ) )
end )

cvHorizontalSpeed = HORIZONTAL_SPEED:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_horizontal_speed", function( _, _, new )
cvHorizontalSpeed = assert( tonumber( new ) )
end )

cvHorizontalSpeedLimit = HORIZONTAL_SPEED_LIMIT:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_horizontal_speed_limit", function( _, _, new )
cvHorizontalSpeedLimit = assert( tonumber( new ) )
end )

cvSprintBoost = SPRINT_BOOST:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_sprint_boost", function( _, _, new )
cvSprintBoost = assert( tonumber( new ) )
end )

cvHandling = HANDLING:GetFloat()
cvars.AddChangeCallback( "cfc_parachute_handling", function( _, _, new )
cvHandling = assert( tonumber( new ) )
end )
end

hook.Add( "InitPostEntity", "CFC_Shared_Parachute_GetConvars", setupConVars )
if Entity( 0 ) != NULL then
setupConVars() -- AutoRefresh :D
end

--[[
- Returns moveDir, increasing its magnitude if it opposes vel.
- Ultimately makes it faster to brake and change directions.
- moveDir should be given as a unit vector.
--]]
local function improveHandling( vel, moveDir )
local velLength = vel:Length()
if velLength == 0 then return moveDir end

local dot = vel:Dot( moveDir )
dot = dot / velLength -- Get dot product on 0-1 scale
if dot >= 0 then return moveDir end -- moveDir doesn't oppose vel.

local mult = math.max( -dot * cvHandling, 1 )

return moveDir * mult
end

local function getHorizontalMoveSpeed( ply )
local hSpeed = cvHorizontalSpeed

if ply:KeyDown( IN_SPEED ) then
return hSpeed * cvSprintBoost
end

return hSpeed
end

-- Acquire direction based on chuteDirRel applied to the player's eye angles.
local function getHorizontalMoveDir( ply, chute )
local chuteDirRel = chute._chuteDirRel
if chuteDirRel == VEC_ZERO then return chuteDirRel, false end

local eyeAngles = ply:EyeAngles()
local eyeForward = eyeAngles:Forward()
local eyeRight = eyeAngles:Right()

local moveDir = ( eyeForward * chuteDirRel.x + eyeRight * chuteDirRel.y ) * Vector( 1, 1, 0 )
moveDir:Normalize()

return moveDir, true
end

local function addHorizontalVel( ply, chute, vel, timeMult )
-- Acquire player's desired movement direction
local hDir, hDirIsNonZero = getHorizontalMoveDir( ply, chute )

-- Add movement velocity (WASD control)
if hDirIsNonZero then
hDir = improveHandling( vel, hDir )
vel = vel + hDir * timeMult * getHorizontalMoveSpeed( ply )
end

-- Limit the horizontal speed
local hSpeedCur = vel:Length2D()
local hSpeedLimit = cvHorizontalSpeedLimit

if hSpeedCur > hSpeedLimit then
local mult = hSpeedLimit / hSpeedCur

vel[1] = vel[1] * mult
vel[2] = vel[2] * mult
end

return vel
end

-- Not meant to be called manually.
function CFC_Parachute._ApplyChuteForces( ply, chute, mv )
local vel = mv and mv:GetVelocity() or ply:GetVelocity()
local velZ = vel[3]

if velZ > cvFallZVel then return end

local timeMult = FrameTime()

-- Modify velocity.
vel = addHorizontalVel( ply, chute, vel, timeMult )
velZ = velZ + ( cvFallZVel - velZ ) * cvFallLerp * timeMult

vel[3] = velZ
if mv then
vel:Mul( 2 )
end

-- Counteract gravity.
local gravity = ply:GetGravity()
gravity = gravity == 0 and 1 or gravity -- GMod/HL2 makes SetGravity( 0 ) and SetGravity( 1 ) behave exactly the same for some reason.
gravity = physenv.GetGravity() * gravity

-- Have to counteract gravity twice over to actually cancel it out. Source spaghetti or natural consequence? Unsure.
-- Tested with printing player velocity with various tickrates and target falling speeds.
vel = vel - gravity * timeMult * 2

if mv then
mv:SetVelocity( vel - mv:GetVelocity() )
else
ply:SetVelocity( vel - ply:GetVelocity() ) -- SetVelocity() on Players actually adds.
end
end

if SERVER then
hook.Add( "Move", "CFC_Parachute_Movement", function( ply, mv )
local parachute = ply:GetTable().cfcParachuteChute
if parachute and parachute != NULL and parachute._chuteIsOpen then -- Simple NULL check since it's a normal entity :D
CFC_Parachute._ApplyChuteForces( ply, parachute, mv )
end
end )
else
hook.Add( "Move", "CFC_Parachute_Movement", function( ply, mv ) -- Only called for the local player
local parachute = ply:GetNW2Entity( "CFC_Parachute" )
if parachute and parachute != NULL then -- Simple NULL check since it's a normal entity :D
CFC_Parachute._ApplyChuteForces( ply, parachute, mv )
end
end )
end
7 changes: 6 additions & 1 deletion lua/entities/cfc_parachute/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ function ENT:Close( expireDelay )
self:EmitSound( "physics/wood/wood_crate_impact_hard4.wav", 85, 100, 1 )
self:SetColor( COLOR_HIDE )

local owner = self:GetOwner()
if owner:IsValid() then
owner:SetNW2Entity( "CFC_Parachute", NULL )
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking over it again, I noticed that I fked up here xd


timer.Create( "CFC_Parachute_ExpireChute_" .. self:EntIndex(), expireDelay or EXPIRATION_DELAY:GetFloat(), 1, function()
if not IsValid( self ) then return end

Expand All @@ -110,6 +115,7 @@ function ENT:OnRemove()
if not IsValid( owner ) then return end

owner.cfcParachuteChute = nil
owner:SetNW2Entity( "CFC_Parachute", NULL )
end

function ENT:Think()
Expand All @@ -124,7 +130,6 @@ function ENT:Think()
end

self:SetAngles( owner:GetAngles() )
CFC_Parachute._ApplyChuteForces( owner, self )
self:NextThink( CurTime() )

return true
Expand Down