AHL_DIVE_DIRECTION_LEFT = "left" AHL_DIVE_DIRECTION_RIGHT = "right" AHL_DIVE_DIRECTION_FORWARD = "forward" AHL_DIVE_DIRECTION_BACKWARD = "backward" AHL_DIVE_TIME = 0.5 AHL_DIVE_MOMENTUM = 300.0 AHL_DIVE_ZFACTOR = 200.0 AHL_DIVE_ROLL_TIME = 1.5 AHL_DIVE_ROLL_SPEED = 50 AHL_DEBUG_ENABLED = true function dive(pl, command, args) if (pl.Diving || pl.Rolling) then return end if (pl:KeyDown(IN_MOVELEFT)) then pl.DiveDirection = AHL_DIVE_DIRECTION_LEFT elseif (pl:KeyDown(IN_MOVERIGHT)) then pl.DiveDirection = AHL_DIVE_DIRECTION_RIGHT elseif (pl:KeyDown(IN_BACK)) then pl.DiveDirection = AHL_DIVE_DIRECTION_BACKWARD elseif (pl:KeyDown(IN_FORWARD)) then pl.DiveDirection = AHL_DIVE_DIRECTION_FORWARD else return end debugLog(pl, "Dive type '" .. pl.DiveDirection .. "' detected") debugLog(pl, "Initiating dive, initial velocity = " .. tostring(pl:GetVelocity():Normalize())) pl:SetVelocity(pl:GetVelocity():Normalize() * AHL_DIVE_MOMENTUM + Vector(0, 0, AHL_DIVE_ZFACTOR)) pl.Diving = true pl.DiveCompleted = false; timer.Simple(AHL_DIVE_TIME, completeDive, pl) end function completeDive(pl) pl.DiveCompleted = true debugLog(pl, "Dive completed") end function completeRoll(pl) pl.Rolling = false; debugLog(pl, "Roll completed") end function onThinkDive() for k, pl in pairs(player.GetAll()) do if (pl.Diving && pl.DiveCompleted && pl:IsOnGround()) then pl.Diving = false pl.Rolling = true debugLog(pl, "Initiating roll") timer.Simple(AHL_DIVE_ROLL_TIME, completeRoll, pl) end end end function onThinkRoll() for k, pl in pairs(player.GetAll()) do if (pl.Rolling) then if (pl.DiveDirection == AHL_DIVE_DIRECTION_RIGHT) then pl:SetVelocity(pl:GetAngles():Right() * AHL_DIVE_ROLL_SPEED) elseif (pl.DiveDirection == AHL_DIVE_DIRECTION_LEFT) then pl:SetVelocity(pl:GetAngles():Left() * AHL_DIVE_ROLL_SPEED) end end end end function debugLog(pl, msg) if (AHL_DEBUG_ENABLED) then pl:PrintMessage(HUD_PRINTTALK, msg) end end concommand.Add("dive", dive) hook.Add("Think", "ahl_think_dive", onThinkDive) hook.Add("Think", "ahl_think_roll", onThinkRoll)