137 lines
4.7 KiB
Lua
137 lines
4.7 KiB
Lua
function SWEP:GetRecoilResetTime(base)
|
|
if base then
|
|
return (self:GetBaseValue("RecoilResetInstant") and 0 or math.min(0.5, 60 / self:GetRPM(true))) + self:GetBaseValue("RecoilResetTime")
|
|
else
|
|
return (self:GetValue("RecoilResetInstant") and 0 or math.min(0.5, 60 / self:GetRPM())) + self:GetValue("RecoilResetTime")
|
|
end
|
|
end
|
|
|
|
function SWEP:ThinkRecoil()
|
|
if self:GetLastRecoilTime() + engine.TickInterval() + self:GetRecoilResetTime() < CurTime() then
|
|
local rec = self:GetRecoilAmount()
|
|
|
|
rec = rec - (FrameTime() * self:GetValue("RecoilDissipationRate"))
|
|
rec = math.Clamp(rec, 0, self:GetValue("RecoilMaximum"))
|
|
|
|
self:SetRecoilAmount(rec)
|
|
end
|
|
end
|
|
|
|
function SWEP:ApplyRecoil()
|
|
local rec = self:GetRecoilAmount()
|
|
local rps = self:GetValue("RecoilPerShot")
|
|
local cfm = self:GetCurrentFiremode()
|
|
|
|
if rec == 0 then
|
|
rps = rps * self:GetValue("RecoilFirstShotMult")
|
|
end
|
|
|
|
if self:GetOwner():Crouching() and self:GetOwner():OnGround() then
|
|
rps = rps * self:GetValue("RecoilMultCrouch")
|
|
end
|
|
|
|
if cfm < 0 then
|
|
rps = rps * self:GetValue("RecoilMultBurst")
|
|
elseif cfm == 1 then
|
|
rps = rps * self:GetValue("RecoilMultSemi")
|
|
end
|
|
|
|
if self:GetInBipod() then
|
|
rps = rps * math.min(1, self:GetValue("BipodRecoil"))
|
|
end
|
|
|
|
rec = rec + rps
|
|
|
|
rec = math.Clamp(rec, 0, self:GetValue("RecoilMaximum"))
|
|
|
|
if self:UseRecoilPatterns() then
|
|
self:SetRecoilDirection(self:GetRecoilPatternDirection(self:GetPatternCount()))
|
|
else
|
|
local stab = math.Clamp(self:GetValue("RecoilStability"), 0, 0.9)
|
|
self:SetRecoilDirection(util.SharedRandom("tacrp_recoildir", -180 + stab * 90, -stab * 90))
|
|
end
|
|
|
|
-- self:SetRecoilDirection(-90)
|
|
self:SetRecoilAmount(rec)
|
|
self:SetLastRecoilTime(CurTime())
|
|
|
|
local vis_kick = self:GetValue("RecoilVisualKick")
|
|
local vis_shake = 0
|
|
|
|
vis_kick = vis_kick * TacRP.ConVars["mult_recoil_vis"]:GetFloat()
|
|
vis_shake = 0
|
|
|
|
if self:GetInBipod() then
|
|
vis_kick = vis_kick * math.min(1, self:GetValue("BipodKick"))
|
|
vis_shake = math.max(0, 1 - self:GetValue("BipodKick"))
|
|
end
|
|
|
|
local vis_kick_v = vis_kick * 1
|
|
local vis_kick_h = vis_kick * util.SharedRandom("tacrp_vis_kick_h", -1, 1)
|
|
|
|
self:GetOwner():SetViewPunchAngles(Angle(vis_kick_v, vis_kick_h, vis_shake))
|
|
|
|
-- self:GetOwner():SetFOV(self:GetOwner():GetFOV() * 0.99, 0)
|
|
-- self:GetOwner():SetFOV(self:GetOwner():GetFOV(), 60 / (self:GetValue("RPM")))
|
|
end
|
|
|
|
function SWEP:RecoilDuration()
|
|
-- return self:GetValue("RecoilResetTime")
|
|
return 0.04 + math.Clamp(math.abs(self:GetValue("RecoilKick")) ^ 0.5, 0, 4) * 0.04
|
|
end
|
|
|
|
function SWEP:UseRecoilPatterns()
|
|
if !TacRP.ConVars["recoilpattern"]:GetBool() then return false end
|
|
if self:GetValue("ShootEnt") or self:GetValue("NoRecoilPattern") then return false end
|
|
if self:GetValue("RPM") <= 100 then return false end
|
|
if self:GetCurrentFiremode() < 0 then return false end
|
|
|
|
return true
|
|
end
|
|
|
|
SWEP.RecoilPatternCache = {}
|
|
SWEP.RecoilPatternSeedCache = nil
|
|
function SWEP:GetRecoilPatternDirection(shot)
|
|
local dir = 0
|
|
|
|
if !self.RecoilPatternSeedCache then
|
|
local cacheseed = self.RecoilPatternSeed or self:GetClass()
|
|
if isstring(cacheseed) then
|
|
local numseed = 0
|
|
for _, i in ipairs(string.ToTable(cacheseed)) do
|
|
numseed = numseed + string.byte(i)
|
|
end
|
|
numseed = numseed % 16777216
|
|
cacheseed = numseed
|
|
end
|
|
self.RecoilPatternSeedCache = cacheseed
|
|
end
|
|
|
|
local seed = self.RecoilPatternSeedCache + shot
|
|
|
|
if self.RecoilPatternCache[shot] then
|
|
dir = self.RecoilPatternCache[shot]
|
|
else
|
|
self.RecoilPatternCache[1] = 0
|
|
if self.RecoilPatternCache[shot - 1] then
|
|
--dir = self.RecoilPatternCache[shot - 1]
|
|
math.randomseed(seed)
|
|
local stab = math.Clamp(self:GetValue("RecoilStability"), 0, 0.9)
|
|
local max = self:GetBaseValue("RPM") / 60 * (1.1 + stab * 1.1)
|
|
local cap = 120 --math.Clamp(30 + shot * (90 / max), 30, 120)
|
|
--dir = dir + math.Rand(-stab * 90, stab * 90)
|
|
dir = Lerp(0.4 + (shot / max) * 0.6, self.RecoilPatternCache[shot - 1], math.Rand(-(1 - stab) * cap, (1 - stab) * cap))
|
|
if self:GetCurrentFiremode() != 1 then
|
|
dir = Lerp(shot / max, dir, math.Clamp(dir * 1.667, -cap, cap))
|
|
end
|
|
math.randomseed(CurTime() + self:EntIndex())
|
|
self.RecoilPatternCache[shot] = dir
|
|
-- print(shot, cap, max, dir)
|
|
else
|
|
dir = 0
|
|
end
|
|
end
|
|
|
|
return math.NormalizeAngle(dir - 90)
|
|
end
|