mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
534 lines
17 KiB
Lua
534 lines
17 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
SWEP.Sighted = false
|
|
SWEP.Sprinted = false
|
|
|
|
local function linearlerp(a, b, c)
|
|
return b + (c - b) * a
|
|
end
|
|
|
|
function SWEP:GetSightTime()
|
|
return self:GetBuff("SightTime")
|
|
end
|
|
|
|
function SWEP:EnterSprint()
|
|
if engine.ActiveGamemode() == "terrortown" and !(TTT2 and self:GetOwner().isSprinting) then return end
|
|
if self:GetState() == ArcCW.STATE_SPRINT then return end
|
|
if self:GetState() == ArcCW.STATE_CUSTOMIZE then return end
|
|
if self:GetTriggerDelta() > 0 then return end
|
|
if self:GetGrenadePrimed() and !self:CanShootWhileSprint() then return end
|
|
self:SetState(ArcCW.STATE_SPRINT)
|
|
self.Sighted = false
|
|
self.Sprinted = true
|
|
|
|
local ct = CurTime()
|
|
|
|
-- self.SwayScale = 1
|
|
-- self.BobScale = 5
|
|
|
|
self:SetShouldHoldType()
|
|
|
|
local s = self:CanShootWhileSprint()
|
|
|
|
if !s and self:GetNextPrimaryFire() <= ct then
|
|
self:SetNextPrimaryFire(ct)
|
|
end
|
|
|
|
local anim = self:SelectAnimation("enter_sprint")
|
|
if anim and !s and self:GetNextSecondaryFire() <= ct then
|
|
self:PlayAnimation(anim, self:GetBuff("SightTime") / self:GetAnimKeyTime(anim, true), true, nil, false, nil, false, false)
|
|
end
|
|
end
|
|
|
|
function SWEP:ExitSprint()
|
|
if self:GetState() == ArcCW.STATE_IDLE then return end
|
|
|
|
local delta = self:GetNWSprintDelta()
|
|
local ct = CurTime()
|
|
|
|
self:SetState(ArcCW.STATE_IDLE)
|
|
self.Sighted = false
|
|
self.Sprinted = false
|
|
|
|
-- self.SwayScale = 1
|
|
-- self.BobScale = 1.5
|
|
|
|
self:SetShouldHoldType()
|
|
|
|
local s = self:CanShootWhileSprint()
|
|
|
|
if !s and self:GetNextPrimaryFire() <= ct then
|
|
self:SetNextPrimaryFire(ct + self:GetSprintTime() * delta)
|
|
end
|
|
|
|
if self:GetOwner():KeyDown(IN_ATTACK2) then
|
|
self:EnterSights()
|
|
end
|
|
|
|
local anim = self:SelectAnimation("exit_sprint")
|
|
if anim and !s then -- and self:GetNextSecondaryFire() <= ct
|
|
self:PlayAnimation(anim, self:GetBuff("SightTime") / self:GetAnimKeyTime(anim, true), true, nil, false, nil, false, false)
|
|
end
|
|
end
|
|
|
|
-- defined above already?
|
|
|
|
function SWEP:EnterSights()
|
|
local asight = self:GetActiveSights()
|
|
if !asight then return end
|
|
if self:GetState() != ArcCW.STATE_IDLE then return end
|
|
if self:GetCurrentFiremode().Mode == 0 then return end
|
|
if !self.ReloadInSights and (self:GetReloading() or self:GetOwner():KeyDown(IN_RELOAD)) then return end
|
|
if self.LockSightsInPriorityAnim and self:GetPriorityAnim() then return end
|
|
if self:GetBuff_Hook("Hook_ShouldNotSight") then return end
|
|
if (!game.SinglePlayer() and !IsFirstTimePredicted()) then return end
|
|
|
|
self:SetupActiveSights()
|
|
|
|
self:SetState(ArcCW.STATE_SIGHTS)
|
|
self.Sighted = true
|
|
self.Sprinted = false
|
|
|
|
self:SetShouldHoldType()
|
|
|
|
self:MyEmitSound(asight.SwitchToSound or "", 75, math.Rand(95, 105), 0.5, CHAN_AUTO)
|
|
|
|
local anim = self:SelectAnimation("enter_sight")
|
|
if anim then
|
|
self:PlayAnimation(anim, 1 * self:GetBuff_Mult("Mult_SightTime"), true)
|
|
end
|
|
|
|
self:GetBuff_Hook("Hook_SightToggle", true)
|
|
end
|
|
|
|
function SWEP:ExitSights()
|
|
local asight = self:GetActiveSights()
|
|
if self:GetState() != ArcCW.STATE_SIGHTS then return end
|
|
if self.LockSightsInReload and self:GetReloading() then return end
|
|
if self.LockSightsInPriorityAnim and self:GetPriorityAnim() then return end
|
|
if (!game.SinglePlayer() and !IsFirstTimePredicted()) then return end
|
|
|
|
self:SetState(ArcCW.STATE_IDLE)
|
|
self.Sighted = false
|
|
self.Sprinted = false
|
|
|
|
self:SetShouldHoldType()
|
|
|
|
self:MyEmitSound(asight.SwitchFromSound or "", 75, math.Rand(80, 90), 0.5, CHAN_AUTO)
|
|
|
|
if self:InSprint() then
|
|
self:EnterSprint()
|
|
end
|
|
|
|
self:MyEmitSound(asight.SwitchFromSound or "", 75, math.Rand(80, 90), 0.5, CHAN_AUTO)
|
|
|
|
local anim = self:SelectAnimation("exit_sight")
|
|
if anim then
|
|
self:PlayAnimation(anim, 1 * self:GetBuff_Mult("Mult_SightTime"), true)
|
|
end
|
|
|
|
self:GetBuff_Hook("Hook_SightToggle", false)
|
|
end
|
|
|
|
function SWEP:GetSprintTime()
|
|
return self:GetSightTime()
|
|
end
|
|
|
|
SWEP.SightTable = {}
|
|
SWEP.SightMagnifications = {}
|
|
|
|
function SWEP:SetupActiveSights()
|
|
if !self.IronSightStruct then return end
|
|
if self:GetBuff_Hook("Hook_ShouldNotSight") then return false end
|
|
|
|
if !self:GetOwner():IsPlayer() then return end
|
|
|
|
local sighttable = {}
|
|
local vm = self:GetOwner():GetViewModel()
|
|
|
|
if !vm or !vm:IsValid() then return end
|
|
|
|
local kbi = self.KeepBaseIrons or true
|
|
local bif = self.BaseIronsFirst or true
|
|
|
|
for i, k in pairs(self.Attachments) do
|
|
if !k.Installed then continue end
|
|
|
|
local atttbl = ArcCW.AttachmentTable[k.Installed]
|
|
|
|
local addsights = self:GetBuff_Stat("AdditionalSights", i)
|
|
if !addsights then continue end
|
|
|
|
if !k.KeepBaseIrons and !atttbl.KeepBaseIrons then kbi = false end
|
|
if !k.BaseIronsFirst and !atttbl.BaseIronsFirst then bif = false end
|
|
|
|
for _, s in pairs(addsights) do
|
|
local stab = table.Copy(s)
|
|
|
|
stab.Slot = i
|
|
|
|
if stab.HolosightData then atttbl = stab.HolosightData end
|
|
|
|
stab.HolosightData = atttbl
|
|
|
|
if atttbl.HolosightMagnification then
|
|
stab.MagnifiedOptic = true
|
|
stab.ScopeMagnification = atttbl.HolosightMagnification or 1
|
|
|
|
if atttbl.HolosightMagnificationMin then
|
|
stab.ScopeMagnificationMin = atttbl.HolosightMagnificationMin
|
|
stab.ScopeMagnificationMax = atttbl.HolosightMagnificationMax
|
|
|
|
stab.ScopeMagnification = math.max(stab.ScopeMagnificationMax, stab.ScopeMagnificationMin)
|
|
|
|
if !i and self.SightMagnifications[0] then
|
|
stab.ScopeMagnification = self.SightMagnifications[0]
|
|
elseif self.SightMagnifications[i] then
|
|
stab.ScopeMagnification = self.SightMagnifications[i]
|
|
end
|
|
else
|
|
stab.ScopeMagnification = atttbl.HolosightMagnification
|
|
end
|
|
end
|
|
|
|
if atttbl.Holosight then
|
|
stab.Holosight = true
|
|
end
|
|
|
|
if !k.Bone then return end
|
|
|
|
local boneid = vm:LookupBone(k.Bone)
|
|
|
|
if !boneid then return end
|
|
|
|
if CLIENT then
|
|
|
|
if atttbl.HolosightPiece then
|
|
stab.HolosightPiece = (k.HSPElement or {}).Model
|
|
end
|
|
|
|
if atttbl.Holosight then
|
|
stab.HolosightModel = (k.VElement or {}).Model
|
|
end
|
|
|
|
local bpos, bang = self:GetFromReference(boneid)
|
|
|
|
local offset
|
|
local offset_ang
|
|
|
|
local vmang = Angle()
|
|
|
|
offset = k.Offset.vpos or Vector(0, 0, 0)
|
|
|
|
local attslot = k
|
|
|
|
local delta = attslot.SlidePos or 0.5
|
|
|
|
local vmelemod = nil
|
|
local slidemod = nil
|
|
|
|
for _, e in pairs(self:GetActiveElements()) do
|
|
local ele = self.AttachmentElements[e]
|
|
|
|
if !ele then continue end
|
|
|
|
if ((ele.AttPosMods or {})[i] or {}).vpos then
|
|
vmelemod = ele.AttPosMods[i].vpos
|
|
end
|
|
|
|
if ((ele.AttPosMods or {})[i] or {}).slide then
|
|
slidemod = ele.AttPosMods[i].slide
|
|
end
|
|
|
|
-- Refer to sh_model Line 837
|
|
if ((ele.AttPosMods or {})[i] or {}).SlideAmount then
|
|
slidemod = ele.AttPosMods[i].SlideAmount
|
|
end
|
|
end
|
|
|
|
offset = vmelemod or attslot.Offset.vpos or Vector()
|
|
|
|
if slidemod or attslot.SlideAmount then
|
|
offset = LerpVector(delta, (slidemod or attslot.SlideAmount).vmin, (slidemod or attslot.SlideAmount).vmax)
|
|
end
|
|
|
|
offset_ang = k.Offset.vang or Angle(0, 0, 0)
|
|
offset_ang = offset_ang + (atttbl.OffsetAng or Angle(0, 0, 0))
|
|
|
|
offset_ang = k.VMOffsetAng or offset_ang
|
|
|
|
bpos, bang = WorldToLocal(Vector(0, 0, 0), Angle(0, 0, 0), bpos, bang)
|
|
|
|
bpos = bpos + bang:Forward() * offset.x
|
|
bpos = bpos + bang:Right() * offset.y
|
|
bpos = bpos + bang:Up() * offset.z
|
|
|
|
bang:RotateAroundAxis(bang:Right(), offset_ang.p)
|
|
bang:RotateAroundAxis(bang:Up(), -offset_ang.y)
|
|
bang:RotateAroundAxis(bang:Forward(), offset_ang.r)
|
|
|
|
local vpos = Vector()
|
|
|
|
vpos.y = -bpos.x
|
|
vpos.x = bpos.y
|
|
vpos.z = -bpos.z
|
|
|
|
local corpos = (k.CorrectivePos or Vector(0, 0, 0))
|
|
|
|
vpos = vpos + bang:Forward() * corpos.x
|
|
vpos = vpos + bang:Right() * corpos.y
|
|
vpos = vpos + bang:Up() * corpos.z
|
|
|
|
-- vpos = vpos + (bang:Forward() * s.Pos.x)
|
|
-- vpos = vpos - (bang:Right() * s.Pos.y)
|
|
-- vpos = vpos + (bang:Up() * s.Pos.z)
|
|
|
|
vmang:Set(-bang)
|
|
|
|
bang.r = -bang.r
|
|
bang.p = -bang.p
|
|
bang.y = -bang.y
|
|
|
|
corang = k.CorrectiveAng or Angle(0, 0, 0)
|
|
|
|
bang:RotateAroundAxis(bang:Right(), corang.p)
|
|
bang:RotateAroundAxis(bang:Up(), corang.y)
|
|
bang:RotateAroundAxis(bang:Forward(), corang.r)
|
|
|
|
-- vpos = LocalToWorld(s.Pos + Vector(0, self.ExtraSightDist or 0, 0), Angle(0, 0, 0), vpos, bang)
|
|
|
|
-- local vmf = (vmang):Forward():GetNormalized()
|
|
-- local vmr = (vmang):Right():GetNormalized()
|
|
-- local vmu = (vmang):Up():GetNormalized()
|
|
|
|
-- print(" ----- vmf, vmr, vmu")
|
|
-- print(vmf)
|
|
-- print(vmr)
|
|
-- print(vmu)
|
|
|
|
-- vmf = -vmf
|
|
-- vmf.x = -vmf.x
|
|
|
|
-- local r = vmf.y
|
|
-- vmf.y = vmf.z
|
|
-- vmf.z = r
|
|
|
|
-- vmr = -vmr
|
|
-- vmr.y = -vmr.y
|
|
|
|
-- -- local r = vmr.y
|
|
-- -- vmr.y = vmr.z
|
|
-- -- vmr.z = r
|
|
|
|
-- vmu = -vmu
|
|
-- vmu.z = vmu.z
|
|
|
|
-- local evpos = Vector(0, 0, 0)
|
|
|
|
-- evpos = evpos + (vmf * (s.Pos.x + k.CorrectivePos.x))
|
|
-- evpos = evpos - (vmr * (s.Pos.y + (self.ExtraSightDist or 0) + k.CorrectivePos.y))
|
|
-- evpos = evpos + (vmu * (s.Pos.z + k.CorrectivePos.z))
|
|
|
|
-- print(vmang:Forward())
|
|
|
|
local evpos = s.Pos
|
|
|
|
evpos = evpos * (k.VMScale or Vector(1, 1, 1))
|
|
|
|
if atttbl.Holosight and !atttbl.HolosightMagnification then
|
|
evpos = evpos + Vector(0, k.ExtraSightDist or self.ExtraSightDist or 0, 0)
|
|
end
|
|
|
|
evpos = evpos + (k.CorrectivePos or Vector(0, 0, 0))
|
|
|
|
stab.Pos, stab.Ang = vpos, bang
|
|
|
|
stab.EVPos = evpos
|
|
stab.EVAng = s.Ang
|
|
|
|
if s.GlobalPos then
|
|
stab.EVPos = Vector(0, 0, 0)
|
|
stab.Pos = s.Pos
|
|
end
|
|
|
|
if s.GlobalAng then
|
|
stab.Ang = Angle(0, 0, 0)
|
|
end
|
|
|
|
end
|
|
|
|
table.insert(sighttable, stab)
|
|
end
|
|
end
|
|
|
|
if kbi then
|
|
local extra = self.ExtraIrons
|
|
if extra then
|
|
for _, ot in pairs(extra) do
|
|
local t = table.Copy(ot)
|
|
t.IronSight = true
|
|
if bif then
|
|
table.insert(sighttable, 1, t)
|
|
else
|
|
table.insert(sighttable, t)
|
|
end
|
|
end
|
|
end
|
|
|
|
local t = table.Copy(self:GetBuff_Override("Override_IronSightStruct") or self.IronSightStruct)
|
|
t.IronSight = true
|
|
if bif then
|
|
table.insert(sighttable, 1, t)
|
|
else
|
|
table.insert(sighttable, t)
|
|
end
|
|
end
|
|
|
|
self.SightTable = sighttable
|
|
end
|
|
|
|
function SWEP:SwitchActiveSights()
|
|
if table.Count(self.SightTable) == 1 then return end
|
|
|
|
self.ActiveSight = (self.ActiveSight or 1) + 1
|
|
|
|
if self.ActiveSight > table.Count(self.SightTable) then
|
|
self.ActiveSight = 1
|
|
end
|
|
|
|
local asight = self:GetActiveSights()
|
|
|
|
local tbl = self:GetBuff_Hook("Hook_SwitchActiveSights", {active = self.ActiveSight, asight = asight})
|
|
|
|
self.ActiveSight = tbl.active or self.ActiveSight
|
|
|
|
if self.ActiveSight > table.Count(self.SightTable) then
|
|
self.ActiveSight = 1
|
|
end
|
|
|
|
local asight2 = self:GetActiveSights()
|
|
|
|
if asight2.SwitchToSound then
|
|
self:MyEmitSound(asight2.SwitchToSound, 75, math.Rand(95, 105), 0.5, CHAN_VOICE2)
|
|
end
|
|
end
|
|
|
|
function SWEP:GetActiveSights()
|
|
if (self.ActiveSight or 1) > table.Count(self.SightTable) then
|
|
self.ActiveSight = 1
|
|
end
|
|
|
|
if table.Count(self.SightTable) == 0 then
|
|
return self.IronSightStruct
|
|
else
|
|
return self.SightTable[self.ActiveSight or 1]
|
|
end
|
|
end
|
|
|
|
local function ScaleFOVByWidthRatio( fovDegrees, ratio )
|
|
local halfAngleRadians = fovDegrees * ( 0.5 * math.pi / 180 )
|
|
local t = math.tan( halfAngleRadians )
|
|
t = t * ratio
|
|
local retDegrees = ( 180 / math.pi ) * math.atan( t )
|
|
return retDegrees * 2
|
|
end
|
|
|
|
function SWEP:QuickFOVix( fov )
|
|
return ScaleFOVByWidthRatio( fov, (ScrW and ScrW() or 4)/(ScrH and ScrH() or 3)/(4/3) )
|
|
end
|
|
|
|
SWEP.LastTranslateFOV = 0
|
|
function SWEP:TranslateFOV(fov)
|
|
local irons = self:GetActiveSights()
|
|
|
|
if CLIENT and ArcCW.ConVars["dev_benchgun"]:GetBool() then self.CurrentFOV = fov self.CurrentViewModelFOV = fov return fov end
|
|
|
|
self.ApproachFOV = self.ApproachFOV or fov
|
|
self.CurrentFOV = self.CurrentFOV or fov
|
|
|
|
-- Only update every tick (this function is called multiple times per tick)
|
|
if self.LastTranslateFOV == UnPredictedCurTime() then return self.CurrentFOV end
|
|
local timed = UnPredictedCurTime() - self.LastTranslateFOV
|
|
self.LastTranslateFOV = UnPredictedCurTime()
|
|
|
|
local app_vm = self.ViewModelFOV + self:GetOwner():GetInfoNum("arccw_vm_fov", 0)
|
|
if CLIENT then
|
|
app_vm = app_vm * (LocalPlayer():GetFOV()/GetConVar("fov_desired"):GetInt())
|
|
end
|
|
|
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
|
local asight = self:GetActiveSights()
|
|
local mag = asight and asight.ScopeMagnification or 1
|
|
|
|
local delta = math.pow(self:GetSightDelta(), 2)
|
|
|
|
if CLIENT then
|
|
local addads = math.Clamp(ArcCW.ConVars["vm_add_ads"]:GetFloat() or 0, -2, 14)
|
|
local csratio = math.Clamp(GetConVar("arccw_cheapscopesv2_ratio"):GetFloat() or 0, 0, 1)
|
|
local pfov = GetConVar("fov_desired"):GetInt()
|
|
|
|
if ArcCW.ConVars["cheapscopes"]:GetBool() and mag > 1 then
|
|
fov = (pfov / (asight and asight.Magnification or 1)) / (mag / (1 + csratio * mag) + (addads or 0) / 3)
|
|
else
|
|
fov = ( (pfov / (asight and asight.Magnification or 1)) * (1 - delta)) + (GetConVar("fov_desired"):GetInt() * delta)
|
|
end
|
|
|
|
app_vm = irons.ViewModelFOV or 45
|
|
|
|
app_vm = app_vm - (asight.MagnifiedOptic and (addads or 0) * 3 or 0)
|
|
end
|
|
end
|
|
|
|
self.ApproachFOV = fov
|
|
|
|
-- magic number? multiplier of 10 seems similar to previous behavior
|
|
self.CurrentFOV = math.Approach(self.CurrentFOV, self.ApproachFOV, timed * 10 * (self.CurrentFOV - self.ApproachFOV))
|
|
|
|
self.CurrentViewModelFOV = self.CurrentViewModelFOV or self.ViewModelFOV
|
|
self.CurrentViewModelFOV = math.Approach(self.CurrentViewModelFOV, app_vm, timed * 10 * (self.CurrentViewModelFOV - app_vm))
|
|
|
|
return self.CurrentFOV
|
|
end
|
|
|
|
function SWEP:SetShouldHoldType()
|
|
if self:GetCurrentFiremode().Mode == 0 then
|
|
self:SetHoldType(self.HoldtypeHolstered)
|
|
return
|
|
end
|
|
|
|
if IsValid(self:GetOwner()) and self:GetOwner():IsNPC() and self.HoldtypeNPC then
|
|
self:SetHoldType(self.HoldtypeNPC)
|
|
return
|
|
end
|
|
|
|
local ht = "normal"
|
|
|
|
if self:GetState() == ArcCW.STATE_SIGHTS then
|
|
ht = self:GetBuff_Override("Override_HoldtypeSights", self.HoldtypeSights)
|
|
elseif self:GetState() == ArcCW.STATE_SPRINT then
|
|
if self:CanShootWhileSprint() then
|
|
ht = self:GetBuff_Override("Override_HoldtypeSprintShoot", self.HoldtypeSprintShoot) or self:GetBuff_Override("Override_HoldtypeActive", self.HoldtypeActive)
|
|
else
|
|
ht = self:GetBuff_Override("Override_HoldtypeHolstered", self.HoldtypeHolstered)
|
|
end
|
|
elseif self:GetState() == ArcCW.STATE_CUSTOMIZE then
|
|
ht = self:GetBuff_Override("Override_HoldtypeCustomize", self.HoldtypeCustomize)
|
|
elseif self:GetCurrentFiremode().Mode == 0 then
|
|
ht = self:GetBuff_Override("Override_HoldtypeHolstered", self.HoldtypeHolstered)
|
|
elseif self.Throwing and self:GetGrenadePrimed() then
|
|
ht = self:GetBuff_Override("Override_HoldtypeSights", self.HoldtypeSights)
|
|
else
|
|
ht = self:GetBuff_Override("Override_HoldtypeActive", self.HoldtypeActive)
|
|
end
|
|
|
|
self:SetHoldType(ht)
|
|
end
|