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