Files
wnsrc/lua/weapons/arccw_base/sh_think.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

446 lines
16 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/
--]]
if CLIENT then
ArcCW.LastWeapon = nil
end
local vec1 = Vector(1, 1, 1)
local vec0 = vec1 * 0
local ang0 = Angle(0, 0, 0)
local lastUBGL = 0
function SWEP:Think()
if IsValid(self:GetOwner()) and self:GetClass() == "arccw_base" then
self:Remove()
return
end
local owner = self:GetOwner()
if !IsValid(owner) or owner:IsNPC() then return end
if self:GetState() == ArcCW.STATE_DISABLE and !self:GetPriorityAnim() then
self:SetState(ArcCW.STATE_IDLE)
if CLIENT and self.UnReady then
self.UnReady = false
end
end
for i, v in ipairs(self.EventTable) do
for ed, bz in pairs(v) do
if ed <= CurTime() then
if bz.AnimKey and (bz.AnimKey != self.LastAnimKey or bz.StartTime != self.LastAnimStartTime) then
continue
end
self:PlayEvent(bz)
self.EventTable[i][ed] = nil
--print(CurTime(), "Event completed at " .. i, ed)
if table.IsEmpty(v) and i != 1 then self.EventTable[i] = nil --[[print(CurTime(), "No more events at " .. i .. ", killing")]] end
end
end
end
if CLIENT and (!game.SinglePlayer() and IsFirstTimePredicted() or true)
and self:GetOwner() == LocalPlayer() and ArcCW.InvHUD
and !ArcCW.Inv_Hidden and ArcCW.Inv_Fade == 0 then
ArcCW.InvHUD:Remove()
ArcCW.Inv_Fade = 0.01
end
local vm = owner:GetViewModel()
self.BurstCount = self:GetBurstCount()
local sg = self:GetShotgunReloading()
if (sg == 2 or sg == 4) and owner:KeyPressed(IN_ATTACK) then
self:SetShotgunReloading(sg + 1)
elseif (sg >= 2) and self:GetReloadingREAL() <= CurTime() then
self:ReloadInsert((sg >= 4) and true or false)
end
self:InBipod()
if self:GetNeedCycle() and !self.Throwing and !self:GetReloading() and self:GetWeaponOpDelay() < CurTime() and self:GetNextPrimaryFire() < CurTime() and -- Adding this delays bolting if the RPM is too low, but removing it may reintroduce the double pump bug. Increasing the RPM allows you to shoot twice on many multiplayer servers. Sure would be convenient if everything just worked nicely
(!ArcCW.ConVars["clicktocycle"]:GetBool() and (self:GetCurrentFiremode().Mode == 2 or !owner:KeyDown(IN_ATTACK))
or ArcCW.ConVars["clicktocycle"]:GetBool() and (self:GetCurrentFiremode().Mode == 2 or owner:KeyPressed(IN_ATTACK))) then
local anim = self:SelectAnimation("cycle")
anim = self:GetBuff_Hook("Hook_SelectCycleAnimation", anim) or anim
local mult = self:GetBuff_Mult("Mult_CycleTime")
local p = self:PlayAnimation(anim, mult, true, 0, true)
if p then
self:SetNeedCycle(false)
self:SetPriorityAnim(CurTime() + self:GetAnimKeyTime(anim, true) * mult)
end
end
if self:GetGrenadePrimed() and !(owner:KeyDown(IN_ATTACK) or owner:KeyDown(IN_ATTACK2)) and (!game.SinglePlayer() or SERVER) then
self:Throw()
end
if self:GetGrenadePrimed() and self.GrenadePrimeTime > 0 and self.isCooked then
local heldtime = (CurTime() - self.GrenadePrimeTime)
local ft = self:GetBuff_Override("Override_FuseTime") or self.FuseTime
if ft and (heldtime >= ft) and (!game.SinglePlayer() or SERVER) then
self:Throw()
end
end
if IsFirstTimePredicted() and self:GetNextPrimaryFire() < CurTime() and owner:KeyReleased(IN_USE) then
if self:InBipod() then
self:ExitBipod()
else
self:EnterBipod()
end
end
if ((game.SinglePlayer() and SERVER) or (!game.SinglePlayer() and true)) and self:GetBuff_Override("Override_TriggerDelay", self.TriggerDelay) then
if owner:KeyReleased(IN_ATTACK) and self:GetBuff_Override("Override_TriggerCharge", self.TriggerCharge) and self:GetTriggerDelta(true) >= 1 then
self:PrimaryAttack()
else
self:DoTriggerDelay()
end
end
if self:GetCurrentFiremode().RunawayBurst then
if self:GetBurstCount() > 0 and ((game.SinglePlayer() and SERVER) or (!game.SinglePlayer() and true)) then
self:PrimaryAttack()
end
if self:Clip1() < self:GetBuff("AmmoPerShot") or self:GetBurstCount() == self:GetBurstLength() then
self:SetBurstCount(0)
if !self:GetCurrentFiremode().AutoBurst then
self.Primary.Automatic = false
end
end
end
if owner:KeyReleased(IN_ATTACK) then
if !self:GetCurrentFiremode().RunawayBurst then
self:SetBurstCount(0)
self.LastTriggerTime = -1 -- Cannot fire again until trigger released
self.LastTriggerDuration = 0
end
if self:GetCurrentFiremode().Mode < 0 and !self:GetCurrentFiremode().RunawayBurst then
local postburst = self:GetCurrentFiremode().PostBurstDelay or 0
if (CurTime() + postburst) > self:GetWeaponOpDelay() then
--self:SetNextPrimaryFire(CurTime() + postburst)
self:SetWeaponOpDelay(CurTime() + postburst * self:GetBuff_Mult("Mult_PostBurstDelay") + self:GetBuff_Add("Add_PostBurstDelay"))
end
end
end
if owner and owner:GetInfoNum("arccw_automaticreload", 0) == 1 and self:Clip1() == 0 and !self:GetReloading() and CurTime() > self:GetNextPrimaryFire() + 0.2 then
self:Reload()
end
if (!(self:GetBuff_Override("Override_ReloadInSights") or self.ReloadInSights) and (self:GetReloading() or owner:KeyDown(IN_RELOAD))) then
if !(self:GetBuff_Override("Override_ReloadInSights") or self.ReloadInSights) and self:GetReloading() then
self:ExitSights()
end
end
if self:GetBuff_Hook("Hook_ShouldNotSight") and (self.Sighted or self:GetState() == ArcCW.STATE_SIGHTS) then
self:ExitSights()
elseif self:GetHolster_Time() > 0 then
self:ExitSights()
else
-- no it really doesn't, past me
local sighted = self:GetState() == ArcCW.STATE_SIGHTS
local toggle = owner:GetInfoNum("arccw_toggleads", 0) >= 1
local suitzoom = owner:KeyDown(IN_ZOOM)
local sp_cl = game.SinglePlayer() and CLIENT
-- if in singleplayer, client realm should be completely ignored
if toggle and !sp_cl then
if owner:KeyPressed(IN_ATTACK2) then
if sighted then
self:ExitSights()
elseif !suitzoom then
self:EnterSights()
end
elseif suitzoom and sighted then
self:ExitSights()
end
elseif !toggle then
if (owner:KeyDown(IN_ATTACK2) and !suitzoom) and !sighted then
self:EnterSights()
elseif (!owner:KeyDown(IN_ATTACK2) or suitzoom) and sighted then
self:ExitSights()
end
end
end
if (!game.SinglePlayer() and IsFirstTimePredicted()) or (game.SinglePlayer() and true) then
if self:InSprint() and (self:GetState() != ArcCW.STATE_SPRINT) then
self:EnterSprint()
elseif !self:InSprint() and (self:GetState() == ArcCW.STATE_SPRINT) then
self:ExitSprint()
end
end
if game.SinglePlayer() or IsFirstTimePredicted() then
self:SetSightDelta(math.Approach(self:GetSightDelta(), self:GetState() == ArcCW.STATE_SIGHTS and 0 or 1, FrameTime() / self:GetSightTime()))
self:SetSprintDelta(math.Approach(self:GetSprintDelta(), self:GetState() == ArcCW.STATE_SPRINT and 1 or 0, FrameTime() / self:GetSprintTime()))
end
if CLIENT and (game.SinglePlayer() or IsFirstTimePredicted()) then
self:ProcessRecoil()
end
if CLIENT and IsValid(vm) then
for i = 1, vm:GetBoneCount() do
vm:ManipulateBoneScale(i, vec1)
end
for i, k in pairs(self:GetBuff_Override("Override_CaseBones", self.CaseBones) or {}) do
if !isnumber(i) then continue end
for _, b in pairs(istable(k) and k or {k}) do
local bone = vm:LookupBone(b)
if !bone then continue end
if self:GetVisualClip() >= i then
vm:ManipulateBoneScale(bone, vec1)
else
vm:ManipulateBoneScale(bone, vec0)
end
end
end
for i, k in pairs(self:GetBuff_Override("Override_BulletBones", self.BulletBones) or {}) do
if !isnumber(i) then continue end
for _, b in pairs(istable(k) and k or {k}) do
local bone = vm:LookupBone(b)
if !bone then continue end
if self:GetVisualBullets() >= i then
vm:ManipulateBoneScale(bone, vec1)
else
vm:ManipulateBoneScale(bone, vec0)
end
end
end
for i, k in pairs(self:GetBuff_Override("Override_StripperClipBones", self.StripperClipBones) or {}) do
if !isnumber(i) then continue end
for _, b in pairs(istable(k) and k or {k}) do
local bone = vm:LookupBone(b)
if !bone then continue end
if self:GetVisualLoadAmount() >= i then
vm:ManipulateBoneScale(bone, vec1)
else
vm:ManipulateBoneScale(bone, vec0)
end
end
end
end
self:DoHeat()
self:ThinkFreeAim()
-- if CLIENT then
-- if !IsValid(ArcCW.InvHUD) then
-- gui.EnableScreenClicker(false)
-- end
-- if self:GetState() != ArcCW.STATE_CUSTOMIZE then
-- self:CloseCustomizeHUD()
-- else
-- self:OpenCustomizeHUD()
-- end
-- end
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
if atttbl.DamagePerSecond then
local dmg = atttbl.DamagePerSecond * FrameTime()
self:DamageAttachment(i, dmg)
end
end
if CLIENT then
self:DoOurViewPunch()
end
if self.Throwing and self:Clip1() == 0 and self:Ammo1() > 0 then
self:SetClip1(1)
owner:SetAmmo(self:Ammo1() - 1, self.Primary.Ammo)
end
-- self:RefreshBGs()
if self:GetMagUpIn() != 0 and CurTime() > self:GetMagUpIn() then
self:ReloadTimed()
self:SetMagUpIn( 0 )
end
if self:HasBottomlessClip() and self:Clip1() != ArcCW.BottomlessMagicNumber then
self:Unload()
self:SetClip1(ArcCW.BottomlessMagicNumber)
elseif !self:HasBottomlessClip() and self:Clip1() == ArcCW.BottomlessMagicNumber then
self:SetClip1(0)
end
-- Performing traces in rendering contexts seem to cause flickering with c_hands that have QC attachments(?)
-- Since we need to run the trace every tick anyways, do it here instead
if CLIENT then
self:BarrelHitWall()
end
self:GetBuff_Hook("Hook_Think")
-- Running this only serverside in SP breaks animation processing and causes CheckpointAnimation to !reset.
--if SERVER or !game.SinglePlayer() then
self:ProcessTimers()
--end
-- Only reset to idle if we don't need cycle. empty idle animation usually doesn't play nice
if self:GetNextIdle() != 0 and self:GetNextIdle() <= CurTime() and !self:GetNeedCycle()
and self:GetHolster_Time() == 0 and self:GetShotgunReloading() == 0 then
self:SetNextIdle(0)
self:PlayIdleAnimation(true)
end
if self:GetUBGLDebounce() and !self:GetOwner():KeyDown(IN_RELOAD) then
self:SetUBGLDebounce( false )
end
end
local lst = SysTime()
function SWEP:ProcessRecoil()
local owner = self:GetOwner()
local ft = (SysTime() - (lst or SysTime())) * GetConVar("host_timescale"):GetFloat()
local newang = owner:EyeAngles()
-- local r = self.RecoilAmount -- self:GetNWFloat("recoil", 0)
-- local rs = self.RecoilAmountSide -- self:GetNWFloat("recoilside", 0)
local ra = Angle(ang0)
ra = ra + (self:GetBuff_Override("Override_RecoilDirection", self.RecoilDirection) * self.RecoilAmount * 0.5)
ra = ra + (self:GetBuff_Override("Override_RecoilDirectionSide", self.RecoilDirectionSide) * self.RecoilAmountSide * 0.5)
newang = newang - ra
local rpb = self.RecoilPunchBack
local rps = self.RecoilPunchSide
local rpu = self.RecoilPunchUp
if rpb != 0 then
self.RecoilPunchBack = math.Approach(rpb, 0, ft * rpb * 10)
end
if rps != 0 then
self.RecoilPunchSide = math.Approach(rps, 0, ft * rps * 5)
end
if rpu != 0 then
self.RecoilPunchUp = math.Approach(rpu, 0, ft * rpu * 5)
end
lst = SysTime()
end
function SWEP:InSprint()
local owner = self:GetOwner()
local sm = self.SpeedMult * self:GetBuff_Mult("Mult_SpeedMult") * self:GetBuff_Mult("Mult_MoveSpeed")
sm = math.Clamp(sm, 0, 1)
local sprintspeed = owner:GetRunSpeed() * sm
local walkspeed = owner:GetWalkSpeed() * sm
local curspeed = owner:GetVelocity():Length()
if TTT2 and owner.isSprinting == true then
return (owner.sprintProgress or 0) > 0 and owner:KeyDown(IN_SPEED) and !owner:Crouching() and curspeed > walkspeed and owner:OnGround()
end
if !owner:KeyDown(IN_SPEED) or !owner:KeyDown(IN_FORWARD+IN_MOVELEFT+IN_MOVERIGHT+IN_BACK) then return false end
if !owner:OnGround() then return false end
if owner:Crouching() then return false end
if curspeed < Lerp(0.5, walkspeed, sprintspeed) then
-- provide some grace time so changing directions won't immediately exit sprint
self.LastExitSprintCheck = self.LastExitSprintCheck or CurTime()
if self.LastExitSprintCheck < CurTime() - 0.25 then
return false
end
else
self.LastExitSprintCheck = nil
end
return true
end
function SWEP:IsTriggerHeld()
return self:GetOwner():KeyDown(IN_ATTACK) and (self:CanShootWhileSprint() or (!self.Sprinted or self:GetState() != ArcCW.STATE_SPRINT)) and (self:GetHolster_Time() < CurTime()) and !self:GetPriorityAnim()
end
SWEP.LastTriggerTime = 0
SWEP.LastTriggerDuration = 0
function SWEP:GetTriggerDelta(noheldcheck)
if self.LastTriggerTime <= 0 or (!noheldcheck and !self:IsTriggerHeld()) then return 0 end
return math.Clamp((CurTime() - self.LastTriggerTime) / self.LastTriggerDuration, 0, 1)
end
function SWEP:DoTriggerDelay()
local shouldHold = self:IsTriggerHeld()
local reserve = self:HasBottomlessClip() and self:Ammo1() or self:Clip1()
if self.LastTriggerTime == -1 or (!self.TriggerPullWhenEmpty and (reserve < self:GetBuff("AmmoPerShot"))) and self:GetNextPrimaryFire() < CurTime() then
if !shouldHold then
self.LastTriggerTime = 0 -- Good to fire again
self.LastTriggerDuration = 0
end
return
end
if self:GetBurstCount() > 0 and self:GetCurrentFiremode().Mode == 1 then
self.LastTriggerTime = -1 -- Cannot fire again until trigger released
self.LastTriggerDuration = 0
elseif self:GetNextPrimaryFire() < CurTime() and self.LastTriggerTime > 0 and !shouldHold then
-- Attack key is released. Stop the animation and clear progress
local anim = self:SelectAnimation("untrigger")
if anim then
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_TriggerDelayTime"), true, 0)
end
self.LastTriggerTime = 0
self.LastTriggerDuration = 0
self:GetBuff_Hook("Hook_OnTriggerRelease")
elseif self:GetNextPrimaryFire() < CurTime() and self.LastTriggerTime == 0 and shouldHold then
-- We haven't played the animation yet. Pull it!
local anim = self:SelectAnimation("trigger")
self:PlayAnimation(anim, self:GetBuff_Mult("Mult_TriggerDelayTime"), true, 0, nil, nil, true) -- need to overwrite sprint up
self.LastTriggerTime = CurTime()
self.LastTriggerDuration = self:GetAnimKeyTime(anim, true) * self:GetBuff_Mult("Mult_TriggerDelayTime")
self:GetBuff_Hook("Hook_OnTriggerHeld")
end
end