Залив

This commit is contained in:
Refosel
2026-03-30 10:39:52 +03:00
commit 2b57c019cb
2010 changed files with 185745 additions and 0 deletions

View File

@@ -0,0 +1,275 @@
require("mw_math")
ENT.m_AimDeltaLerp = 0
ENT.m_LocomotionDeltaLerp = 0
ENT.m_CustomizationRateLerp = 0
ENT.m_bMoveStopped = true
ENT.m_bMoveStarted = false
ENT.m_bOnGround = true
ENT.m_LeftHandGripPoseParameter = nil
ENT.m_LeftHandGripTarget = 0
ENT.m_LeftHandGripLerp = 0
ENT.m_RightHandGripPoseParameter = nil
ENT.m_RightHandGripTarget = 0
ENT.m_RightHandGripLerp = 0
ENT.m_LastSprayRounds = 0
local idleIndices = {
["Idle"] = true,
["Jump"] = true,
["Jog_Out"] = true,
["Land"] = true
}
local uncancellableIndices = {
["Sprint_In"] = true,
["Holster"] = true
}
local allowAim = {
["Ads_In"] = true,
["Fire_Last"] = true,
["Fire"] = true
}
local function playIdleAnimation(vm, seqIndex)
local ind = vm.m_LastSequenceIndex
if ((idleIndices[ind] || (!uncancellableIndices[ind] && vm:GetCycle() >= 0.98)) && (allowAim[ind] != nil || vm:GetOwner():GetAimDelta() <= 0)) then
vm:PlayAnimation(seqIndex, true)
end
end
local function locomotion(vm)
local w = vm:GetOwner()
local p = w:GetOwner()
if (!IsValid(p) || !p:IsPlayer()) then
return
end
local vel = p:GetVelocity()
vel = Vector(vel.x, vel.y, 0)
local len = math.max(vel:Length(), 0.01)
if (!p:IsOnGround() || (p.GetSliding != nil && p:GetSliding())) then
vm.m_LocomotionDeltaLerp = mw_math.SafeLerp(6 * RealFrameTime(), vm.m_LocomotionDeltaLerp, 0)
else
vm.m_LocomotionDeltaLerp = mw_math.SafeLerp(4 * RealFrameTime(), vm.m_LocomotionDeltaLerp, len / p:GetWalkSpeed())
end
--jogging and walking
local slowWalkPoint = p:GetSlowWalkSpeed() / p:GetWalkSpeed()
local slowWalkDelta = 1 - math.abs(slowWalkPoint - vm.m_LocomotionDeltaLerp) / slowWalkPoint
local jogDelta = vm.m_LocomotionDeltaLerp - slowWalkDelta
--when we stop jogging
if (jogDelta <= 0.5 && !vm.m_bMoveStopped) then
if (p:IsOnGround()) then
playIdleAnimation(vm, "Jog_Out")
end
vm.m_bMoveStopped = true
elseif (jogDelta > 0.5) then
vm.m_bMoveStopped = false
end
--when we start moving
if (vm.m_LocomotionDeltaLerp > 0.1 && !vm.m_bMoveStarted) then
if (p:IsOnGround()) then
playIdleAnimation(vm, "Land")
end
vm.m_bMoveStarted = true
elseif (vm.m_LocomotionDeltaLerp <= 0.1) then
vm.m_bMoveStarted = false
end
vm:SetPoseParameter("jog_loop", jogDelta * Lerp(vm.m_AimDeltaLerp, 1, 0.1 * (w.Zoom.MovementMultiplier || 1)))
vm:SetPoseParameter("walk_loop", slowWalkDelta * Lerp(vm.m_AimDeltaLerp, 1, 0.2 * (w.Zoom.PoseParameterMultiplier || 1)))
--freefall loop
local z = math.min(p:GetVelocity().z, 0)
local delta = math.min(math.min(z + 500, 0) / -1100, 1)
vm:SetPoseParameter("freefall_loop", delta * Lerp(vm.m_AimDeltaLerp, 1, 0.1))
--jumping and landing
if (vm.m_bOnGround != p:IsOnGround()) then
if (!p:IsOnGround()) then
playIdleAnimation(vm, "Jump")
else
playIdleAnimation(vm, "Land")
end
vm.m_bOnGround = p:IsOnGround()
end
--sprint
local sprintPoint = p:GetRunSpeed() / p:GetWalkSpeed()
local sprintDelta = (vm.m_LocomotionDeltaLerp - 1) / (sprintPoint - 1)
vm:SetPoseParameter("sprint_loop", math.min(sprintDelta, math.Clamp((CurTime() - w:GetNextReloadTime()) * 10, 0, 1)) * Lerp(vm.m_AimDeltaLerp, 1, 0.1))
-- not so efficient but very effective sprinting reload bodge
--the offset when moving in general
local offsetDelta = mw_math.CosineInterp(vm.m_LocomotionDeltaLerp * math.Clamp(1 - sprintDelta, 0, 1), 0, 1)
offsetDelta = offsetDelta * (1 - math.Clamp(vm.m_AimDeltaLerp * 2, 0, 1))
vm:SetPoseParameter("jog_offset", offsetDelta)
--after fire reshoulder
if (vm.m_LastSprayRounds != w:GetSprayRounds() && !w:HasFlag("BipodDeployed")) then
if (w:GetSprayRounds() == 0 && vm.m_LastSprayRounds >= 5) then
if (!string.find(string.lower(vm.m_LastSequenceIndex), "fire")) then
local anim = math.random(1, 2) == 1 && "Land" || "Jog_Out"
if (w.Animations.SprayEnd != nil) then
anim = "SprayEnd"
end
playIdleAnimation(vm, anim)
vm.m_LastSprayRounds = w:GetSprayRounds()
end
else
vm.m_LastSprayRounds = w:GetSprayRounds()
end
end
end
ENT.m_InspectSpeed = 1
local function inspection(vm)
local w = vm:GetOwner()
local randomness = math.sin(CurTime() * 2) * 0.05 + math.sin(CurTime() * 3) * 0.05
local inspectDelta = w.FreezeInspectDelta || 0.15
if (w:Clip1() <= 0 && w.EmptyFreezeInspectDelta) then
inspectDelta = w.EmptyFreezeInspectDelta
end
local bStop = w:HasFlag("StoppedInspectAnimation") || (w:HasFlag("Customizing") && vm:GetCycle() > inspectDelta)
vm.m_InspectSpeed = mw_math.SafeLerp(5 * RealFrameTime(), vm.m_InspectSpeed, Lerp(mw_math.btn(bStop), 1, randomness))
if (string.find(string.lower(vm.m_LastSequenceIndex), "inspect")) then
vm:SetPlaybackRate(vm.m_InspectSpeed)
end
end
local function grips(vm)
local w = vm:GetOwner()
if (w.GripPoseParameters != nil) then
for i, pp in pairs(w.GripPoseParameters) do
vm:SetPoseParameter(pp, 0)
end
vm.m_LeftHandGripLerp = math.Approach(vm.m_LeftHandGripLerp, vm.m_LeftHandGripTarget, 10 * RealFrameTime())
if (vm.m_LeftHandGripPoseParameter != nil) then
vm:SetPoseParameter(vm.m_LeftHandGripPoseParameter, vm.m_LeftHandGripLerp)
end
end
if (w.GripPoseParameters2 != nil) then
for i, pp in pairs(w.GripPoseParameters2) do
vm:SetPoseParameter(pp, 0)
end
vm.m_RightHandGripLerp = math.Approach(vm.m_RightHandGripLerp, vm.m_RightHandGripTarget, 10 * RealFrameTime())
if (vm.m_RightHandGripPoseParameter != nil) then
vm:SetPoseParameter(vm.m_RightHandGripPoseParameter, vm.m_RightHandGripLerp)
end
end
end
function ENT:SetPoseParameters()
local w = self:GetOwner()
self:SetPoseParameter("aim_offset", self.m_AimDeltaLerp)
self:SetPoseParameter("hybrid_offset", w:GetAimMode())
self:SetPoseParameter("firemode_offset", w:GetFiremode() - 1)
self:SetPoseParameter("empty_offset", mw_math.btn(w:Clip1() <= 0 || !w:HasFlag("Rechambered")))
self:SetPoseParameter("bipod", mw_math.btn(w:HasFlag("BipodDeployed")))
end
ENT.m_UpdateDelta = 0
function ENT:Think()
local w = self:GetOwner()
if (!IsValid(w)) then
return
end
self:ReconcileServerAnims()
if (!w:IsCarriedByLocalPlayer() || !IsValid(w:GetOwner()) || w != w:GetOwner():GetActiveWeapon()) then
return
end
if (self.m_UpdateDelta <= 0.2) then
self:UpdateAnimation(self.m_LastSequenceIndex)
self.m_UpdateDelta = self.m_UpdateDelta + FrameTime()
--WAKE UP GODDAMN IT
end
if (self.m_LastSequenceIndex != "INIT") then
self.m_AimDeltaLerp = mw_math.SafeLerp(30 * RealFrameTime(), self.m_AimDeltaLerp, w:GetAimDelta())
self:SetPoseParameters()
--we play idle a bit earlier if ads in
local targetCycle = self.m_LastSequenceIndex == "Ads_In" && 0.5 || 0.98
if (self:GetCycle() >= targetCycle) then
playIdleAnimation(self, "Idle")
end
--states
locomotion(self)
inspection(self)
grips(self)
end
end
function ENT:ReconcileServerAnims()
if (self.m_AnimFromServer == nil) then
return
end
local tick = self.m_AnimFromServer.Tick
local animId = self.m_AnimFromServer.AnimID
local rate = self.m_AnimFromServer.Rate
local timeDifference = self.m_AnimFromServer.TimeDifference
self.m_AnimFromServer = nil
local seqIndex = self:GetSequenceIndexByID(animId)
if (tick < self.m_Tick || (tick == self.m_Tick && self.m_LastSequenceIndex == seqIndex)) then
return
end
local sequences = self:GetOwner().Animations[seqIndex].Sequences
local seqId = self:LookupSequence(sequences[1])
local length = self:SequenceDuration(seqId)
local cycle = timeDifference / length
cycle = cycle * rate
self:PlaySequence(sequences[math.random(1, #sequences)], rate, cycle)
self.m_LastSequenceIndex = seqIndex
self.m_Tick = tick
end
function ENT:VManipPostPlayAnim(name)
playIdleAnimation(self, "Jog_Out")
end
function ENT:VManipHoldQuit()
playIdleAnimation(self, "Land")
end
function ENT:VManipRemove()
playIdleAnimation(self, "Jog_Out")
end

View File

@@ -0,0 +1,461 @@
require("mw_math")
require("mw_utils")
ENT.m_AimDelta = 0
ENT.m_AimModeDelta = 0
ENT.m_CameraAttachment = nil
function ENT:CalcView(origin, angles)
if (self:GetRenderOrigin() == nil) then
return
end
--local camera = self:GetAttachment(mw_utils.LookupAttachmentCached(self, "camera"))
if (self.m_CameraAttachment == nil) then
return
end
local camera = self.m_CameraAttachment
local cameraPos, cameraAng = camera:GetTranslation(), camera:GetAngles()
angles:RotateAroundAxis(angles:Forward(), cameraAng.r)
angles:RotateAroundAxis(angles:Up(), -cameraAng.y)
angles:RotateAroundAxis(angles:Right(), cameraAng.p)
mw_math.VectorAddAndMul(origin, angles:Forward(), -cameraPos.x)
mw_math.VectorAddAndMul(origin, angles:Up(), -cameraPos.z)
mw_math.VectorAddAndMul(origin, angles:Right(), cameraPos.y)
end
ENT.m_Movement = {
p = mw_math.CreateSpring(150, 0.75),
x = mw_math.CreateSpring(80, 1),
y = mw_math.CreateSpring(100, 1)
}
ENT.m_LastZVel = 0
ENT.m_LandTarget = 0
local function movementInertia(vm, pos, ang)
local w = vm:GetWeaponOwner()
local p = vm:GetPlayerOwner()
if (!IsValid(vm:GetPlayerOwner())) then
return
end
local vel = p:GetVelocity()
--vertical
if (!p:IsOnGround()) then
vm.m_LastZVel = vel.z
vm.m_LandTarget = 0
else
if (vm.m_LastZVel != 0) then
vm.m_LandTarget = -math.Clamp(vm.m_LastZVel, -1000, 1000) * 0.02
vm.m_LastZVel = 0
end
vm.m_LandTarget = mw_math.SafeLerp(5 * FrameTime(), vm.m_LandTarget, 0)
end
vm.m_Movement.p:SetTarget(math.Clamp(math.Clamp(vel.z, -200, 200) * 0.025, -10, 10) + vm.m_LandTarget)
vm.m_Movement.p:Decay()
local pi = vm.m_Movement.p:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, 0.1)
ang:SetUnpacked(ang.p - pi, ang.y, ang.r)
--horizontal
vel:Div(p:GetWalkSpeed())
local dotY = 0
local dotX = 0
if (!w:HasFlag("Sprinting")) then
local movementAngles = Angle(0, p:EyeAngles().y, 0)
dotY = movementAngles:Forward():Dot(vel)
dotY = dotY * -1
dotY = math.Clamp(dotY, -2, 2)
dotX = movementAngles:Right():Dot(vel)
dotX = dotX * -1
dotX = math.Clamp(dotX, -1.25, 1.25)
end
vm.m_Movement.y:SetTarget(dotY)
vm.m_Movement.y:Decay()
vm.m_Movement.x:SetTarget(dotX)
vm.m_Movement.x:Decay()
local y = vm.m_Movement.y:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, 0.3)
local x = vm.m_Movement.x:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, 0.075)
pos:SetUnpacked(pos.x + x, pos.y + y, pos.z)
end
ENT.m_SwayAngle = nil
ENT.m_Sway = {
p = mw_math.CreateSpring(150, 0.75),
ya = mw_math.CreateSpring(120, 1),
r = mw_math.CreateSpring(60, 0.85),
x = mw_math.CreateSpring(145, 1),
y = mw_math.CreateSpring(100, 1),
z = mw_math.CreateSpring(150, 0.75)
}
local function sway(vm, pos, ang, originalAng)
if (vm.m_SwayAngle == nil) then
vm.m_SwayAngle = Angle(originalAng)
end
local diffY = math.AngleDifference(vm.m_SwayAngle.y, originalAng.y)
diffY = diffY / RealFrameTime()
diffY = diffY * 0.015
local diffP = math.AngleDifference(vm.m_SwayAngle.p, originalAng.p)
diffP = diffP / RealFrameTime()
diffP = diffP * 0.01
vm.m_Sway.p:SetTarget(diffP + diffY * mw_math.SafeLerp(vm.m_AimDelta, 0.1, 0))
vm.m_Sway.ya:SetTarget(diffY)
vm.m_Sway.r:SetTarget(diffY * 0.75)
vm.m_Sway.z:SetTarget(diffP * 0.125 + diffY * mw_math.SafeLerp(vm.m_AimDelta, 0.01, 0))
vm.m_Sway.x:SetTarget(diffY * 0.15)
vm.m_Sway.y:SetTarget(diffY * 0.1)
vm.m_Sway.p:Decay()
vm.m_Sway.ya:Decay()
vm.m_Sway.r:Decay()
vm.m_Sway.x:Decay()
vm.m_Sway.y:Decay()
vm.m_Sway.z:Decay()
vm.m_SwayAngle:Set(originalAng)
--
local p = vm.m_Sway.p:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, -0.1)
local y = vm.m_Sway.ya:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, -0.1)
local r = vm.m_Sway.r:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, -0.1)
ang:SetUnpacked(ang.p - p, ang.y + y, ang.r - r)
local x = vm.m_Sway.x:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, -0.1)
x = x - mw_math.SafeLerp(vm.m_AimDelta, r * 0.05, 0)
local y = vm.m_Sway.y:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, -0.1)
local z = vm.m_Sway.z:GetValue() * mw_math.SafeLerp(vm.m_AimDelta, 1, -0.1)
z = z - mw_math.SafeLerp(vm.m_AimDelta, r * 0.035, 0)
pos:SetUnpacked(pos.x + x, pos.y + y, pos.z + z)
end
local defaultSprintAngle = Angle(0, 0, 25)
local defaultSprintPos = Vector(1, 0, -1)
local defaultVManipAngle = Angle(0, 2, -10)
local defaultVManipPos = Vector(1.5, 3, -1.5)
local defaultCrouchAngle = Angle(0, 0, -5)
local defaultCrouchPos = Vector(-1, -0.5, -1)
local defaultBipodAngle = Angle()
local defaultBipodPos = Vector(-1.5, 0, -1.5)
ENT.m_OffsetAng = {
p = mw_math.CreateSpring(150, 0.75),
ya = mw_math.CreateSpring(120, 1),
r = mw_math.CreateSpring(100, 1.5)
}
ENT.m_OffsetPos = mw_math.CreateVectorSpring(150, 1.5)
local offsetsPos = Vector()
local offsetsAng = Angle()
local sprintAng = Angle()
local sprintPos = Vector()
local alternateAimPos = Vector()
local alternateAimAng = Angle()
local aimPos = Vector()
local aimAng = Angle()
local vManipAng = Angle()
local vManipPos = Vector()
local bipodAng = Angle()
local bipodPos = Vector()
local crouchAng = Angle()
local crouchPos = Vector()
local function offsets(vm, pos, ang)
local w = vm:GetOwner()
local p = w:GetOwner()
offsetsPos:SetUnpacked(0, 0, 0)
offsetsAng:SetUnpacked(0, 0, 0)
--aim offsets
aimPos:Set(w.ViewModelOffsets.Aim.Pos)
aimAng:Set(w.ViewModelOffsets.Aim.Angles)
if (w:GetSight() != nil) then
aimPos:Add(w:GetSight().AimPos || mw_math.ZeroVector)
aimAng:Add(w:GetSight().AimAng || mw_math.ZeroAngle)
end
aimPos:Mul(mw_math.btn(w:HasFlag("Aiming") && w:GetAimMode() == 0))
aimAng:Mul(mw_math.btn(w:HasFlag("Aiming") && w:GetAimMode() == 0))
offsetsPos:Add(aimPos)
offsetsAng:Add(aimAng)
--canted aim offsets
alternateAimPos:Set(w.ViewModelOffsets.Aim.Pos)
alternateAimAng:Set(w.ViewModelOffsets.Aim.Angles)
if (w:GetSight() != nil && w:GetSight().ReticleHybrid != nil) then
alternateAimPos:Add(w:GetSight().HybridAimPos || w.HybridAimPos || mw_math.ZeroVector)
alternateAimAng:Add(w:GetSight().HybridAimAng || w.HybridAimAngles || mw_math.ZeroAngle)
else
if (w.LaserAimPos != nil && w.LaserAimAngles != nil && w:GetLaser() != nil) then
alternateAimPos:Set(w.LaserAimPos)
alternateAimAng:Set(w.LaserAimAngles)
local reloadDelta = Lerp(mw_math.btn(CurTime() >= Lerp(0.5, w:GetNextMagTime(), w:GetNextReloadTime())), 0.5, 1)
alternateAimAng:Mul(reloadDelta)
alternateAimPos:Mul(reloadDelta)
end
end
--alternateAimPos:Mul(vm.m_AimModeDelta)
alternateAimPos:Mul(mw_math.btn(!(w.DisableCantedReload && w:HasFlag("Reloading")) && w:HasFlag("Aiming") && w:GetAimMode() > 0))
--alternateAimAng:Mul(vm.m_AimModeDelta)
alternateAimAng:Mul(mw_math.btn(!(w.DisableCantedReload && w:HasFlag("Reloading")) && w:HasFlag("Aiming") && w:GetAimMode() > 0))
offsetsPos:Add(alternateAimPos)
offsetsAng:Add(alternateAimAng)
--sprinting
sprintAng:Set(defaultSprintAngle)
sprintPos:Set(defaultSprintPos)
if (w.ViewModelOffsets.Sprint != nil) then
sprintAng:Set(w.ViewModelOffsets.Sprint.Angles || sprintAng)
sprintPos:Set(w.ViewModelOffsets.Sprint.Pos || sprintPos)
end
sprintPos:Mul(mw_math.btn(w:HasFlag("Sprinting")))
sprintAng:Mul(mw_math.btn(w:HasFlag("Sprinting")))
offsetsAng:Add(sprintAng)
offsetsPos:Add(sprintPos)
--idle
local eyePitch = Lerp(mw_math.btn(w:HasFlag("Aiming")), p:EyeAngles().p / 90, 0)
offsetsAng:Add(w.ViewModelOffsets.Idle.Angles * mw_math.btn(!w:HasFlag("Aiming")))
offsetsAng.r = offsetsAng.r + (eyePitch * 5)
offsetsPos:Add(w.ViewModelOffsets.Idle.Pos * mw_math.btn(!w:HasFlag("Aiming")))
offsetsPos.y = offsetsPos.y + eyePitch
offsetsPos.z = offsetsPos.z + (math.min(eyePitch, 0.5) * 5 * mw_math.btn(w:HasFlag("BipodDeployed")))
--vmanip
vManipAng:Set(defaultVManipAngle)
vManipPos:Set(defaultVManipPos)
if (w.ViewModelOffsets.VManip != nil) then
vManipAng:Set(w.ViewModelOffsets.VManip.Angles || vManipAng)
vManipPos:Set(w.ViewModelOffsets.VManip.Pos || vManipPos)
end
vManipPos:Mul(mw_math.btn(VManip != nil && !w:HasFlag("Aiming") && VManip:IsActive()))
vManipAng:Mul(mw_math.btn(VManip != nil && !w:HasFlag("Aiming") && VManip:IsActive()))
offsetsAng:Add(vManipAng)
offsetsPos:Add(vManipPos)
--bipod
bipodAng:Set(defaultBipodAngle)
bipodPos:Set(defaultBipodPos)
if (w.ViewModelOffsets.Bipod != nil) then
bipodAng:Set(w.ViewModelOffsets.Bipod.Angles || bipodAng)
bipodPos:Set(w.ViewModelOffsets.Bipod.Pos || bipodPos)
end
bipodPos:Mul(mw_math.btn(w:HasFlag("BipodDeployed") && !w:HasFlag("Aiming")))
bipodAng:Mul(mw_math.btn(w:HasFlag("BipodDeployed") && !w:HasFlag("Aiming")))
offsetsAng:Add(bipodAng)
offsetsPos:Add(bipodPos)
--crouching
crouchAng:Set(defaultCrouchAngle)
crouchPos:Set(defaultCrouchPos)
if (w.ViewModelOffsets.Crouch != nil) then
crouchAng:Set(w.ViewModelOffsets.Crouch.Angles || crouchAng)
crouchPos:Set(w.ViewModelOffsets.Crouch.Pos || crouchPos)
end
local crouchDelta = mw_math.btn(p:IsFlagSet(4) && !w:HasFlag("BipodDeployed") && !w:HasFlag("Aiming"))
crouchPos:Mul(crouchDelta)
crouchAng.p = crouchAng.p * crouchDelta
crouchAng.y = crouchAng.y * crouchDelta
crouchAng.r = Lerp(mw_math.btn(p:IsFlagSet(4) && !w:HasFlag("BipodDeployed")), 0, Lerp(mw_math.btn(w:HasFlag("Aiming")), crouchAng.r, crouchAng.r * 0.5))
offsetsAng:Add(crouchAng)
offsetsPos:Add(crouchPos)
--final result
vm.m_OffsetAng.p:SetTarget(offsetsAng.p)
vm.m_OffsetAng.ya:SetTarget(offsetsAng.y)
vm.m_OffsetAng.r:SetTarget(offsetsAng.r)
vm.m_OffsetPos:SetTarget(offsetsPos)
mw_math.DecaySprings(vm.m_OffsetAng.p, vm.m_OffsetAng.ya, vm.m_OffsetAng.r, vm.m_OffsetPos)
local x, y, z = vm.m_OffsetPos:GetValue().x, vm.m_OffsetPos:GetValue().y, vm.m_OffsetPos:GetValue().z
pos:SetUnpacked(pos.x + x, pos.y + y, pos.z + z)
local pi, ya, r = vm.m_OffsetAng.p:GetValue(), vm.m_OffsetAng.ya:GetValue(), vm.m_OffsetAng.r:GetValue()
ang:SetUnpacked(ang.p - pi, ang.y + ya, ang.r + r)
end
ENT.m_RecoilResetSpeed = 100
ENT.m_RecoilAngleTarget = Angle()
ENT.m_RecoilPosTarget = Vector()
ENT.m_RecoilShakeLerp = 0
ENT.m_RecoilRollLerp = 0
ENT.m_RecoilRoll = 0
local recoilFuncs = {
[true] = function(w, name) return w.Recoil.ViewModel[name] || 1 end,
[false] = function() return 1 end
}
local function getRecoilValue(w, name)
return recoilFuncs[w.Recoil.ViewModel != nil](w, name)
end
ENT.m_RecoilAng = mw_math.CreateAngleSpring(80, 1)
ENT.m_RecoilPos = mw_math.CreateVectorSpring(40, 1)
function ENT:SetRecoilTargets(pos, ang)
self.m_RecoilAngleTarget:Set(ang)
self.m_RecoilPosTarget:Set(pos)
self.m_RecoilResetSpeed = -1
end
local lerp = Lerp
local clamp = math.Clamp
local safeLerp = mw_math.SafeLerp
local realFrameTime = RealFrameTime
local approach = mw_math.Approach
local approachAngle = mw_math.ApproachAngle
local function recoil(vm, pos, ang)
local w = vm:GetOwner()
vm.m_RecoilShakeLerp = safeLerp(10 * realFrameTime(), vm.m_RecoilShakeLerp, w.Camera.Shake)
vm.m_RecoilRoll = safeLerp(10 * realFrameTime(), vm.m_RecoilRoll, 0)
vm.m_RecoilRollLerp = safeLerp(10 * realFrameTime(), vm.m_RecoilRollLerp, vm.m_RecoilRoll)
vm.m_RecoilAng.sc = lerp(vm.m_AimDelta, 80, 240) * getRecoilValue(w, "SnapMultiplier")
vm.m_RecoilAng.wc = lerp(vm.m_AimDelta, 1.25, 0.85) / getRecoilValue(w, "LoosenessMultiplier")
vm.m_RecoilPos.sc = lerp(vm.m_AimDelta, 80, 120) * getRecoilValue(w, "SnapMultiplier")
vm.m_RecoilPos.wc = lerp(vm.m_AimDelta, 1, 1.2) / getRecoilValue(w, "LoosenessMultiplier")
vm.m_RecoilResetSpeed = safeLerp(10 * realFrameTime(), vm.m_RecoilResetSpeed, 1)
local resetSpeed = clamp(vm.m_RecoilResetSpeed, 0, 1) * 100
vm.m_RecoilAngleTarget.pitch = approachAngle(vm.m_RecoilAngleTarget.pitch, 0, resetSpeed * realFrameTime())
vm.m_RecoilAngleTarget.yaw = approachAngle(vm.m_RecoilAngleTarget.yaw, 0, resetSpeed * realFrameTime())
vm.m_RecoilAngleTarget.roll = approachAngle(vm.m_RecoilAngleTarget.roll, 0, resetSpeed * realFrameTime())
vm.m_RecoilAng:SetTarget(vm.m_RecoilAngleTarget * 10)
vm.m_RecoilAng:Decay()
vm.m_RecoilPosTarget.x = approach(vm.m_RecoilPosTarget.x, 0, resetSpeed * realFrameTime())
vm.m_RecoilPosTarget.y = approach(vm.m_RecoilPosTarget.y, 0, resetSpeed * realFrameTime())
vm.m_RecoilPosTarget.z = approach(vm.m_RecoilPosTarget.z, 0, resetSpeed * realFrameTime())
vm.m_RecoilPos:SetTarget(vm.m_RecoilPosTarget)
vm.m_RecoilPos:Decay()
local p = vm.m_RecoilAng:GetValue().p * lerp(vm.m_AimDelta, 1, 0.065)
local ya = vm.m_RecoilAng:GetValue().y * lerp(vm.m_AimDelta, 1, 0.08)
local r = vm.m_RecoilAng:GetValue().r * lerp(vm.m_AimDelta, 1, 0.1)
ang.p = ang.p - p
ang.y = ang.y - ya
ang.r = ang.r + r + lerp(vm.m_AimDelta, 0, vm.m_RecoilRollLerp)
local x = vm.m_RecoilPos:GetValue().x * lerp(vm.m_AimDelta, 1, 0.35)
local y = vm.m_RecoilPos:GetValue().y * lerp(vm.m_AimDelta, 1, 0.35)
local z = vm.m_RecoilPos:GetValue().z * lerp(vm.m_AimDelta, 1, 0.35)
pos.x = pos.x - x
pos.y = pos.y - y - lerp(vm.m_AimDelta, 0, vm.m_RecoilShakeLerp * 1.5)
pos.z = pos.z + z
end
function ENT:CalcViewModelView(pos, ang)
if (game.SinglePlayer() && gui.IsGameUIVisible()) then
return
end
local w = self:GetOwner()
local lpos, lang = hook.Run("CalcViewModelView", w, self, pos, ang, Vector(pos), Angle(ang))
pos:Set(lpos)
ang:Set(lang)
local cPos, cAng = Vector(), Angle()
self.m_AimDelta = mw_math.SafeLerp(18 * RealFrameTime(), self.m_AimDelta, w:GetAimDelta())
self.m_AimModeDelta = mw_math.SafeLerp(18 * RealFrameTime(), self.m_AimModeDelta, w:GetAimModeDelta())
movementInertia(self, cPos, cAng)
sway(self, cPos, cAng, ang)
recoil(self, cPos, cAng)
cPos:Mul(mw_math.btn(1 / RealFrameTime() >= 14))
cAng:Mul(mw_math.btn(1 / RealFrameTime() >= 14))
ang:RotateAroundAxis(ang:Forward(), cAng.r)
ang:RotateAroundAxis(ang:Right(), cAng.p)
ang:RotateAroundAxis(ang:Up(), cAng.y)
pos:Add(ang:Forward() * cPos.y)
pos:Add(ang:Right() * cPos.x)
pos:Add(ang:Up() * cPos.z)
--we calculate offsets at the end so movements are aligned to original axis
--regardless of offset
cPos:SetUnpacked(0, 0, 0)
cAng:SetUnpacked(0, 0, 0)
offsets(self, cPos, cAng)
ang:RotateAroundAxis(ang:Forward(), cAng.r)
ang:RotateAroundAxis(ang:Right(), cAng.p)
ang:RotateAroundAxis(ang:Up(), cAng.y)
pos:Add(ang:Forward() * cPos.y)
pos:Add(ang:Right() * cPos.x)
pos:Add(ang:Up() * cPos.z)
local originalFov = weapons.GetStored("mg_base").ViewModelFOV
local hipFovMul = GetConVar("mgbase_fx_vmfov"):GetFloat()
local adsFovMul = GetConVar("mgbase_fx_vmfov_ads"):GetFloat()
if (w:GetSight() != nil && w:GetSight().Optic != nil) then
adsFovMul = math.max(adsFovMul, Lerp(self.m_AimModeDelta, 1, adsFovMul))
end
w.ViewModelFOV = mw_math.SafeLerp(self.m_AimDelta, originalFov, originalFov * Lerp(self.m_AimModeDelta, w.Zoom.ViewModelFovMultiplier, 0.9))
w.ViewModelFOV = w.ViewModelFOV * Lerp(self.m_AimDelta, hipFovMul, adsFovMul)
if (GetViewEntity():IsPlayer()) then
local curFov = GetViewEntity():GetFOV()
w.ViewModelFOV = w.ViewModelFOV / Lerp(self.m_AimDelta, 1, (90 / curFov))
end
end

