mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
888 lines
33 KiB
Lua
888 lines
33 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/
|
|
--]]
|
|
|
|
--[[
|
|
Please, for the love of god, don't create objects in functions that are called multiple times per frame.
|
|
The garbage collector will explode and so will players' comptuters.
|
|
|
|
That means minimize usage of things that generate new objects, including:
|
|
calls to Vector() or Angle(); use vector_origin and angle_zero if the value isn't modified
|
|
arithmetic using +, -, * and / on Vectors and Angles; modifying individual parameters is fine
|
|
functions like Angle:Right() and Vector:Angle(); however functions like Vector:Add() and Angle:Add() are fine
|
|
|
|
Cache them if you use them more than one time!
|
|
]]
|
|
|
|
local mth = math
|
|
local m_appor = mth.Approach
|
|
local m_clamp = mth.Clamp
|
|
local f_lerp = Lerp
|
|
local srf = surface
|
|
SWEP.ActualVMData = false
|
|
local swayxmult, swayymult, swayzmult, swayspeed = 1, 1, 1, 1
|
|
local lookxmult, lookymult = 1, 1
|
|
SWEP.VMPos = Vector()
|
|
SWEP.VMAng = Angle()
|
|
SWEP.VMPosOffset = Vector()
|
|
SWEP.VMAngOffset = Angle()
|
|
SWEP.VMPosOffset_Lerp = Vector()
|
|
SWEP.VMAngOffset_Lerp = Angle()
|
|
SWEP.VMLookLerp = Angle()
|
|
SWEP.StepBob = 0
|
|
SWEP.StepBobLerp = 0
|
|
SWEP.StepRandomX = 1
|
|
SWEP.StepRandomY = 1
|
|
SWEP.LastEyeAng = Angle()
|
|
SWEP.SmoothEyeAng = Angle()
|
|
SWEP.LastVelocity = Vector()
|
|
SWEP.Velocity_Lerp = Vector()
|
|
SWEP.VelocityLastDiff = 0
|
|
SWEP.Breath_Intensity = 1
|
|
SWEP.Breath_Rate = 1
|
|
|
|
-- magic variables
|
|
local sprint_vec1 = Vector(-2, 5, 2)
|
|
local sprint_vec2 = Vector(0, 7, 3)
|
|
local sprint_ang1 = Angle(-15, -15, 0)
|
|
local spring_ang2 = Angle(-15, 15, -22)
|
|
local sight_vec1 = Vector(0, 15, -4)
|
|
local sight_vec2 = Vector(1, 5, -1)
|
|
local sight_ang1 = Angle(0, 0, -45)
|
|
local sight_ang2 = Angle(-5, 0, -10)
|
|
local sextra_vec = Vector(0.0002, 0.001, 0.005)
|
|
|
|
local procdraw_vec = Vector(0, 0, -5)
|
|
local procdraw_ang = Angle(-70, 30, 0)
|
|
local prochol_ang = Angle(-70, 30, 10)
|
|
|
|
local lst = SysTime()
|
|
local function scrunkly()
|
|
local ret = (SysTime() - (lst or SysTime())) * GetConVar("host_timescale"):GetFloat()
|
|
return ret
|
|
end
|
|
|
|
local function LerpC(t, a, b, powa)
|
|
return a + (b - a) * math.pow(t, powa)
|
|
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
|
|
|
|
local function LerpMod2(from, usrobj, dlt, clamp_ang)
|
|
usrobj[1] = f_lerp(dlt, from[1], usrobj[1])
|
|
usrobj[2] = f_lerp(dlt, from[2], usrobj[2])
|
|
usrobj[3] = f_lerp(dlt, from[3], usrobj[3])
|
|
if clamp_ang then
|
|
for i = 1, 3 do usrobj[i] = math.NormalizeAngle(usrobj[i]) end
|
|
end
|
|
end
|
|
|
|
-- debug for testing garbage count
|
|
-- TODO: comment this out or something before actually going into main branch
|
|
local sw = false
|
|
local tries = {}
|
|
local totaltries = 1000
|
|
local sw_start = 0
|
|
local sw_orig = 0
|
|
concommand.Add("arccw_dev_stopwatch", function() tries = {} sw = true end)
|
|
|
|
local function stopwatch(name)
|
|
if !sw then return end
|
|
if name == true then
|
|
local d = (collectgarbage("count") - sw_orig)
|
|
if #tries == 0 then print(" total garbage: " .. d) end
|
|
table.insert(tries, d)
|
|
if #tries == totaltries then
|
|
sw = false
|
|
local average = 0
|
|
for _, v in ipairs(tries) do average = average + v end
|
|
average = average / totaltries
|
|
print("----------------------------------")
|
|
print("average over " .. totaltries .. " tries: " .. average)
|
|
end
|
|
return
|
|
end
|
|
local gb = collectgarbage("count")
|
|
if name then
|
|
if #tries == 0 then print(name .. ": " .. (gb - sw_start)) end
|
|
else
|
|
if #tries == 0 then print("----------------------------------") end
|
|
sw_orig = gb
|
|
end
|
|
sw_start = gb
|
|
end
|
|
|
|
function SWEP:Move_Process(EyePos, EyeAng, velocity)
|
|
local VMPos, VMAng = self.VMPos, self.VMAng
|
|
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
|
|
local VMPosOffset_Lerp, VMAngOffset_Lerp = self.VMPosOffset_Lerp, self.VMAngOffset_Lerp
|
|
local FT = scrunkly()
|
|
local sightedmult = (self:GetState() == ArcCW.STATE_SIGHTS and 0.05) or 1
|
|
local sg = self:GetSightDelta()
|
|
VMPos:Set(EyePos)
|
|
VMAng:Set(EyeAng)
|
|
VMPosOffset.x = math.Clamp(velocity.z * 0.0025, -1, 1) * sightedmult
|
|
VMPosOffset.x = VMPosOffset.x + (velocity.x * 0.001 * sg)
|
|
VMPosOffset.y = math.Clamp(velocity.y * -0.002, -1, 1) * sightedmult
|
|
VMPosOffset.z = math.Clamp(VMPosOffset.x * -2, -4, 4)
|
|
VMPosOffset_Lerp.x = Lerp(8 * FT, VMPosOffset_Lerp.x, VMPosOffset.x)
|
|
VMPosOffset_Lerp.y = Lerp(8 * FT, VMPosOffset_Lerp.y, VMPosOffset.y)
|
|
VMPosOffset_Lerp.z = Lerp(8 * FT, VMPosOffset_Lerp.z, VMPosOffset.z)
|
|
--VMAngOffset.x = math.Clamp(VMPosOffset.x * 8, -4, 4)
|
|
VMAngOffset.y = VMPosOffset.y
|
|
VMAngOffset.z = VMPosOffset.y * 0.5 + (VMPosOffset.x * -5) + (velocity.x * -0.005 * sg)
|
|
VMAngOffset_Lerp.x = LerpC(10 * FT, VMAngOffset_Lerp.x, VMAngOffset.x, 0.75)
|
|
VMAngOffset_Lerp.y = LerpC(5 * FT, VMAngOffset_Lerp.y, VMAngOffset.y, 0.6)
|
|
VMAngOffset_Lerp.z = Lerp(25 * FT, VMAngOffset_Lerp.z, VMAngOffset.z)
|
|
VMPos:Add(VMAng:Up() * VMPosOffset_Lerp.x)
|
|
VMPos:Add(VMAng:Right() * VMPosOffset_Lerp.y)
|
|
VMPos:Add(VMAng:Forward() * VMPosOffset_Lerp.z)
|
|
VMAngOffset_Lerp:Normalize()
|
|
VMAng:Add(VMAngOffset_Lerp)
|
|
end
|
|
|
|
local stepend = math.pi * 4
|
|
|
|
function SWEP:Step_Process(EyePos, EyeAng, velocity)
|
|
|
|
local VMPos, VMAng = self.VMPos, self.VMAng
|
|
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
|
|
local VMPosOffset_Lerp = self.VMPosOffset_Lerp
|
|
local state = self:GetState()
|
|
local sprd = self:GetSprintDelta()
|
|
|
|
if state == ArcCW.STATE_SPRINT and self:SelectAnimation("idle_sprint") and !self:GetReloading() and !self:CanShootWhileSprint() then
|
|
velocity = 0
|
|
else
|
|
velocity = math.min(velocity:Length(), 400) * Lerp(sprd, 1, 1.25)
|
|
end
|
|
|
|
local delta = math.abs(self.StepBob * 2 / stepend - 1)
|
|
local FT = scrunkly() --FrameTime()
|
|
local sightedmult = (state == ArcCW.STATE_SIGHTS and 0.25) or 1
|
|
local sprintmult = (state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() and 2) or 1
|
|
local pronemult = (self:IsProne() and 10) or 1
|
|
local onground = self:GetOwner():OnGround()
|
|
self.StepBob = self.StepBob + (velocity * 0.00015 + (math.pow(delta, 0.01) * 0.03)) * swayspeed * FT * 300
|
|
|
|
if self.StepBob >= stepend then
|
|
self.StepBob = 0
|
|
self.StepRandomX = math.Rand(1, 1.5)
|
|
self.StepRandomY = math.Rand(1, 1.5)
|
|
end
|
|
|
|
if velocity == 0 then
|
|
self.StepBob = 0
|
|
end
|
|
|
|
if onground then
|
|
-- oh no it says sex tra
|
|
local sextra = vector_origin
|
|
if (state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint() and !self:SelectAnimation("idle_sprint")) or true then
|
|
sextra = LerpVector(sprd, vector_origin, sextra_vec)
|
|
end
|
|
|
|
VMPosOffset.x = (math.sin(self.StepBob) * velocity * (0.000375 + sextra.x) * sightedmult * swayxmult) * self.StepRandomX
|
|
VMPosOffset.y = (math.sin(self.StepBob * 0.5) * velocity * (0.0005 + sextra.y) * sightedmult * sprintmult * pronemult * swayymult) * self.StepRandomY
|
|
VMPosOffset.z = math.sin(self.StepBob * 0.75) * velocity * (0.002 + sextra.z) * sightedmult * pronemult * swayzmult
|
|
end
|
|
|
|
VMPosOffset_Lerp.x = Lerp(32 * FT, VMPosOffset_Lerp.x, VMPosOffset.x)
|
|
VMPosOffset_Lerp.y = Lerp(4 * FT, VMPosOffset_Lerp.y, VMPosOffset.y)
|
|
VMPosOffset_Lerp.z = Lerp(2 * FT, VMPosOffset_Lerp.z, VMPosOffset.z)
|
|
VMAngOffset.x = VMPosOffset_Lerp.x * 2
|
|
VMAngOffset.y = VMPosOffset_Lerp.y * -7.5
|
|
VMAngOffset.z = VMPosOffset_Lerp.y * 10
|
|
VMPos:Add(VMAng:Up() * VMPosOffset_Lerp.x)
|
|
VMPos:Add(VMAng:Right() * VMPosOffset_Lerp.y)
|
|
VMPos:Add(VMAng:Forward() * VMPosOffset_Lerp.z)
|
|
VMAng:Add(VMAngOffset)
|
|
end
|
|
|
|
function SWEP:Breath_Health()
|
|
local owner = self:GetOwner()
|
|
if !IsValid(owner) then return end
|
|
local health = owner:Health()
|
|
local maxhealth = owner:GetMaxHealth()
|
|
self.Breath_Intensity = math.Clamp(maxhealth / health, 0, 2)
|
|
self.Breath_Rate = math.Clamp((maxhealth * 0.5) / health, 1, 1.5)
|
|
end
|
|
|
|
function SWEP:Breath_StateMult()
|
|
local owner = self:GetOwner()
|
|
if !IsValid(owner) then return end
|
|
local sightedmult = (self:GetState() == ArcCW.STATE_SIGHTS and 0.05) or 1
|
|
self.Breath_Intensity = self.Breath_Intensity * sightedmult
|
|
end
|
|
|
|
function SWEP:Breath_Process(EyePos, EyeAng)
|
|
local VMPos, VMAng = self.VMPos, self.VMAng
|
|
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
|
|
-- self:Breath_Health() Snaps around when regenerating
|
|
self:Breath_StateMult()
|
|
VMPosOffset.x = (math.sin(CurTime() * 2 * self.Breath_Rate) * 0.1) * self.Breath_Intensity
|
|
VMPosOffset.y = (math.sin(CurTime() * 2.5 * self.Breath_Rate) * 0.025) * self.Breath_Intensity
|
|
VMAngOffset.x = VMPosOffset.x * 1.5
|
|
VMAngOffset.y = VMPosOffset.y * 2
|
|
VMAngOffset.z = VMPosOffset.y * VMPosOffset.x * -40
|
|
VMPos:Add(VMAng:Up() * VMPosOffset.x)
|
|
VMPos:Add(VMAng:Right() * VMPosOffset.y)
|
|
VMAng:Add(VMAngOffset)
|
|
end
|
|
|
|
function SWEP:Look_Process(EyePos, EyeAng, velocity)
|
|
local VMPos, VMAng = self.VMPos, self.VMAng
|
|
local VMPosOffset, VMAngOffset = self.VMPosOffset, self.VMAngOffset
|
|
local FT = scrunkly()
|
|
local sightedmult = (self:GetState() == ArcCW.STATE_SIGHTS and 0.25) or 1
|
|
self.SmoothEyeAng = LerpAngle(0.05, self.SmoothEyeAng, EyeAng - self.LastEyeAng)
|
|
-- local xd, yd = (velocity.z / 10), (velocity.y / 200)
|
|
VMPosOffset.x = -self.SmoothEyeAng.x * -0.5 * sightedmult * lookxmult
|
|
VMPosOffset.y = self.SmoothEyeAng.y * 0.5 * sightedmult * lookymult
|
|
VMAngOffset.x = VMPosOffset.x * 0.75
|
|
VMAngOffset.y = VMPosOffset.y * 2.5
|
|
VMAngOffset.z = VMPosOffset.x * 2 + VMPosOffset.y * -2
|
|
self.VMLookLerp.y = Lerp(FT * 10, self.VMLookLerp.y, VMAngOffset.y * -1.5 + self.SmoothEyeAng.y)
|
|
VMAng.y = VMAng.y - self.VMLookLerp.y
|
|
VMPos:Add(VMAng:Up() * VMPosOffset.x)
|
|
VMPos:Add(VMAng:Right() * VMPosOffset.y)
|
|
VMAng:Add(VMAngOffset)
|
|
end
|
|
|
|
function SWEP:GetVMPosition(EyePos, EyeAng)
|
|
local velocity = self:GetOwner():GetVelocity()
|
|
velocity = WorldToLocal(velocity, angle_zero, vector_origin, EyeAng)
|
|
self:Move_Process(EyePos, EyeAng, velocity)
|
|
stopwatch("Move_Process")
|
|
self:Step_Process(EyePos, EyeAng, velocity)
|
|
stopwatch("Step_Process")
|
|
self:Breath_Process(EyePos, EyeAng)
|
|
stopwatch("Breath_Process")
|
|
self:Look_Process(EyePos, EyeAng, velocity)
|
|
stopwatch("Look_Process")
|
|
self.LastEyeAng = EyeAng
|
|
self.LastEyePos = EyePos
|
|
self.LastVelocity = velocity
|
|
|
|
return self.VMPos, self.VMAng
|
|
end
|
|
|
|
SWEP.TheJ = {posa = Vector(), anga = Angle()}
|
|
local rap_pos = Vector()
|
|
local rap_ang = Angle()
|
|
|
|
local actual
|
|
local target = {pos = Vector(), ang = Angle()}
|
|
|
|
local GunDriverFix = Angle( 0, 90, 90 )
|
|
|
|
function SWEP:GetViewModelPosition(pos, ang)
|
|
if ArcCW.ConVars["dev_benchgun"]:GetBool() then
|
|
if ArcCW.ConVars["dev_benchgun_custom"]:GetString() then
|
|
local bgc = ArcCW.ConVars["dev_benchgun_custom"]:GetString()
|
|
if string.Left(bgc, 6) != "setpos" then return vector_origin, angle_zero end
|
|
|
|
bgc = string.TrimLeft(bgc, "setpos ")
|
|
bgc = string.Replace(bgc, ";setang", "")
|
|
bgc = string.Explode(" ", bgc)
|
|
|
|
return Vector(bgc[1], bgc[2], bgc[3]), Angle(bgc[4], bgc[5], bgc[6])
|
|
else
|
|
return vector_origin, angle_zero
|
|
end
|
|
end
|
|
|
|
stopwatch()
|
|
|
|
local owner = self:GetOwner()
|
|
if !IsValid(owner) or !owner:Alive() then return end
|
|
local FT = scrunkly()
|
|
local CT = CurTime()
|
|
local TargetTick = (1 / FT) / 66.66
|
|
local cdelta = math.Clamp(math.ease.InOutSine((owner:GetViewOffset().z - owner:GetCurrentViewOffset().z) / (owner:GetViewOffset().z - owner:GetViewOffsetDucked().z)),0,1)
|
|
|
|
if TargetTick < 1 then
|
|
FT = FT * TargetTick
|
|
end
|
|
|
|
local vm = LocalPlayer():GetViewModel()
|
|
|
|
local asight = self:GetActiveSights()
|
|
local state = self:GetState()
|
|
local sgtd = self:GetSightDelta()
|
|
local sprd = self:GetSprintDelta()
|
|
|
|
local sprinted = self.Sprinted or state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint()
|
|
local sighted = self.Sighted or state == ArcCW.STATE_SIGHTS
|
|
local holstered = self:GetCurrentFiremode().Mode == 0
|
|
|
|
if game.SinglePlayer() then
|
|
sprinted = state == ArcCW.STATE_SPRINT and !self:CanShootWhileSprint()
|
|
sighted = state == ArcCW.STATE_SIGHTS
|
|
end
|
|
|
|
local oldpos, oldang = Vector(), Angle()
|
|
oldpos:Set(pos)
|
|
oldang:Set(ang)
|
|
ang:Sub(self:GetOurViewPunchAngles())
|
|
|
|
actual = self.ActualVMData or {
|
|
pos = Vector(),
|
|
ang = Angle(),
|
|
down = 1,
|
|
sway = 1,
|
|
bob = 1,
|
|
evpos = Vector(),
|
|
evang = Angle(),
|
|
}
|
|
|
|
local apos, aang = self:GetBuff_Override("Override_ActivePos", self.ActivePos), self:GetBuff_Override("Override_ActiveAng", self.ActiveAng)
|
|
local cpos, cang = self:GetBuff("CrouchPos", true) or apos, self:GetBuff("CrouchAng", true) or aang
|
|
target.down = 1
|
|
target.sway = 2
|
|
target.bob = 2
|
|
|
|
stopwatch("set")
|
|
|
|
if self:InBipod() and self:GetBipodAngle() then
|
|
local bpos = self:GetBuff_Override("Override_InBipodPos", self.InBipodPos)
|
|
target.pos:Set(asight and asight.Pos or apos)
|
|
target.ang:Set(asight and asight.Ang or aang)
|
|
|
|
local BEA = (self.BipodStartAngle or self:GetBipodAngle()) - owner:EyeAngles()
|
|
target.pos:Add(BEA:Right() * bpos.x * self.InBipodMult.x)
|
|
target.pos:Add(BEA:Forward() * bpos.y * self.InBipodMult.y)
|
|
target.pos:Add(BEA:Up() * bpos.z * self.InBipodMult.z)
|
|
target.sway = 0.2
|
|
-- elseif (owner:Crouching() or owner:KeyDown(IN_DUCK)) and !self:GetReloading() then
|
|
-- target.pos:Set(self:GetBuff("CrouchPos", true) or apos)
|
|
-- target.ang:Set(self:GetBuff("CrouchAng", true) or aang)
|
|
elseif self:GetReloading() then
|
|
target.pos:Set(self:GetBuff("ReloadPos", true) or apos)
|
|
target.ang:Set(self:GetBuff("ReloadAng", true) or aang)
|
|
else
|
|
target.pos:Set(apos)
|
|
target.ang:Set(aang)
|
|
LerpMod(target.pos, cpos, cdelta)
|
|
LerpMod(target.ang, cang, cdelta, true)
|
|
end
|
|
if (owner:Crouching() or owner:KeyDown(IN_DUCK)) then target.down = 0 end
|
|
|
|
stopwatch("reload, crouch, bipod")
|
|
|
|
target.pos.x = target.pos.x + ArcCW.ConVars["vm_right"]:GetFloat()
|
|
target.pos.y = target.pos.y + ArcCW.ConVars["vm_forward"]:GetFloat()
|
|
target.pos.z = target.pos.z + ArcCW.ConVars["vm_up"]:GetFloat()
|
|
|
|
target.ang.p = target.ang.p + ArcCW.ConVars["vm_pitch"]:GetFloat()
|
|
target.ang.y = target.ang.y + ArcCW.ConVars["vm_yaw"]:GetFloat()
|
|
target.ang.r = target.ang.r + ArcCW.ConVars["vm_roll"]:GetFloat()
|
|
|
|
if state == ArcCW.STATE_CUSTOMIZE then
|
|
target.down = 1
|
|
target.sway = 3
|
|
target.bob = 1
|
|
local mx, my = input.GetCursorPos()
|
|
mx = 2 * mx / ScrW()
|
|
my = 2 * my / ScrH()
|
|
target.pos:Set(self:GetBuff_Override("Override_CustomizePos", self.CustomizePos))
|
|
target.ang:Set(self:GetBuff_Override("Override_CustomizeAng", self.CustomizeAng))
|
|
target.pos.x = target.pos.x + mx
|
|
target.pos.z = target.pos.z + my
|
|
target.ang.y = target.ang.y + my * 2
|
|
target.ang.r = target.ang.r + mx * 2
|
|
if self.InAttMenu then
|
|
target.ang.y = target.ang.y - 5
|
|
end
|
|
end
|
|
|
|
stopwatch("cust")
|
|
|
|
-- Sprinting
|
|
local hpos, spos = self:GetBuff("HolsterPos", true), self:GetBuff("SprintPos", true)
|
|
local hang, sang = self:GetBuff("HolsterAng", true), self:GetBuff("SprintAng", true)
|
|
do
|
|
local aaaapos = holstered and (hpos or spos) or (spos or hpos)
|
|
local aaaaang = holstered and (hang or sang) or (sang or hang)
|
|
|
|
local sd = (self:GetReloading() and 0) or (self:IsProne() and math.Clamp(owner:GetVelocity():Length() / prone.Config.MoveSpeed, 0, 1)) or (holstered and 1) or (!self:CanShootWhileSprint() and sprd) or 0
|
|
sd = math.pow(math.sin(sd * math.pi * 0.5), 2)
|
|
|
|
local d = math.pow(math.sin(sd * math.pi * 0.5), math.pi)
|
|
local coolilove = d * math.cos(d * math.pi * 0.5)
|
|
|
|
local joffset, jaffset
|
|
if !sprinted then
|
|
joffset = sprint_vec2
|
|
jaffset = spring_ang2
|
|
else
|
|
joffset = sprint_vec1
|
|
jaffset = sprint_ang1
|
|
end
|
|
|
|
LerpMod(target.pos, aaaapos, sd)
|
|
LerpMod(target.ang, aaaaang, sd, true)
|
|
for i = 1, 3 do
|
|
target.pos[i] = target.pos[i] + joffset[i] * coolilove
|
|
target.ang[i] = target.ang[i] + jaffset[i] * coolilove
|
|
end
|
|
|
|
local fu_sprint = (sprinted and self:SelectAnimation("idle_sprint"))
|
|
|
|
target.sway = target.sway * f_lerp(sd, 1, fu_sprint and 0 or 2)
|
|
target.bob = target.bob * f_lerp(sd, 1, fu_sprint and 0 or 2)
|
|
end
|
|
|
|
stopwatch("sprint")
|
|
|
|
-- Sighting
|
|
if asight then
|
|
local delta = sgtd
|
|
delta = math.pow(math.sin(delta * math.pi * 0.5), math.pi)
|
|
local im = asight.Midpoint
|
|
local coolilove = delta * math.cos(delta * math.pi * 0.5)
|
|
|
|
local joffset, jaffset
|
|
if !sighted then
|
|
joffset = sight_vec2
|
|
jaffset = sight_ang2
|
|
else
|
|
joffset = (im and im.Pos or sight_vec1)
|
|
jaffset = (im and im.Ang or sight_ang1)
|
|
end
|
|
|
|
target.pos.z = target.pos.z - 1
|
|
LerpMod2(asight.Pos, target.pos, delta)
|
|
LerpMod2(asight.Ang, target.ang, delta)
|
|
for i = 1, 3 do
|
|
target.pos[i] = target.pos[i] + joffset[i] * coolilove
|
|
target.ang[i] = target.ang[i] + jaffset[i] * coolilove
|
|
end
|
|
|
|
target.evpos = f_lerp(delta, asight.EVPos or vector_origin, vector_origin)
|
|
target.evang = f_lerp(delta, asight.EVAng or angle_zero, angle_zero)
|
|
|
|
target.down = 0
|
|
target.sway = target.sway * f_lerp(delta, 0.1, 1)
|
|
target.bob = target.bob * f_lerp(delta, 0.1, 1)
|
|
end
|
|
|
|
stopwatch("sight")
|
|
|
|
local deg = self:GetBarrelNearWall()
|
|
if deg > 0 and ArcCW.ConVars["vm_nearwall"]:GetBool() then
|
|
LerpMod(target.pos, hpos, deg)
|
|
LerpMod(target.ang, hang, deg)
|
|
target.down = 2 * math.max(sgtd, 0.5)
|
|
end
|
|
|
|
if !isangle(target.ang) then
|
|
target.ang = Angle(target.ang)
|
|
end
|
|
|
|
target.ang.y = target.ang.y + (self:GetFreeAimOffset().y * 0.5)
|
|
target.ang.p = target.ang.p - (self:GetFreeAimOffset().p * 0.5)
|
|
|
|
if self.InProcDraw then
|
|
self.InProcHolster = false
|
|
local delta = m_clamp((CT - self.ProcDrawTime) / (0.5 * self:GetBuff_Mult("Mult_DrawTime")), 0, 1)
|
|
target.pos = LerpVector(delta, procdraw_vec, target.pos)
|
|
target.ang = LerpAngle(delta, procdraw_ang, target.ang)
|
|
target.down = target.down
|
|
target.sway = target.sway
|
|
target.bob = target.bob
|
|
end
|
|
|
|
if self.InProcHolster then
|
|
self.InProcDraw = false
|
|
local delta = 1 - m_clamp((CT - self.ProcHolsterTime) / (0.25 * self:GetBuff_Mult("Mult_DrawTime")), 0, 1)
|
|
target.pos = LerpVector(delta, procdraw_vec, target.pos)
|
|
target.ang = LerpAngle(delta, prochol_ang, target.ang)
|
|
target.down = target.down
|
|
target.sway = target.sway
|
|
target.bob = target.bob
|
|
end
|
|
|
|
if self.InProcBash then
|
|
self.InProcDraw = false
|
|
local mult = self:GetBuff_Mult("Mult_MeleeTime")
|
|
local mtime = self.MeleeTime * mult
|
|
local delta = 1 - m_clamp((CT - self.ProcBashTime) / mtime, 0, 1)
|
|
|
|
local bp, ba
|
|
|
|
if delta > 0.3 then
|
|
bp = self:GetBuff_Override("Override_BashPreparePos", self.BashPreparePos)
|
|
ba = self:GetBuff_Override("Override_BashPrepareAng", self.BashPrepareAng)
|
|
delta = (delta - 0.5) * 2
|
|
else
|
|
bp = self:GetBuff_Override("Override_BashPos", self.BashPos)
|
|
ba = self:GetBuff_Override("Override_BashAng", self.BashAng)
|
|
delta = delta * 2
|
|
end
|
|
|
|
LerpMod2(bp, target.pos, delta)
|
|
LerpMod2(ba, target.ang, delta)
|
|
|
|
target.speed = 10
|
|
|
|
if delta == 0 then
|
|
self.InProcBash = false
|
|
end
|
|
end
|
|
|
|
stopwatch("proc")
|
|
|
|
-- local gunbone, gbslot = self:GetBuff_Override("LHIK_GunDriver")
|
|
-- if gunbone and IsValid(self.Attachments[gbslot].VElement.Model) and self.LHIKGunPos and self.LHIKGunAng then
|
|
-- local magnitude = 1 --Lerp(sgtd, 0.1, 1)
|
|
-- local lhik_model = self.Attachments[gbslot].VElement.Model
|
|
-- local att = lhik_model:GetAttachment(lhik_model:LookupAttachment(gunbone))
|
|
-- local attang = att.Ang
|
|
-- local attpos = att.Pos
|
|
-- attang = lhik_model:WorldToLocalAngles(attang)
|
|
-- attpos = lhik_model:WorldToLocal(attpos)
|
|
-- attang:Sub(self.LHIKGunAng)
|
|
-- attpos:Sub(self.LHIKGunPos)
|
|
-- attang:Mul(magnitude)
|
|
-- attpos:Mul(magnitude)
|
|
-- --target.ang:Add(attang)
|
|
-- --target.pos:Add(attpos)
|
|
-- --debugoverlay.Axis(lhik_model:GetPos() + attpos, att.Ang, 8, FrameTime() * 3, true)
|
|
-- debugoverlay.Axis(lhik_model:GetPos(), att.Ang, 8, FrameTime() * 3, true)
|
|
-- end
|
|
|
|
-- stopwatch("gunbone")
|
|
|
|
local vmhit = self.ViewModel_Hit
|
|
if vmhit then
|
|
if !vmhit:IsZero() then
|
|
target.pos.x = target.pos.x + m_clamp(vmhit.y, -1, 1) * 0.25
|
|
target.pos.y = target.pos.y + vmhit.y
|
|
target.pos.z = target.pos.z + m_clamp(vmhit.x, -1, 1) * 1
|
|
target.ang.x = target.ang.x + m_clamp(vmhit.x, -1, 1) * 5
|
|
target.ang.y = target.ang.y + m_clamp(vmhit.y, -1, 1) * -2
|
|
target.ang.z = target.ang.z + m_clamp(vmhit.z, -1, 1) * 12.5
|
|
end
|
|
|
|
local spd = vmhit:Length() * 5
|
|
vmhit.x = m_appor(vmhit.x, 0, FT * spd)
|
|
vmhit.y = m_appor(vmhit.y, 0, FT * spd)
|
|
vmhit.z = m_appor(vmhit.z, 0, FT * spd)
|
|
end
|
|
|
|
if ArcCW.ConVars["shakevm"]:GetBool() and !engine.IsRecordingDemo() then
|
|
target.pos:Add(VectorRand() * self.RecoilAmount * 0.2 * self.RecoilVMShake)
|
|
end
|
|
|
|
stopwatch("vmhit")
|
|
|
|
local speed = 15 * FT * (game.SinglePlayer() and 1 or 2)
|
|
|
|
LerpMod(actual.pos, target.pos, speed)
|
|
LerpMod(actual.ang, target.ang, speed, true)
|
|
LerpMod(actual.evpos, target.evpos or vector_origin, speed)
|
|
LerpMod(actual.evang, target.evang or angle_zero, speed, true)
|
|
actual.down = f_lerp(speed, actual.down, target.down)
|
|
actual.sway = f_lerp(speed, actual.sway, target.sway)
|
|
actual.bob = f_lerp(speed, actual.bob, target.bob)
|
|
|
|
ApproachMod(actual.pos, target.pos, speed * 0.1)
|
|
ApproachMod(actual.ang, target.ang, speed * 0.1)
|
|
actual.down = m_appor(actual.down, target.down, speed * 0.1)
|
|
|
|
stopwatch("actual -> target")
|
|
|
|
local coolsway = ArcCW.ConVars["vm_coolsway"]:GetBool()
|
|
self.SwayScale = (coolsway and 0) or actual.sway
|
|
self.BobScale = (coolsway and 0) or actual.bob
|
|
|
|
if coolsway then
|
|
swayxmult = ArcCW.ConVars["vm_sway_zmult"]:GetFloat() or 1
|
|
swayymult = ArcCW.ConVars["vm_sway_xmult"]:GetFloat() or 1
|
|
swayzmult = ArcCW.ConVars["vm_sway_ymult"]:GetFloat() or 1
|
|
swayspeed = ArcCW.ConVars["vm_sway_speedmult"]:GetFloat() or 1
|
|
lookxmult = ArcCW.ConVars["vm_look_xmult"]:GetFloat() or 1
|
|
lookymult = ArcCW.ConVars["vm_look_ymult"]:GetFloat() or 1
|
|
|
|
local sd = self:GetSightDelta()
|
|
lookxmult = Lerp(sd, 0, lookxmult)
|
|
lookymult = Lerp(sd, 0, lookymult)
|
|
swayxmult = Lerp(sd, 0, swayxmult)
|
|
swayymult = Lerp(sd, 0, swayymult)
|
|
swayzmult = Lerp(sd, 0, swayzmult)
|
|
swayspeed = Lerp(sd, 0, swayspeed)
|
|
|
|
stopwatch("before vmposition")
|
|
local npos, nang = self:GetVMPosition(oldpos, oldang)
|
|
pos:Set(npos)
|
|
ang:Set(nang)
|
|
end
|
|
|
|
local old_r, old_f, old_u = oldang:Right(), oldang:Forward(), oldang:Up()
|
|
pos:Add(math.min(self.RecoilPunchBack, Lerp(sgtd, self.RecoilPunchBackMaxSights or 1, self.RecoilPunchBackMax)) * -old_f)
|
|
|
|
ang:RotateAroundAxis(old_r, actual.ang.x)
|
|
ang:RotateAroundAxis(old_u, actual.ang.y)
|
|
ang:RotateAroundAxis(old_f, actual.ang.z)
|
|
ang:RotateAroundAxis(old_r, actual.evang.x)
|
|
ang:RotateAroundAxis(old_u, actual.evang.y)
|
|
ang:RotateAroundAxis(old_f, actual.evang.z)
|
|
|
|
local new_r, new_f, new_u = ang:Right(), ang:Forward(), ang:Up()
|
|
old_r:Mul(actual.evpos.x)
|
|
old_f:Mul(actual.evpos.y)
|
|
old_u:Mul(actual.evpos.z)
|
|
pos:Add(old_r)
|
|
pos:Add(old_f)
|
|
pos:Add(old_u)
|
|
new_r:Mul(actual.pos.x)
|
|
new_f:Mul(actual.pos.y)
|
|
new_u:Mul(actual.pos.z)
|
|
pos:Add(new_r)
|
|
pos:Add(new_f)
|
|
pos:Add(new_u)
|
|
|
|
pos.z = pos.z - actual.down
|
|
|
|
ang:Add(self:GetOurViewPunchAngles() * Lerp(sgtd, 1, -1))
|
|
|
|
local gunbone, gbslot = self:GetBuff_Override("LHIK_GunDriver")
|
|
local lhik_model = gbslot and self.Attachments[gbslot].VElement and self.Attachments[gbslot].VElement.Model -- Visual M203 attachment
|
|
local lhik_anim_model = gbslot and self.Attachments[gbslot].GodDriver and self.Attachments[gbslot].GodDriver.Model -- M203 anim and camera
|
|
local lhik_refl_model = gbslot and self.Attachments[gbslot].ReflectDriver and self.Attachments[gbslot].ReflectDriver.Model -- Rifle
|
|
if IsValid(lhik_model) and IsValid(lhik_anim_model) and IsValid(lhik_refl_model) and lhik_anim_model:GetAttachment(lhik_anim_model:LookupAttachment(gunbone)) then
|
|
local att = lhik_anim_model:LookupAttachment(gunbone)
|
|
local offset = lhik_anim_model:GetAttachment(att).Pos
|
|
local affset = lhik_anim_model:GetAttachment(att).Ang
|
|
|
|
affset:Sub( GunDriverFix )
|
|
local r = affset.r
|
|
affset.r = affset.p
|
|
affset.p = -r
|
|
affset.y = -affset.y
|
|
|
|
local anchor = self.Attachments[gbslot].VMOffsetPos
|
|
|
|
local looku = lhik_refl_model:LookupBone( self.Attachments[gbslot].Bone )
|
|
local bonp, bona = lhik_refl_model:GetBonePosition( looku )
|
|
if bonp == lhik_refl_model:GetPos() then
|
|
bonp = lhik_refl_model:GetBoneMatrix( looku ):GetTranslation()
|
|
bona = lhik_refl_model:GetBoneMatrix( looku ):GetAngles()
|
|
end
|
|
|
|
if anchor and bonp then -- Not ready / deploying
|
|
anchor = ( bonp + ( (bona:Forward()*anchor.x) + (bona:Right()*anchor.y) + (bona:Up()*anchor.z) ) )
|
|
|
|
debugoverlay.Axis(anchor, angle_zero, 4, FrameTime(), true)
|
|
|
|
rap_pos, rap_ang = ArcCW.RotateAroundPoint2(pos, ang, anchor, offset, affset)
|
|
rap_pos:Sub(pos)
|
|
rap_ang:Sub(ang)
|
|
|
|
pos:Add(rap_pos)
|
|
ang:Add(rap_ang)
|
|
end
|
|
end
|
|
|
|
self.ActualVMData = actual
|
|
|
|
stopwatch("apply actual")
|
|
|
|
stopwatch(true)
|
|
|
|
lst = SysTime()
|
|
return pos, ang
|
|
end
|
|
|
|
function SWEP:ShouldCheapWorldModel()
|
|
local lp = LocalPlayer()
|
|
if lp:GetObserverMode() == OBS_MODE_IN_EYE and lp:GetObserverTarget() == self:GetOwner() then return true end
|
|
if !IsValid(self:GetOwner()) and !ArcCW.ConVars["att_showground"]:GetBool() then return true end
|
|
|
|
return !ArcCW.ConVars["att_showothers"]:GetBool()
|
|
end
|
|
|
|
local bird = Material("arccw/hud/arccw_bird.png", "mips smooth")
|
|
local iw = 32
|
|
|
|
function SWEP:DrawWorldModel()
|
|
local cvar2d3d = ArcCW.ConVars["2d3d"]:GetInt()
|
|
if !IsValid(self:GetOwner()) and !TTT2
|
|
and (cvar2d3d == 2 or (cvar2d3d == 1 and LocalPlayer():GetEyeTrace().Entity == self))
|
|
and (EyePos() - self:WorldSpaceCenter()):LengthSqr() <= 262144 then -- 512^2
|
|
local ang = LocalPlayer():EyeAngles()
|
|
ang:RotateAroundAxis(ang:Forward(), 180)
|
|
ang:RotateAroundAxis(ang:Right(), 90)
|
|
ang:RotateAroundAxis(ang:Up(), 90)
|
|
cam.Start3D2D(self:WorldSpaceCenter() + Vector(0, 0, 16), ang, 0.1)
|
|
|
|
srf.SetFont("ArcCW_32_Unscaled")
|
|
local w = srf.GetTextSize(self.PrintName)
|
|
srf.SetTextPos(-w / 2 + 2, 2)
|
|
srf.SetTextColor(0, 0, 0, 150)
|
|
srf.DrawText(self.PrintName)
|
|
srf.SetTextPos(-w / 2, 0)
|
|
srf.SetTextColor(255, 255, 255, 255)
|
|
srf.DrawText(self.PrintName)
|
|
|
|
local icons = {}
|
|
for i, slot in pairs(self.Attachments or {}) do
|
|
if slot.Installed then
|
|
local atttbl = ArcCW.AttachmentTable[slot.Installed]
|
|
if !atttbl then continue end
|
|
local icon = atttbl.Icon
|
|
if !icon or icon:IsError() then icon = bird end
|
|
table.insert(icons, icon)
|
|
end
|
|
end
|
|
|
|
local ind = math.min(6, #icons)
|
|
|
|
surface.SetDrawColor(255, 255, 255)
|
|
for i = 1, ind do
|
|
if i == 6 and #icons > 6 then
|
|
local str = "+" .. (#icons - ind)
|
|
local strw = srf.GetTextSize(str)
|
|
srf.SetTextPos(-ind * iw / 2 + (i - 1) * iw + 2 + strw / 2, iw + 14)
|
|
srf.SetTextColor(0, 0, 0, 150)
|
|
srf.DrawText(str)
|
|
srf.SetTextPos(-ind * iw / 2 + (i - 1) * iw + strw / 2, iw + 12)
|
|
srf.SetTextColor(255, 255, 255, 255)
|
|
srf.DrawText(str)
|
|
else
|
|
local icon = icons[i]
|
|
surface.SetMaterial(icon)
|
|
surface.DrawTexturedRect(-ind * iw / 2 + (i - 1) * iw, iw + 12, iw, iw)
|
|
end
|
|
end
|
|
|
|
-- srf.SetFont("ArcCW_24_Unscaled")
|
|
-- local count = self:CountAttachments()
|
|
|
|
-- if count > 0 then
|
|
-- local t = tostring(count) .. " Attachments"
|
|
-- w = srf.GetTextSize(t)
|
|
-- srf.SetTextPos(-w / 2, 32)
|
|
-- srf.SetTextColor(255, 255, 255, 255)
|
|
-- srf.DrawText(t)
|
|
-- end
|
|
|
|
cam.End3D2D()
|
|
end
|
|
|
|
self:DrawCustomModel(true)
|
|
self:DoLaser(true)
|
|
|
|
if self:ShouldGlint() then
|
|
self:DoScopeGlint()
|
|
end
|
|
|
|
if !self.CertainAboutAtts and !self.AttReqSent and !IsValid(self:GetOwner()) then
|
|
self.AttReqSent = true
|
|
-- print(self, "network weapon from cl_viewmodel")
|
|
-- debugoverlay.Cross(self:GetPos(), 8, 10, color_white, true)
|
|
-- debugoverlay.EntityTextAtPosition(self:GetPos(), 1, tostring(self) .. " requesting networking data", 10, color_white)
|
|
net.Start("arccw_rqwpnnet")
|
|
net.WriteEntity(self)
|
|
net.SendToServer()
|
|
end
|
|
end
|
|
|
|
function SWEP:ShouldCheapScope()
|
|
if !ArcCW.ConVars["cheapscopes"]:GetBool() then return end
|
|
end
|
|
|
|
local POSTVMDONE = nil
|
|
local POSTVMDONE_TIME = 0
|
|
|
|
local lst2 = SysTime()
|
|
function SWEP:PreDrawViewModel(vm)
|
|
if ArcCW.VM_OverDraw then return end
|
|
if !vm then return end
|
|
|
|
if self:GetState() == ArcCW.STATE_CUSTOMIZE then
|
|
self:BlurNotWeapon()
|
|
end
|
|
|
|
if ArcCW.ConVars["cheapscopesautoconfig"]:GetBool() then
|
|
local fps = 1 / (SysTime() - lst2)
|
|
lst2 = SysTime()
|
|
local lowfps = fps <= 45
|
|
ArcCW.ConVars["cheapscopes"]:SetBool(lowfps)
|
|
ArcCW.ConVars["cheapscopesautoconfig"]:SetBool(false)
|
|
end
|
|
|
|
local asight = self:GetActiveSights()
|
|
|
|
if asight and ((ArcCW.ConVars["cheapscopes"]:GetBool() and self:GetSightDelta() < 1 and asight.MagnifiedOptic)
|
|
or (self:GetSightDelta() < 1 and asight.ScopeTexture)) then
|
|
-- Necessary to call here since physbullets are not drawn until PreDrawEffects; cheap scope implementation will not allow them to be visible
|
|
-- Introduces a bug when we try to call GetAttachment on the viewmodel in DrawPhysBullets here, so set a workaround variable to not call it
|
|
ArcCW:DrawPhysBullets(true)
|
|
self:FormCheapScope()
|
|
end
|
|
|
|
local coolFOV = self.CurrentViewModelFOV or self.ViewModelFOV
|
|
|
|
if ArcCW.VMInRT then
|
|
local mag = asight.ScopeMagnification
|
|
coolFOV = self.ViewModelFOV - mag * 4 - (ArcCW.ConVars["vm_add_ads"]:GetFloat() * 3 or 0)
|
|
ArcCW.VMInRT = false
|
|
end
|
|
|
|
cam.Start3D(EyePos(), EyeAngles(), self:QuickFOVix(coolFOV), nil, nil, nil, nil, 0.5, 1000)
|
|
cam.IgnoreZ(true)
|
|
self:DrawCustomModel(false)
|
|
self:DoLHIK()
|
|
|
|
if !ArcCW.Overdraw then
|
|
self:DoLaser(false, true)
|
|
end
|
|
|
|
-- patrol
|
|
if POSTVMDONE == false and POSTVMDONE_TIME <= CurTime() then
|
|
POSTVMDONE_TIME = CurTime() + 1
|
|
print( "[ArcCW] Warning: PostDrawViewModel failed response!! cam.End3D errors may be inbound!! You may have an addon conflict!!")
|
|
print( "[ArcCW] Follow the troubleshooting guide at https://github.com/HaodongMo/ArcCW/wiki/Help-&-Troubleshooting#camend3d-errors")
|
|
end
|
|
POSTVMDONE = false
|
|
end
|
|
|
|
function SWEP:PostDrawViewModel()
|
|
POSTVMDONE = true
|
|
if ArcCW.VM_OverDraw then return end
|
|
render.SetBlend(1)
|
|
cam.End3D()
|
|
cam.Start3D(EyePos(), EyeAngles(), self:QuickFOVix(self.CurrentViewModelFOV or self.ViewModelFOV), nil, nil, nil, nil, 0.5, 1000)
|
|
cam.IgnoreZ(true)
|
|
|
|
if ArcCW.Overdraw then
|
|
ArcCW.Overdraw = false
|
|
else
|
|
--self:DoLaser()
|
|
self:DoHolosight()
|
|
end
|
|
|
|
cam.End3D()
|
|
end
|