Files
2026-03-31 10:27:04 +03:00

357 lines
14 KiB
Lua

local customizedelta = 0
local sightdelta = 0
local sprintdelta = 0
local peekdelta = 0
local bipoddelta = 0
local blindfiredelta, blindfiredeltaleft, blindfiredeltaright, blindfiredeltakys = 0, 0, 0, 0
local freeaim_p, freeaim_y = 0, 0
local nearwalldelta = 0
local angle_zero = Angle(0, 0, 0)
local vector_origin = Vector(0, 0, 0)
local peekvector = Vector(0, 0, -2)
local m_appor = math.Approach
local f_lerp = function(dlt, from, to) return from + (to - from) * dlt end
local function ApproachMod(usrobj, to, dlt)
usrobj[1] = m_appor(usrobj[1], to[1], dlt)
usrobj[2] = m_appor(usrobj[2], to[2], dlt)
usrobj[3] = m_appor(usrobj[3], to[3], dlt)
end
local function LerpMod(usrobj, to, dlt, clamp_ang)
usrobj[1] = f_lerp(dlt, usrobj[1], to[1])
usrobj[2] = f_lerp(dlt, usrobj[2], to[2])
usrobj[3] = f_lerp(dlt, usrobj[3], to[3])
if clamp_ang then
for i = 1, 3 do usrobj[i] = math.NormalizeAngle(usrobj[i]) end
end
end
SWEP.BenchPos = SWEP.BenchPos or Vector(0, 0, 0)
SWEP.BenchAng = SWEP.BenchAng or Angle(0, 0, 0)
SWEP.ViewModelPos = Vector(0, 0, 0)
SWEP.ViewModelAng = Angle(0, 0, 0)
function SWEP:GetViewModelPosition(pos, ang)
if !IsValid(self:GetOwner()) then
return Vector(0, 0, 0), Angle(0, 0, 0)
end
if TacRP.ConVars["dev_benchgun"]:GetBool() then
return self.BenchPos, self.BenchAng
end
self.BenchPos = pos
self.BenchAng = ang
local vm = self:GetOwner():GetViewModel()
local FT = self:DeltaSysTime() -- FrameTime()
local RFT = RealFrameTime()
ang = ang - (self:GetOwner():GetViewPunchAngles() * 0.5)
local oldang = Angle(0, 0, 0)
oldang:Set(ang)
local offsetpos = Vector(self.PassivePos)
local offsetang = Angle(self.PassiveAng)
local extra_offsetpos = Vector(0, 0, 0)
local extra_offsetang = Angle(0, 0, 0)
-- local cor_val = (self.ViewModelFOV / self:GetShouldFOV())
local cor_val = 0.75
---------------------------------------------
-- Blindfire
---------------------------------------------
local bfmode = self:GetBlindFireMode()
local bfl = bfmode == TacRP.BLINDFIRE_LEFT
local bfr = bfmode == TacRP.BLINDFIRE_RIGHT
local bfs = bfmode == TacRP.BLINDFIRE_KYS
blindfiredelta = math.Approach(blindfiredelta, self:GetBlindFire() and 1 or 0, FT / 0.3)
blindfiredeltaleft = math.Approach(blindfiredeltaleft, bfl and 1 or 0, FT / (bfr and 0.45 or 0.3))
blindfiredeltaright = math.Approach(blindfiredeltaright, bfr and 1 or 0, FT / (bfl and 0.45 or 0.3))
blindfiredeltakys = math.Approach(blindfiredeltakys, bfs and 1 or 0, FT / (bfs and 0.75 or 0.3))
if blindfiredelta > 0 then
local curvedblindfiredelta = self:Curve(blindfiredelta)
local curvedblindfiredeltaleft = self:Curve(blindfiredeltaleft)
local curvedblindfiredeltaright = self:Curve(blindfiredeltaright)
local curvedblindfiredeltakys = self:Curve(blindfiredeltakys)
offsetpos = LerpVector(curvedblindfiredelta, offsetpos, self:GetValue("BlindFirePos"))
offsetang = LerpAngle(curvedblindfiredelta, offsetang, self:GetValue("BlindFireAng"))
if curvedblindfiredeltaleft > 0 then
offsetpos = LerpVector(curvedblindfiredeltaleft, offsetpos, self:GetValue("BlindFireLeftPos"))
offsetang = LerpAngle(curvedblindfiredeltaleft, offsetang, self:GetValue("BlindFireLeftAng"))
end
if curvedblindfiredeltaright > 0 then
offsetpos = LerpVector(curvedblindfiredeltaright, offsetpos, self:GetValue("BlindFireRightPos"))
offsetang = LerpAngle(curvedblindfiredeltaright, offsetang, self:GetValue("BlindFireRightAng"))
end
if curvedblindfiredeltakys > 0 then
offsetpos = LerpVector(curvedblindfiredeltakys, offsetpos, self:GetValue("BlindFireSuicidePos"))
offsetang = LerpAngle(curvedblindfiredeltakys, offsetang, self:GetValue("BlindFireSuicideAng"))
end
end
---------------------------------------------
-- Aiming & Peeking
---------------------------------------------
local ads = self:GetAimDownSightsTime()
if self:GetScopeLevel() > 0 then
if self:GetSprintLockTime() > CurTime() then
ads = ads + self:GetSprintToFireTime()
end
sightdelta = m_appor(sightdelta, 1, FT / ads)
else
sightdelta = m_appor(sightdelta, 0, FT / ads)
end
-- if IsFirstTimePredicted() or game.SinglePlayer() then
if self:GetPeeking() then
peekdelta = m_appor(peekdelta, 1, FT / 0.2)
else
peekdelta = m_appor(peekdelta, 0, FT / 0.2)
end
-- end
local curvedsightdelta = self:Curve(sightdelta)
local curvedpeekdelta = self:Curve(peekdelta)
-- cor_val = Lerp(sightdelta, cor_val, 1)
local ppos = Vector(self:GetValue("PeekPos")) * curvedpeekdelta
local pang = Angle(self:GetValue("PeekAng")) * curvedpeekdelta
if sightdelta > 0 then
local sightpos, sightang = self:GetSightPositions()
if self:DoLowerIrons() then
sightpos = sightpos + LerpVector(curvedpeekdelta, peekvector, vector_origin)
end
LerpMod(offsetpos, sightpos + ppos, curvedsightdelta)
LerpMod(offsetang, sightang + pang, curvedsightdelta, true)
local eepos, eeang = self:GetExtraSightPosition()
local im = self:GetValue("SightMidPoint")
local midpoint = curvedsightdelta * math.cos(curvedsightdelta * (math.pi / 2)) * (1 - curvedpeekdelta)
local joffset = (im and im.Pos or Vector(0, 0, 0) + ppos) * midpoint
local jaffset = (im and im.Ang or Angle(0, 0, 0) + pang) * midpoint
LerpMod(extra_offsetpos, -eepos + joffset, curvedsightdelta)
LerpMod(extra_offsetang, -eeang + jaffset, curvedsightdelta)
end
---------------------------------------------
-- Bipod
---------------------------------------------
local amt = math.Clamp(self:GetBipodPos():Distance(self:GetOwner():EyePos()) / 60, 0.15, 0.3)
bipoddelta = math.Approach(bipoddelta, self:GetInBipod() and 1 or 0, FT / (self:GetInBipod() and 0.4 or amt))
if bipoddelta > 0 then
local curvedbipoddelta = self:Curve(bipoddelta)
pos = LerpVector(math.Clamp(curvedbipoddelta - curvedsightdelta, 0, 1), pos, self:GetBipodPos())
end
---------------------------------------------
-- Procedural Firing
---------------------------------------------
local procdata = self:GetValue("ProceduralIronFire")
if IsValid(vm) and procdata then
local dt = math.max(0, UnPredictedCurTime() - self:GetLastProceduralFireTime() + self:GetPingOffsetScale())
if dt <= procdata.tmax then
self.ProceduralIronCleanup = false
if !(self:GetValue("LastShot") and self:Clip1() == 0) then
for k, v in pairs(procdata.bones or {}) do
local bone = vm:LookupBone(v.bone or "")
if !bone then continue end
local f = 1
if v.t0 == 0 then
f = v.t1 and math.Clamp(1 - dt / v.t1, 0, 1) or 0
else
f = v.t1 and (dt > v.t0 and math.Clamp(1 - (dt - v.t0) / (v.t1 - v.t0), 0, 1) or (dt / v.t0)) or (dt > v.t0 and 1 or (dt / v.t0))
end
if v.pos then
local offset = LerpVector(f, vector_origin, v.pos)
vm:ManipulateBonePosition(bone, offset, false)
end
if v.ang then
local offset = LerpAngle(f, angle_zero, v.ang)
vm:ManipulateBoneAngles(bone, offset, false)
end
end
end
local dtc = math.ease.InQuad(math.Clamp(1 - dt / procdata.t, 0, 1))
if dtc > 0 and procdata.vm_pos then
LerpMod(offsetpos, offsetpos + procdata.vm_pos, dtc)
end
if dtc > 0 and procdata.vm_ang then
LerpMod(offsetang, offsetang + procdata.vm_ang, dtc, true)
end
elseif !self.ProceduralIronCleanup then
self.ProceduralIronCleanup = true
for k, v in pairs(procdata.bones or {}) do
local bone = vm:LookupBone(v.bone or "")
if !bone then continue end
if v.pos then
vm:ManipulateBonePosition(bone, vector_origin, false)
end
if v.ang then
vm:ManipulateBoneAngles(bone, angle_zero, false)
end
end
end
end
---------------------------------------------
-- Free Aim & Sway
---------------------------------------------
local swayang = self:GetSwayAngles()
extra_offsetang.y = extra_offsetang.y - (swayang.p * cor_val)
extra_offsetang.p = extra_offsetang.p + (swayang.y * cor_val)
local idlesway = Lerp(self:GetSightDelta(), 1 / 3, 0)
extra_offsetpos.x = extra_offsetpos.x + (swayang.y * cor_val * idlesway)
extra_offsetpos.z = extra_offsetpos.z + (swayang.p * cor_val * idlesway)
local freeaimang = self:GetFreeAimOffset()
freeaim_p = f_lerp(0.5, freeaim_p, freeaimang.p)
freeaim_y = f_lerp(0.5, freeaim_y, freeaimang.y)
freeaim_p = m_appor(freeaim_p, freeaimang.p, FT)
freeaim_y = m_appor(freeaim_y, freeaimang.y, FT)
extra_offsetang.y = extra_offsetang.y - (freeaim_p * cor_val)
extra_offsetang.p = extra_offsetang.p + (freeaim_y * cor_val)
---------------------------------------------
-- Customization
---------------------------------------------
-- if IsFirstTimePredicted() or game.SinglePlayer() then
if self:GetCustomize() then
customizedelta = m_appor(customizedelta, 1, RealFrameTime() * 1 / 0.15)
else
customizedelta = m_appor(customizedelta, 0, RealFrameTime() * 1 / 0.15)
end
-- end
if customizedelta > 0 then
local curvedcustomizedelta = self:Curve(customizedelta)
LerpMod(offsetpos, self:GetValue("CustomizePos"), curvedcustomizedelta)
LerpMod(offsetang, self:GetValue("CustomizeAng"), curvedcustomizedelta)
LerpMod(extra_offsetang, angle_zero, curvedcustomizedelta, true)
end
---------------------------------------------
-- Sprinting
---------------------------------------------
local stf = self:GetSprintToFireTime()
if self:GetCustomize() or self:GetInBipod() or (!self:GetSafe() and !self.LastWasSprinting and !self:ShouldLowerWeapon()) then
-- not accurate to how sprint progress works but looks much smoother
if self:GetScopeLevel() > 0 and self:GetSprintLockTime() > UnPredictedCurTime() then
stf = stf + self:GetAimDownSightsTime() * 0.5
end
sprintdelta = m_appor(sprintdelta, 0, FT / stf)
self.LastReloadEnd = nil
elseif self:GetReloading() then
if (self.LastWasSprinting or self:ShouldLowerWeapon()) and self:GetEndReload() then
self.LastReloadEnd = self.LastReloadEnd or (self:GetReloadFinishTime() - UnPredictedCurTime())
sprintdelta = 1 - self:Curve((self:GetReloadFinishTime() - UnPredictedCurTime()) / self.LastReloadEnd)
else
sprintdelta = m_appor(sprintdelta, 0, FT / 0.5)
end
else
if self:GetLastMeleeTime() + 0.5 > CurTime() or self:GetStartPrimedGrenadeTime() + 0.8 > CurTime() then
sprintdelta = m_appor(sprintdelta, 0, FT / 0.2)
else
sprintdelta = m_appor(sprintdelta, 1, FT / stf)
end
self.LastReloadEnd = nil
end
local curvedsprintdelta = self:Curve(sprintdelta)
if curvedsprintdelta > 0 then
LerpMod(offsetpos, self:GetValue("SprintPos"), curvedsprintdelta)
LerpMod(offsetang, self:GetValue("SprintAng"), curvedsprintdelta)
LerpMod(extra_offsetang, angle_zero, curvedsprintdelta, true)
local sim = self:GetValue("SprintMidPoint")
local spr_midpoint = curvedsprintdelta * math.cos(curvedsprintdelta * (math.pi / 2))
local spr_joffset = (sim and sim.Pos or Vector(0, 0, 0)) * spr_midpoint
local spr_jaffset = (sim and sim.Ang or Angle(0, 0, 0)) * spr_midpoint
extra_offsetpos:Add(spr_joffset)
extra_offsetang:Add(spr_jaffset)
end
---------------------------------------------
-- Near Walling
---------------------------------------------
nearwalldelta = m_appor(nearwalldelta, self:GetNearWallAmount(), FT / 0.3)
local curvednearwalldelta = self:Curve(nearwalldelta) - customizedelta - sightdelta
if curvednearwalldelta > 0 then
local sprpos = LerpVector(curvednearwalldelta, vector_origin, self:GetValue("NearWallPos"))
local sprang = LerpAngle(curvednearwalldelta, angle_zero, self:GetValue("NearWallAng"))
local pointdir = self:GetOwner():WorldToLocalAngles(self:GetShootDir())
extra_offsetpos:Add(pointdir:Right() * sprpos[2])
extra_offsetpos:Add(pointdir:Forward() * sprpos[1])
extra_offsetpos:Add(pointdir:Up() * sprpos[3])
extra_offsetang:Add(sprang)
end
self.SwayScale = f_lerp(sightdelta, 1, 0.1)
self.BobScale = 0
local speed = 15 * FT * (game.SinglePlayer() and 1 or 2)
LerpMod(self.ViewModelPos, offsetpos, speed)
LerpMod(self.ViewModelAng, offsetang, speed, true)
ApproachMod(self.ViewModelPos, offsetpos, speed * 0.1)
ApproachMod(self.ViewModelAng, offsetang, speed * 0.1)
self.ViewModelAng:Normalize()
pos = pos + (ang:Right() * offsetpos[1])
pos = pos + (ang:Forward() * offsetpos[2])
pos = pos + (ang:Up() * offsetpos[3])
ang:RotateAroundAxis(ang:Up(), offsetang[1])
ang:RotateAroundAxis(ang:Right(), offsetang[2])
ang:RotateAroundAxis(ang:Forward(), offsetang[3])
pos = pos + (oldang:Right() * extra_offsetpos[1])
pos = pos + (oldang:Forward() * extra_offsetpos[2])
pos = pos + (oldang:Up() * extra_offsetpos[3])
ang:RotateAroundAxis(oldang:Up(), extra_offsetang[1])
ang:RotateAroundAxis(oldang:Right(), extra_offsetang[2])
ang:RotateAroundAxis(oldang:Forward(), extra_offsetang[3])
pos, ang = self:GetViewModelBob(pos, ang)
pos, ang = self:GetViewModelSway(pos, ang)
self.ViewModelPos = pos
self.ViewModelAng = ang
self.LastSysTime = SysTime()
return pos, ang
end
function SWEP:TranslateFOV(fov)
return fov
end