View File

@@ -0,0 +1,298 @@
require("mw_utils")
--Events we can use:
-- CL_EVENT_SOUND [sound, vector for spatial] (5004) -> sound (eg: "event 5004 mw19.sound 0,10,10")
-- CL_EJECT_BRASS1 [attachment name] (6001) -> ejection (eg: event 6001 tag_ejection)
-- CL_EVENT_DISPATCHEFFECT0 [particle name, attachment name] (9001) -> particles (eg: event 9001 mw_muzzleflash tag_flash)
-- CL_EVENT_DISPATCHEFFECT1 [0/1] (9011) -> left hand grip pose toggle (eg: event 9011 0 -> event 9011 1)
-- CL_EVENT_DISPATCHEFFECT2 [0/1] (9021) -> right hand grip pose toggle (eg: event 9021 0 -> event 9021 1)
-- CL_EVENT_DISPATCHEFFECT3 [name] (9031) -> run attachment function (eg: event 9031 FillBullets)
--Animation event codes
local CL_EVENT_MUZZLEFLASH0 = 5001 -- Muzzleflash on attachment 0
local CL_EVENT_MUZZLEFLASH1 = 5011 -- Muzzleflash on attachment 1
local CL_EVENT_MUZZLEFLASH2 = 5021 -- Muzzleflash on attachment 2
local CL_EVENT_MUZZLEFLASH3 = 5031 -- Muzzleflash on attachment 3
local CL_EVENT_SPARK0 = 5002 -- Spark on attachment 0
local CL_EVENT_NPC_MUZZLEFLASH0 = 5003 -- Muzzleflash on attachment 0 for third person views
local CL_EVENT_NPC_MUZZLEFLASH1 = 5013 -- Muzzleflash on attachment 1 for third person views
local CL_EVENT_NPC_MUZZLEFLASH2 = 5023 -- Muzzleflash on attachment 2 for third person views
local CL_EVENT_NPC_MUZZLEFLASH3 = 5033 -- Muzzleflash on attachment 3 for third person views
local CL_EVENT_SOUND = 5004 -- Emit a sound // NOTE THIS MUST MATCH THE DEFINE AT CBaseEntity::PrecacheModel on the server!!!!!
local CL_EVENT_EJECTBRASS1 = 6001 -- Eject a brass shell from attachment 1
local CL_EVENT_DISPATCHEFFECT0 = 9001 -- Hook into a DispatchEffect on attachment 0
local CL_EVENT_DISPATCHEFFECT1 = 9011 -- Hook into a DispatchEffect on attachment 1
local CL_EVENT_DISPATCHEFFECT2 = 9021 -- Hook into a DispatchEffect on attachment 2
local CL_EVENT_DISPATCHEFFECT3 = 9031 -- Hook into a DispatchEffect on attachment 3
local CL_EVENT_DISPATCHEFFECT4 = 9041 -- Hook into a DispatchEffect on attachment 4
local CL_EVENT_DISPATCHEFFECT5 = 9051 -- Hook into a DispatchEffect on attachment 5
local CL_EVENT_DISPATCHEFFECT6 = 9061 -- Hook into a DispatchEffect on attachment 6
local CL_EVENT_DISPATCHEFFECT7 = 9071 -- Hook into a DispatchEffect on attachment 7
local CL_EVENT_DISPATCHEFFECT8 = 9081 -- Hook into a DispatchEffect on attachment 8
local CL_EVENT_DISPATCHEFFECT9 = 9091 -- Hook into a DispatchEffect on attachment 9
local utilef = util.Effect
local pef = ParticleEffectAttach
local function invalidateBoneCacheForParticles(ent)
while (IsValid(ent)) do
if (ent:IsEffectActive(EF_BONEMERGE) || !IsValid(ent:GetParent())) then
ent:InvalidateBoneCache()
end
ent = ent:GetParent()
end
end
local function findAttachmentInChildren(ent, attName)
local attId = mw_utils.LookupAttachmentCached(ent, attName)
for _, c in pairs(ent:GetChildren()) do
if (c:GetClass() != "class C_BaseFlex") then
continue
end
local ce, ca = findAttachmentInChildren(c, attName)
if (ca != nil) then
attId = ca
ent = ce
end
end
return ent, attId
end
function ENT:FindAttachment(attName)
return findAttachmentInChildren(self, attName)
end
local function createEffectDataForShell(owner, attName)
local data = EffectData()
data:SetEntity(owner)
local attEnt, attId = findAttachmentInChildren(owner, attName)
if (attId == nil) then
mw_utils.ErrorPrint("createEffectDataForShell: "..attName.." does not exist on model!")
return data
end
local att = attEnt:GetAttachment(attId)
data:SetOrigin(att.Pos)
data:SetAngles(att.Ang)
owner = owner:GetOwner()
while (IsValid(owner) && !owner:IsPlayer()) do
owner = owner:GetOwner()
end
if (IsValid(owner)) then
data:SetNormal(owner:GetVelocity():GetNormalized())
data:SetMagnitude(owner:GetVelocity():Length())
end
return data
end
function ENT:IsFirstPerson()
local w = self:GetOwner()
return IsValid(w:GetOwner()) && w:GetOwner():IsPlayer() && !w:GetOwner():ShouldDrawLocalPlayer() && w:IsCarriedByLocalPlayer()
end
function ENT:HandleEjection(attName)
local w = self:GetOwner()
if (w.Shell == "mwb_shelleject" || w.Shell == "mwb_shelleject_comp") then
mw_utils.ErrorPrint("DoEjection: do not use mwb_shelleject! Use an existing caliber or make your own.")
return true
elseif (istable(w.Shell)) then
mw_utils.DevPrint("DoEjection: still using legacy way! Consider switching to new method.")
end
local eff = isstring(w.Shell) && w.Shell || "mwb_shelleject_comp"
if (self:IsFirstPerson()) then
local data = createEffectDataForShell(self, attName)
data:SetFlags(1)
utilef(eff, data)
else
local data = createEffectDataForShell(w, attName)
data:SetFlags(0)
utilef(eff, data)
end
return true
end
function ENT:HandleParticle(partName, attName)
local w = self:GetOwner()
if (w.ParticleEffects != nil && w.ParticleEffects[partName] != nil) then
partName = w.ParticleEffects[partName]
end
if (self:IsFirstPerson()) then
local ent, attId = findAttachmentInChildren(self, attName)
if (attId == nil) then
mw_utils.ErrorPrint("HandleParticle: "..attName.." does not exist on viewmodel!")
return true
end
if (self.m_Particles[partName] != nil) then
self.m_Particles[partName]:StopEmissionAndDestroyImmediately()
end
local particleSystem = CreateParticleSystem(ent, partName, PATTACH_POINT_FOLLOW, attId)
particleSystem:SetIsViewModelEffect(true)
particleSystem:SetShouldDraw(false)
self.m_Particles[partName] = particleSystem
else
local ent, attId = findAttachmentInChildren(w, attName)
if (attId == nil) then
mw_utils.ErrorPrint("HandleParticle: "..attName.." does not exist on worldmodel!")
return true
end
ent:StopParticlesNamed(partName)
pef(partName, PATTACH_POINT_FOLLOW, ent, attId)
end
return true
end
function ENT:HandleSound(soundName, spatialVector)
local w = self:GetOwner()
if (IsValid(w) && w.SoundOverrides != nil) then
soundName = w.SoundOverrides[soundName] || soundName
end
if (spatialVector != nil && !spatialVector:IsZero()) then
if (IsValid(w:GetOwner()) && !w:GetOwner():IsOnGround()) then
return true
end
local ang = self:GetAngles()
local pos = self:GetPos()
pos:Add(ang:Forward() * spatialVector.y)
pos:Add(ang:Right() * spatialVector.x)
pos:Add(ang:Up() * spatialVector.z)
sound.Play(soundName, pos)
return true
end
--if (self:GetPlaybackRate() != 1) then
-- self:EmitSound(soundName, 100, math.Clamp(self:GetPlaybackRate(), 0.95, 1.15) * 100, 1, CHAN_AUTO, SND_CHANGE_PITCH)
--else
self:EmitSound(soundName, 0, math.Clamp(self:GetPlaybackRate(), 1, 1.1) * 100, 0, 0, SND_SHOULDPAUSE + SND_CHANGE_PITCH)
--end
return true
end
function ENT:HandleLeftHandGrip(val)
self.m_LeftHandGripTarget = tonumber(val)
return true
end
function ENT:HandleRightHandGrip(val)
self.m_RightHandGripTarget = tonumber(val)
return true
end
function ENT:HandleAttFunction(name)
self:GetOwner():AttachmentFunction(name)
return true
end
local function eventError(event, msg)
mw_utils.ErrorPrint("FireAnimationEvent ("..event.."): "..msg)
end
function ENT:FireAnimationEvent(pos, ang, event, name)
if (event == CL_EVENT_DISPATCHEFFECT3) then
return self:HandleAttFunction(name)
end
if (event == CL_EVENT_DISPATCHEFFECT1) then
return self:HandleLeftHandGrip(name || 0)
end
if (event == CL_EVENT_DISPATCHEFFECT2) then
return self:HandleRightHandGrip(name || 0)
end
if (event == CL_EVENT_SOUND) then
if (name == nil) then
eventError(event, "Missing sound name!")
return true
end
local args = string.Explode(" ", name)
if (#args <= 0) then
eventError(event, "Missing arguments!")
return true
end
local soundName = args[1]
local spatialVector = Vector()
if (args[2] != nil) then
local components = string.Explode(",", args[2])
if (#components <= 1) then
--jake used spaces like a dumbass
spatialVector.x = args[2]
spatialVector.y = args[3]
spatialVector.z = args[4]
else
spatialVector.x = tonumber(components[1]) || 0
spatialVector.y = tonumber(components[2]) || 0
spatialVector.z = tonumber(components[3]) || 0
end
end
return self:HandleSound(soundName, spatialVector)
end
if (event == CL_EVENT_EJECTBRASS1) then
if (name == nil) then
eventError(event, "Missing attachment name!")
return true
end
if (self:GetOwner().HandleEjection != nil) then
return self:GetOwner():HandleEjection(name)
end
return self:HandleEjection(name)
end
if (event == CL_EVENT_DISPATCHEFFECT0) then
if (name == nil) then
eventError(event, "Missing arguments!")
return true
end
local args = string.Explode(" ", name)
if (#args <= 0) then
eventError(event, "Missing arguments!")
return true
end
local partName = args[1]
local attName = args[2]
if (attName == nil) then
eventError(event, "Missing attachment name!")
return true
end
return self:HandleParticle(partName, attName)
end
end

View File

@@ -0,0 +1,273 @@
local function drawModels(vm, ent, flags)
--https://github.com/Facepunch/garrysmod-issues/issues/4821
--i didn't need this before, but now i do :shrug:
ent:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
local children = ent:GetChildren()
local numChildren = #children
if (ent:IsEffectActive(EF_BONEMERGE)) then
if (ent == vm.m_CHands) then
ent:SetRenderOrigin(LocalToWorld(-ent:OBBCenter(), mw_math.ZeroAngle, vm:GetRenderOrigin(), vm:GetRenderAngles()))
else
if (ent:EntIndex() < 0) then
ent:SetRenderOrigin(vm:GetRenderOrigin())
end
if (numChildren > 0) then
--some weird issue on windowed needs this
ent:SetupBones()
end
end
end
if ((numChildren <= 0 || ent:EntIndex() > 0) && !ent.bAttachmentRenderOverride) then
ent:DrawModel(flags)
end
ent.CustomizationAnimationDelta = 0
for c = 1, numChildren do
drawModels(vm, children[c], flags)
end
end
local function isCustomizing()
return IsValid(MW_CUSTOMIZEMENU)
end
local function drawCustomizationBackground()
if (!isCustomizing()) then
return
end
cam.Start2D()
surface.SetDrawColor(0, 0, 0, MW_CUSTOMIZEMENU.AlphaDelta * 200)
surface.DrawRect(0, 0, ScrW(), ScrH())
cam.End2D()
end
local function shouldDrawModel(model, children)
for _, c in pairs(children) do
if (!c:IsEffectActive(EF_BONEMERGE)) then
return true
end
end
return #children <= 0 || model:EntIndex() > 0
end
local function drawCustomizationHighlights(model, flags, refvalue)
model.CustomizationAnimationDelta = (model.CustomizationAnimationDelta || 0) - (math.min(FrameTime(), 0.1) * 3)
local children = model:GetChildren()
if (shouldDrawModel(model, children)) then
model:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
if (#children > 0) then
--some weird issue on windowed needs this
model:SetupBones()
end
render.SetStencilWriteMask(0xFF)
render.SetStencilTestMask(0xFF)
render.SetStencilReferenceValue(0)
render.SetStencilCompareFunction(STENCIL_ALWAYS)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilFailOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_KEEP)
render.SetStencilEnable(true)
render.SetStencilReferenceValue(refvalue + 1)
model:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
model:DrawModel(flags)
render.SetStencilCompareFunction(STENCIL_EQUAL)
if (model.CustomizationAnimationDelta > 0) then
cam.Start2D()
surface.SetDrawColor(model.CustomizationAnimationColor.r, model.CustomizationAnimationColor.g, model.CustomizationAnimationColor.b, model.CustomizationAnimationDelta * 200)
surface.DrawRect(0, 0, ScrW(), ScrH())
cam.End2D()
end
render.SetStencilEnable(false)
end
for i, c in pairs(children) do
drawCustomizationHighlights(c, flags, refvalue + i + #c:GetChildren()) --this is gonna get out of hand eventually
end
end
function ENT:Draw(flags)
if (GetConVar("mgbase_debug_vmrender"):GetInt() <= 0) then
return
end
if (self.m_LastSequenceIndex == "INIT" || self:GetRenderOrigin() == nil) then
--calcview / no anim called
return
end
local w = self:GetOwner()
if (!IsValid(w) || !w:IsCarriedByLocalPlayer()) then
return
end
if (IsValid(w:GetOwner())) then
w:GetOwner():DrawViewModel(false)
end
render.SetColorModulation(1, 1, 1)
drawCustomizationBackground()
self:DrawShadow(false)
self.bRendering = true
self:SetupBones() --makes velements and vmanip work
self.bRendering = false
if (!isCustomizing()) then
if (!w:HasFlag("Holstering") || CurTime() <= w:GetNextHolsterTime()) then
self:SetNoDraw(false)
drawModels(self, self, flags)
for name, particleSystem in pairs(self.m_Particles) do
if (!particleSystem:IsValid() || particleSystem:IsFinished()) then
self.m_Particles[name] = nil
continue
end
particleSystem:Render()
end
--attachments
local atts = w:GetAllAttachmentsInUse()
for slot = #atts, 1, -1 do
if (IsValid(atts[slot].m_Model)) then
atts[slot]:Render(w, atts[slot].m_Model)
end
end
end
self:SetNoDraw(true)
else
--self.m_CHands:SetNoDraw(false)
self.m_CHands:DrawModel(flags)
--self.m_CHands:SetNoDraw(true)
drawCustomizationHighlights(self, flags, MWBASE_STENCIL_REFVALUE + 17)
end
for shell, _ in pairs(self.m_Shells) do
if (!IsValid(shell)) then
self.m_Shells[shell] = nil
continue
end
shell:DrawModel(flags)
end
self:ViewBlur()
if (IsValid(w:GetOwner())) then
w:GetOwner():DrawViewModel(true)
end
end
local function drawBlurModels(model, flags)
local children = model:GetChildren()
--if (shouldDrawModel(model, children)) then
model:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
model:DrawModel(flags)
--end
for i, c in pairs(children) do
drawBlurModels(c, flags) --this is gonna get out of hand eventually
end
end
local blurMaterial = Material("mg/blur.vmt")
ENT.LerpBlur = 0
function ENT:ViewBlur()
local w = self:GetOwner()
if (!IsValid(w)) then
return
end
local bPixelShaders2 = render.SupportsPixelShaders_2_0()
if (!bPixelShaders2) then
return
end
if (GetConVar("mgbase_fx_blur"):GetInt() != 1) then return end
if (w.DisableReloadBlur && w:HasFlag("Reloading")) then return end
local bOpticAim = (w:GetAimDelta() > 0 && w:GetSight() != nil && w:GetSight().Optic != nil && w:GetAimModeDelta() <= w.m_hybridSwitchThreshold)
local bCanBlur = w:HasFlag("Reloading") || w:HasFlag("Customizing") || bOpticAim || (CurTime() < w:GetNextInspectTime() && w.m_seqIndex == "Inspect")
if (bCanBlur) then
local delta = 1 - w:GetAimDelta()
if (bOpticAim) then
delta = w:GetAimDelta()
end
if (CurTime() < w:GetNextInspectTime() && w.m_seqIndex == "Inspect") then
delta = self:GetCycle() > 0.8 && 0 || 1
end
self.LerpBlur = Lerp(5 * FrameTime(), self.LerpBlur, 5 * delta)
render.SetStencilWriteMask(0xFF)
render.SetStencilTestMask(0xFF)
render.SetStencilReferenceValue(0)
render.SetStencilPassOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_KEEP)
render.ClearStencil()
render.SetStencilEnable(true)
render.SetStencilReferenceValue(MWBASE_STENCIL_REFVALUE + 13)
render.SetStencilCompareFunction(STENCIL_NEVER)
render.SetStencilFailOperation(STENCIL_REPLACE)
render.SetBlend(0)
if (w:GetAimDelta() < 1) then
drawBlurModels(self, flags)
elseif (w:GetSight() != nil && IsValid(w:GetSight().hideModel)) then
w:GetSight().m_Model:SetupBones()
w:GetSight().m_Model:InvalidateBoneCache()
local matrix = w:GetSight().m_Model:GetBoneMatrix(0)
w:GetSight().hideModel:SetPos(matrix:GetTranslation())
w:GetSight().hideModel:SetAngles(matrix:GetAngles())
w:GetSight().hideModel:DrawModel()
end
render.SetBlend(1)
render.SetStencilCompareFunction(STENCIL_NOTEQUAL)
cam.Start2D()
for i = 1, self.LerpBlur, 1 do
render.UpdateScreenEffectTexture()
surface.SetMaterial(blurMaterial)
surface.SetDrawColor(255, 255, 255, 255)
surface.DrawTexturedRect(0, 0, ScrW(), ScrH())
end
cam.End2D()
render.SetStencilEnable(false)
render.ClearStencil()
else
self.LerpBlur = 0
end
end
--[[hook.Add("VManipVMEntity", "MW19_VManipEntity", function(ply, weapon)
--this is probably not necessary since vmanip already looks for m_ViewModel
if (weapons.IsBasedOn(weapon:GetClass(), "mg_base")) then
return weapon:GetViewModel()
end
end)]]