mirror of
https://github.com/JonnyBro/beatrun.git
synced 2025-04-03 17:37:08 +05:00
283 lines
6.3 KiB
Lua
283 lines
6.3 KiB
Lua
if SERVER and game.SinglePlayer() then
|
|
util.AddNetworkString("Zipline_SPFix")
|
|
elseif CLIENT and game.SinglePlayer() then
|
|
net.Receive("Zipline_SPFix", function()
|
|
local ply = LocalPlayer()
|
|
local zipline = ply:GetZipline()
|
|
|
|
if not IsValid(zipline) then return end
|
|
|
|
local startpos = zipline:GetStartPos()
|
|
local endpos = zipline:GetEndPos()
|
|
|
|
if net.ReadBool() then
|
|
local startp = startpos
|
|
startpos = endpos
|
|
endpos = startp
|
|
end
|
|
|
|
ply.OrigEyeAng = (endpos - startpos):Angle()
|
|
end)
|
|
end
|
|
|
|
local function ZiplineCheck(ply, mv, cmd, zipline)
|
|
local startpos = zipline:GetStartPos()
|
|
local endpos = zipline:GetEndPos()
|
|
|
|
if zipline:GetTwoWay() and cmd:GetViewAngles():Forward():Dot((endpos - startpos):Angle():Forward()) < 0.5 then
|
|
local startp = startpos
|
|
startpos = endpos
|
|
endpos = startp
|
|
|
|
ply.ZiplineTwoWay = true
|
|
else
|
|
ply.ZiplineTwoWay = false
|
|
end
|
|
|
|
local _, near = util.DistanceToLine(startpos, endpos, mv:GetOrigin())
|
|
local neardist = near:Distance(endpos)
|
|
local totaldist = startpos:Distance(endpos)
|
|
local start = math.abs(neardist / totaldist - 1)
|
|
|
|
if start < 1 then
|
|
local tr = ply.ZiplineTrace
|
|
local trout = ply.ZiplineTraceOut
|
|
local omins = tr.mins
|
|
local omaxs = tr.maxs
|
|
|
|
tr.start = LerpVector(start, startpos, endpos)
|
|
tr.endpos = tr.start
|
|
tr.mins, tr.maxs = ply:GetHull()
|
|
|
|
util.TraceHull(tr)
|
|
|
|
if trout.Hit and trout.Entity ~= zipline then
|
|
local div = startpos:Distance(endpos)
|
|
local fail = true
|
|
|
|
for _ = 1, 32 do
|
|
start = start + 25 / div
|
|
tr.start = LerpVector(start, startpos, endpos)
|
|
tr.endpos = tr.start
|
|
util.TraceHull(tr)
|
|
|
|
if not trout.Hit or trout.Entity == zipline and start < 1 then
|
|
fail = false
|
|
break
|
|
end
|
|
end
|
|
|
|
if fail then
|
|
tr.maxs = omaxs
|
|
tr.mins = omins
|
|
|
|
ply:SetZiplineDelay(CurTime() + 0.1)
|
|
|
|
return
|
|
end
|
|
end
|
|
|
|
tr.maxs = omaxs
|
|
tr.mins = omins
|
|
|
|
local origin = mv:GetOrigin()
|
|
|
|
if CLIENT then
|
|
BodyAnimSetEase(origin)
|
|
elseif game.SinglePlayer() then
|
|
ply:SetNW2Vector("SPBAEase", origin)
|
|
ply:SendLua("BodyAnimSetEase(LocalPlayer():GetNW2Vector('SPBAEase'))")
|
|
end
|
|
|
|
mv:SetOrigin(near)
|
|
ply:SetJumpTurn(false)
|
|
ply:SetZipline(zipline)
|
|
ply:SetZiplineStart(start)
|
|
ply:SetZiplineFraction(start)
|
|
ply:SetDive(false)
|
|
ply:SetCrouchJump(false)
|
|
ply:SetWallrunCount(0)
|
|
|
|
local vel = mv:GetVelocity()
|
|
vel.z = 0
|
|
|
|
ply:SetZiplineSpeed(math.min(vel:Length(), 750))
|
|
ply:SetCrouchJumpBlocked(false)
|
|
|
|
if CLIENT and IsFirstTimePredicted() then
|
|
ply.OrigEyeAng = (endpos - startpos):Angle()
|
|
elseif game.SinglePlayer() then
|
|
net.Start("Zipline_SPFix")
|
|
net.WriteBool(ply.ZiplineTwoWay)
|
|
net.Send(ply)
|
|
end
|
|
|
|
if CLIENT and IsFirstTimePredicted() or game.SinglePlayer() then
|
|
ply:EmitSound("ZiplineLoop")
|
|
ply:EmitSound("ZiplineStart")
|
|
end
|
|
|
|
ParkourEvent("ziplinestart", ply)
|
|
end
|
|
end
|
|
|
|
-- local zipvec = Vector(0, 0, 85)
|
|
|
|
local function ZiplineThink(ply, mv, cmd, zipline)
|
|
local fraction = ply:GetZiplineFraction()
|
|
local speed = ply:GetZiplineSpeed()
|
|
local startpos = zipline:GetStartPos()
|
|
local endpos = zipline:GetEndPos()
|
|
local dir = (endpos - startpos):Angle():Forward()
|
|
|
|
if zipline:GetTwoWay() and ply.ZiplineTwoWay then
|
|
local startp = startpos
|
|
startpos = endpos
|
|
endpos = startp
|
|
|
|
dir:Mul(-1)
|
|
end
|
|
|
|
if fraction >= 1 or cmd:KeyDown(IN_DUCK) then
|
|
ply:SetZipline(nil)
|
|
ply:SetMoveType(MOVETYPE_WALK)
|
|
|
|
mv:SetVelocity(dir * speed * 0.75)
|
|
|
|
ply:SetZiplineDelay(CurTime() + 0.75)
|
|
|
|
if CLIENT and IsFirstTimePredicted() or game.SinglePlayer() then
|
|
ply:EmitSound("ZiplineEnd")
|
|
ply:StopSound("ZiplineLoop")
|
|
|
|
if game.SinglePlayer() then
|
|
ply:SendLua("viewtiltlerp.z = BodyAnimEyeAng.z")
|
|
else
|
|
viewtiltlerp.z = BodyAnimEyeAng.z
|
|
end
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
local newfraction = math.Approach(fraction, 1, FrameTime() * speed / startpos:Distance(endpos))
|
|
|
|
ply:SetZiplineFraction(newfraction)
|
|
|
|
local ziplerp = LerpVector(newfraction, startpos, endpos)
|
|
ziplerp:Sub(zipline:GetUp() * 75)
|
|
|
|
local tr = ply.ZiplineTrace
|
|
local trout = ply.ZiplineTraceOut
|
|
local omins = tr.mins
|
|
local omaxs = tr.maxs
|
|
|
|
tr.start = ziplerp
|
|
tr.endpos = ziplerp
|
|
tr.mins, tr.maxs = ply:GetHull()
|
|
|
|
util.TraceHull(tr)
|
|
|
|
if trout.Hit and trout.Entity ~= zipline and newfraction > 0.1 then
|
|
ply:SetZipline(nil)
|
|
ply:SetMoveType(MOVETYPE_WALK)
|
|
|
|
mv:SetVelocity(dir * speed * 0.75)
|
|
|
|
ply:SetZiplineDelay(CurTime() + 0.75)
|
|
|
|
if CLIENT and IsFirstTimePredicted() or game.SinglePlayer() then
|
|
ply:EmitSound("ZiplineEnd")
|
|
ply:StopSound("ZiplineLoop")
|
|
|
|
if game.SinglePlayer() then
|
|
ply:SendLua("viewtiltlerp.z = BodyAnimEyeAng.z")
|
|
else
|
|
viewtiltlerp.z = BodyAnimEyeAng.z
|
|
end
|
|
end
|
|
|
|
tr.maxs = omaxs
|
|
tr.mins = omins
|
|
|
|
return
|
|
end
|
|
|
|
tr.maxs = omaxs
|
|
tr.mins = omins
|
|
|
|
mv:SetOrigin(ziplerp)
|
|
|
|
ply:SetZiplineSpeed(math.Approach(speed, 750, FrameTime() * 250))
|
|
|
|
mv:SetVelocity(dir * speed)
|
|
mv:SetButtons(0)
|
|
mv:SetForwardSpeed(0)
|
|
mv:SetSideSpeed(0)
|
|
mv:SetUpSpeed(0)
|
|
end
|
|
|
|
local function Zipline(ply, mv, cmd)
|
|
if not ply.ZiplineTrace then
|
|
ply.ZiplineTrace = {}
|
|
ply.ZiplineTraceOut = {}
|
|
|
|
local tr = ply.ZiplineTrace
|
|
local mins, maxs = ply:GetHull()
|
|
|
|
mins.z = maxs.z * 0.8
|
|
maxs.z = maxs.z * 2
|
|
mins:Mul(2)
|
|
maxs:Mul(2)
|
|
mins.z = mins.z * 0.5
|
|
maxs.z = maxs.z * 0.5
|
|
|
|
tr.maxs = maxs
|
|
tr.mins = mins
|
|
ply.ZiplineTrace.mask = MASK_PLAYERSOLID
|
|
ply.ZiplineTrace.collisiongroup = COLLISION_GROUP_PLAYER_MOVEMENT
|
|
end
|
|
|
|
if not IsValid(ply:GetZipline()) and not ply:GetGrappling() and (not ply:Crouching() or ply:GetDive()) and not ply:OnGround() and ply:GetZiplineDelay() < CurTime() then
|
|
local tr = ply.ZiplineTrace
|
|
local trout = ply.ZiplineTraceOut
|
|
|
|
tr.output = trout
|
|
tr.start = mv:GetOrigin()
|
|
tr.endpos = tr.start
|
|
tr.filter = ply
|
|
|
|
util.TraceHull(tr)
|
|
local trentity = trout.Entity
|
|
|
|
if IsValid(trentity) and trentity:GetClass() == "br_zipline" and ply:GetMoveType() == MOVETYPE_WALK then
|
|
ZiplineCheck(ply, mv, cmd, trentity)
|
|
end
|
|
end
|
|
|
|
if IsValid(ply:GetZipline()) then
|
|
ZiplineThink(ply, mv, cmd, ply:GetZipline())
|
|
end
|
|
end
|
|
|
|
hook.Add("SetupMove", "Zipline", Zipline)
|
|
|
|
function CreateZipline(startpos, endpos)
|
|
if startpos and endpos then
|
|
local zipline = ents.Create("br_zipline")
|
|
|
|
zipline:SetStartPos(startpos)
|
|
zipline:SetEndPos(endpos)
|
|
zipline:Spawn()
|
|
|
|
return zipline
|
|
end
|
|
end
|
|
|
|
if CLIENT then
|
|
hook.Add("Think", "ZiplineSoundFix", function()
|
|
if not IsValid(LocalPlayer():GetZipline()) then
|
|
LocalPlayer():StopSound("ZiplineLoop")
|
|
end
|
|
end)
|
|
end
|