--[[ | 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/ --]] -- Copyright (c) 2018-2020 TFA Base Devs -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- The above copyright notice and this permission notice shall be included in all -- copies or substantial portions of the Software. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- SOFTWARE. local sp = game.SinglePlayer() SWEP.Locomotion_Data_Queued = nil local ServersideLooped = { [ACT_VM_FIDGET] = true, [ACT_VM_FIDGET_EMPTY] = true } --[ACT_VM_IDLE] = true, --[ACT_VM_IDLE_EMPTY] = true, --[ACT_VM_IDLE_SILENCED] = true local d, pbr -- Override this after SWEP:Initialize, for example, in attachments SWEP.BaseAnimations = { ["draw_first"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRAW_DEPLOYED, ["enabled"] = nil --Manually force a sequence to be enabled }, ["draw"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRAW }, ["draw_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRAW_EMPTY }, ["draw_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRAW_SILENCED }, ["shoot1"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_PRIMARYATTACK }, ["shoot1_last"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_PRIMARYATTACK_EMPTY }, ["shoot1_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRYFIRE }, ["shoot1_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_PRIMARYATTACK_SILENCED }, ["shoot1_silenced_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRYFIRE_SILENCED or 0 }, ["shoot1_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_PRIMARYATTACK_1 }, ["shoot2"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_SECONDARYATTACK }, ["shoot2_last"] = { ["type"] = TFA.Enum.ANIMATION_SEQ, --Sequence or act ["value"] = "shoot2_last" }, ["shoot2_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DRYFIRE }, ["shoot2_silenced"] = { ["type"] = TFA.Enum.ANIMATION_SEQ, --Sequence or act ["value"] = "shoot2_silenced" }, ["shoot2_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_ISHOOT_M203 }, ["idle"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_IDLE }, ["idle_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_IDLE_EMPTY }, ["idle_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_IDLE_SILENCED }, ["reload"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_RELOAD }, ["reload_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_RELOAD_EMPTY }, ["reload_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_RELOAD_SILENCED }, ["reload_shotgun_start"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_SHOTGUN_RELOAD_START }, ["reload_shotgun_finish"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_SHOTGUN_RELOAD_FINISH }, ["reload_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_VM_RELOAD_ADS }, ["reload_empty_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_VM_RELOAD_EMPTY_ADS }, ["reload_silenced_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_VM_RELOAD_SILENCED_ADS }, ["reload_shotgun_start_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_SHOTGUN_RELOAD_START_ADS }, ["reload_shotgun_finish_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, ["value"] = ACT_SHOTGUN_RELOAD_FINISH_ADS }, ["holster"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_HOLSTER }, ["holster_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_HOLSTER_EMPTY }, ["holster_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_HOLSTER_SILENCED }, ["silencer_attach"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_ATTACH_SILENCER }, ["silencer_detach"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_DETACH_SILENCER }, ["rof"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_FIREMODE }, ["rof_is"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_IFIREMODE }, ["bash"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_HITCENTER }, ["bash_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_HITCENTER2 }, ["bash_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_MISSCENTER }, ["bash_empty_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_MISSCENTER2 }, ["inspect"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_FIDGET }, ["inspect_empty"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_FIDGET_EMPTY }, ["inspect_silenced"] = { ["type"] = TFA.Enum.ANIMATION_ACT, --Sequence or act ["value"] = ACT_VM_FIDGET_SILENCED } } SWEP.Animations = {} function SWEP:InitializeAnims() local self2 = self:GetTable() setmetatable(self2.Animations, { __index = function(t, k) return self2.BaseAnimations[k] end }) end function SWEP:BuildAnimActivities() local self2 = self:GetTable() self2.AnimationActivities = self2.AnimationActivities or {} for k, v in pairs(self2.BaseAnimations) do if v.value then self2.AnimationActivities[v.value] = k end local kvt = self2.GetStatL(self, "Animations." .. k) if kvt.value then self2.AnimationActivities[kvt.value] = k end end for k, _ in pairs(self2.Animations) do local kvt = self2.GetStatL(self, "Animations." .. k) if kvt.value then self2.AnimationActivities[kvt.value] = k end end end function SWEP:GetActivityEnabled(act) local self2 = self:GetTable() local stat = self2.GetStatL(self, "SequenceEnabled." .. act) if stat then return stat end if not self2.AnimationActivities then self:BuildAnimActivities() end local keysel = self2.AnimationActivities[act] or "" local kv = self2.GetStatL(self, "Animations." .. keysel) if not kv then return false end if kv["enabled"] then return kv["enabled"] else return false end end function SWEP:ChooseAnimation(keyOrData) local self2 = self:GetTable() local data if isstring(keyOrData) then data = self2.GetStatL(self, "Animations." .. keyOrData) elseif istable(keyOrData) then data = keyOrData else error("Unknown value type " .. type(keyOrData) .. " passed!") end if not data then return 0, 0 end if not data["type"] then return 0, 0 end if not data["value"] then return 0, 0 end local retType, retValue = data["type"], data["value"] if self:Clip1() <= 0 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_empty then retValue = data.value_empty retType = data.type_empty or retType end end if self:Clip1() == 1 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_last then retValue = data.value_last retType = data.type_last or retType end end if self2.GetSilenced(self) then local previousRetType = retType if data.value_sil then retValue = data.value_sil retType = data.type_sil or previousRetType end if self:Clip1() <= 0 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_sil_empty then retValue = data.value_sil_empty retType = data.type_sil_empty or previousRetType end end end if self:GetIronSights() then local previousRetType = retType if data.value_is then retValue = data.value_is retType = data.type_is or previousRetType end if self:Clip1() <= 0 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_is_empty then retValue = data.value_is_empty retType = data.type_is_empty or previousRetType end end if self:Clip1() == 1 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_is_last then retValue = data.value_is_last retType = data.type_is_last or previousRetType end end if self2.GetSilenced(self) then if data.value_is_sil then retValue = data.value_is_sil retType = data.type_is_sil or previousRetType end if self:Clip1() <= 0 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_is_sil_empty then retValue = data.value_is_sil_empty retType = data.type_is_sil_empty or previousRetType end end if self:Clip1() == 1 and self2.GetStatL(self, "Primary.ClipSize") >= 0 then if data.value_is_sil_last then retValue = data.value_is_sil_last retType = data.type_is_sil_last or previousRetType end end end end if retType == TFA.Enum.ANIMATION_ACT and isstring(retValue) then retValue = tonumber(retValue) or -1 elseif retType == TFA.Enum.ANIMATION_SEQ and isstring(retValue) then retValue = self2.OwnerViewModel:LookupSequence(retValue) end return retType, retValue end function SWEP:GetAnimationRate(ani, animationType) local self2 = self:GetTable() local rate = 1 if not ani or ani < 0 or not self:VMIV() then return rate end local nm if animationType == TFA.Enum.ANIMATION_ACT or animationType == nil then nm = self2.OwnerViewModel:GetSequenceName(self2.OwnerViewModel:SelectWeightedSequence(ani)) elseif isnumber(ani) then nm = self2.OwnerViewModel:GetSequenceName(ani) elseif isstring(ani) then nm = ani else error("ani argument is typeof " .. type(ani)) end local sqto = self2.GetStatL(self, "SequenceTimeOverride." .. nm) or self2.GetStatL(self, "SequenceTimeOverride." .. (ani or "0")) local sqro = self2.GetStatL(self, "SequenceRateOverride." .. nm) or self2.GetStatL(self, "SequenceRateOverride." .. (ani or "0")) if sqro then rate = rate * sqro elseif sqto then local t = self:GetActivityLengthRaw(ani, false) if t then rate = rate * t / sqto end end rate = hook.Run("TFA_AnimationRate", self, ani, rate) or rate return rate end function SWEP:SendViewModelAnim(act, rate, targ, blend) local self2 = self:GetTable() local vm = self2.OwnerViewModel if rate and not targ then rate = math.max(rate, 0.0001) end if not rate then rate = 1 end if targ then rate = rate / self:GetAnimationRate(act) else rate = rate * self:GetAnimationRate(act) end if act < 0 then return false, act end if not self:VMIV() then return false, act end local seq = vm:SelectWeightedSequenceSeeded(act, self:GetSeedIrradical()) if seq < 0 then if act == ACT_VM_IDLE_EMPTY then seq = vm:SelectWeightedSequenceSeeded(ACT_VM_IDLE, self:GetSeedIrradical()) elseif act == ACT_VM_PRIMARYATTACK_EMPTY then seq = vm:SelectWeightedSequenceSeeded(ACT_VM_PRIMARYATTACK, self:GetSeedIrradical()) else return false, 0 end if seq < 0 then return false, act end end local preLastActivity = self:GetLastActivity() --local preLastSequence = self:GetLastActivity() self:SetLastActivity(act) self:SetLastSequence(seq) self:ResetEvents() if preLastActivity == act and ServersideLooped[act] then self:ChooseIdleAnim() d = vm:SequenceDuration(seq) pbr = targ and (d / (rate or 1)) or (rate or 1) if IsValid(self) then if blend == nil then blend = self2.Idle_Smooth end self:SetNextIdleAnim(CurTime() + d / pbr - blend) end if IsFirstTimePredicted() then timer.Simple(0, function() vm:SendViewModelMatchingSequence(seq) d = vm:SequenceDuration() pbr = targ and (d / (rate or 1)) or (rate or 1) vm:SetPlaybackRate(pbr) if IsValid(self) then if blend == nil then blend = self2.Idle_Smooth end self:SetNextIdleAnim(CurTime() + d / pbr - blend) self:SetLastActivity(act) end end) end else if seq >= 0 then vm:SendViewModelMatchingSequence(seq) end d = vm:SequenceDuration() pbr = targ and (d / (rate or 1)) or (rate or 1) vm:SetPlaybackRate(pbr) if blend == nil then blend = self2.Idle_Smooth end self:SetNextIdleAnim(CurTime() + math.max(d / pbr - blend, self2.Idle_Smooth)) end return true, act end function SWEP:SendViewModelSeq(seq, rate, targ, blend) local self2 = self:GetTable() local seqold = seq if not self:VMIV() then return false, 0 end local vm = self2.OwnerViewModel if isstring(seq) then seq = vm:LookupSequence(seq) or 0 end local act = vm:GetSequenceActivity(seq) if self2.SequenceRateOverride[seqold] then rate = self2.SequenceRateOverride[seqold] targ = false elseif self2.SequenceRateOverride[act] then rate = self2.SequenceRateOverride[act] targ = false elseif self2.SequenceTimeOverride[seqold] then rate = self2.SequenceTimeOverride[seqold] targ = true elseif self2.SequenceTimeOverride[act] then rate = self2.SequenceTimeOverride[act] targ = true end if not rate then rate = 1 end if targ then rate = rate / self:GetAnimationRate(seq, TFA.Enum.ANIMATION_SEQ) else rate = rate * self:GetAnimationRate(seq, TFA.Enum.ANIMATION_SEQ) end if seq < 0 then return false, seq end local preLastActivity = self:GetLastActivity() --local preLastSequence = self:GetLastSequence() self:SetLastActivity(act) self:SetLastSequence(seq) self:ResetEvents() if preLastActivity == act and ServersideLooped[act] then vm:SendViewModelMatchingSequence(act == 0 and 1 or 0) vm:SetPlaybackRate(0) vm:SetCycle(0) self:SetNextIdleAnim(CurTime() + 0.03) if IsFirstTimePredicted() then timer.Simple(0, function() vm:SendViewModelMatchingSequence(seq) d = vm:SequenceDuration() pbr = targ and (d / (rate or 1)) or (rate or 1) vm:SetPlaybackRate(pbr) if IsValid(self) then if blend == nil then blend = self2.Idle_Smooth end self:SetNextIdleAnim(CurTime() + d / pbr - blend) self:SetLastActivity(act) end end) end else if seq >= 0 then vm:SendViewModelMatchingSequence(seq) end d = vm:SequenceDuration() pbr = targ and (d / (rate or 1)) or (rate or 1) vm:SetPlaybackRate(pbr) if IsValid(self) then if blend == nil then blend = self2.Idle_Smooth end self:SetNextIdleAnim(CurTime() + d / pbr - blend) end end return true, seq end function SWEP:PlayAnimation(data, fade, rate, targ) local self2 = self:GetTable() if not self:VMIV() then return end if not data then return false, -1 end local ttype, tval = self:ChooseAnimation(data) if ttype == TFA.Enum.ANIMATION_SEQ then local success, activityID = self:SendViewModelSeq(tval, rate or 1, targ, fade or (data.transition and self2.Idle_Blend or self2.Idle_Smooth)) return success, activityID, TFA.Enum.ANIMATION_SEQ end local success, activityID = self:SendViewModelAnim(tval, rate or 1, targ, fade or (data.transition and self2.Idle_Blend or self2.Idle_Smooth)) return success, activityID, TFA.Enum.ANIMATION_ACT end --[[ Function Name: Locomote Syntax: self:Locomote( flip ironsights, new is, flip sprint, new sprint, flip walk, new walk). Returns: Notes: Purpose: Animation / Utility ]] local tldata function SWEP:Locomote(flipis, is, flipsp, spr, flipwalk, walk, flipcust, cust) local self2 = self:GetTable() if not (flipis or flipsp or flipwalk or flipcust) then return end if not (self:GetStatus() == TFA.Enum.STATUS_IDLE or (self:GetStatus() == TFA.Enum.STATUS_SHOOTING and self:CanInterruptShooting())) then return end tldata = nil if flipis then if is and self2.GetStatL(self, "IronAnimation.in") then tldata = self2.GetStatL(self, "IronAnimation.in", tldata) elseif self2.GetStatL(self, "IronAnimation.out") and not flipsp then tldata = self2.GetStatL(self, "IronAnimation.out", tldata) end end if flipsp then if spr and self2.GetStatL(self, "SprintAnimation.in") then tldata = self2.GetStatL(self, "SprintAnimation.in", tldata) elseif self2.GetStatL(self, "SprintAnimation.out") and not flipis and not spr then tldata = self2.GetStatL(self, "SprintAnimation.out", tldata) end end if flipwalk and not is then if walk and self2.GetStatL(self, "WalkAnimation.in") then tldata = self2.GetStatL(self, "WalkAnimation.in", tldata) elseif self2.GetStatL(self, "WalkAnimation.out") and (not flipis and not flipsp and not flipcust) and not walk then tldata = self2.GetStatL(self, "WalkAnimation.out", tldata) end end if flipcust then if cust and self2.GetStatL(self, "CustomizeAnimation.in") then tldata = self2.GetStatL(self, "CustomizeAnimation.in", tldata) elseif self2.GetStatL(self, "CustomizeAnimation.out") and (not flipis and not flipsp and not flipwalk) and not cust then tldata = self2.GetStatL(self, "CustomizeAnimation.out", tldata) end end if tldata then return self:PlayAnimation(tldata) end return false, -1, TFA.Enum.ANIMATION_SEQ end function SWEP:LocomoteOrIdle(...) local success, animID, animType = self:Locomote(...) if not success then return self:SetNextIdleAnim(-1) end return success, animID, animType end --[[ Function Name: ChooseDrawAnim Syntax: self:ChooseDrawAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Purpose: Animation / Utility ]] SWEP.IsFirstDeploy = true local function PlayChosenAnimation(self, typev, tanim, ...) local fnName = typev == TFA.Enum.ANIMATION_SEQ and "SendViewModelSeq" or "SendViewModelAnim" local a, b = self[fnName](self, tanim, ...) return a, b, typev end SWEP.PlayChosenAnimation = PlayChosenAnimation local success, tanim, typev function SWEP:ChooseDrawAnim() local self2 = self:GetTable() if not self:VMIV() then return end --self:ResetEvents() tanim = ACT_VM_DRAW success = true if self2.IsFirstDeploy and CurTime() > (self2.LastDeployAnim or CurTime()) + 0.1 then self2.IsFirstDeploy = false end if self:GetActivityEnabled(ACT_VM_DRAW_EMPTY) and self:IsEmpty1() then typev, tanim = self:ChooseAnimation("draw_empty") elseif (self:GetActivityEnabled(ACT_VM_DRAW_DEPLOYED) or self2.FirstDeployEnabled) and self2.IsFirstDeploy then typev, tanim = self:ChooseAnimation("draw_first") elseif self:GetActivityEnabled(ACT_VM_DRAW_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation("draw_silenced") else typev, tanim = self:ChooseAnimation("draw") end self2.LastDeployAnim = CurTime() return PlayChosenAnimation(self, typev, tanim) end function SWEP:ResetFirstDeploy() local self2 = self:GetTable() self2.IsFirstDeploy = true self2.LastDeployAnim = math.huge end --[[ Function Name: ChooseInspectAnim Syntax: self:ChooseInspectAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Purpose: Animation / Utility ]] -- function SWEP:ChooseInspectAnim() local self2 = self:GetTable() if not self:VMIV() then return end if self:GetActivityEnabled(ACT_VM_FIDGET_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation("inspect_silenced") elseif self:GetActivityEnabled(ACT_VM_FIDGET_EMPTY) and self:IsEmpty1() then typev, tanim = self:ChooseAnimation("inspect_empty") elseif self2.InspectionActions then tanim = self2.InspectionActions[self:SharedRandom(1, #self2.InspectionActions, "Inspect")] elseif self:GetActivityEnabled(ACT_VM_FIDGET) then typev, tanim = self:ChooseAnimation("inspect") else typev, tanim = self:ChooseAnimation("idle") success = false end return PlayChosenAnimation(self, typev, tanim) end --[[ Function Name: ChooseHolsterAnim Syntax: self:ChooseHolsterAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Purpose: Animation / Utility ]] -- function SWEP:ChooseHolsterAnim() local self2 = self:GetTable() if not self:VMIV() then return end if self:GetActivityEnabled(ACT_VM_HOLSTER_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation("holster_silenced") elseif self:GetActivityEnabled(ACT_VM_HOLSTER_EMPTY) and self:IsEmpty1() then typev, tanim = self:ChooseAnimation("holster_empty") elseif self:GetActivityEnabled(ACT_VM_HOLSTER) then typev, tanim = self:ChooseAnimation("holster") else return false, select(2, self:ChooseIdleAnim()) end return PlayChosenAnimation(self, typev, tanim) end --[[ Function Name: ChooseProceduralReloadAnim Syntax: self:ChooseProceduralReloadAnim(). Returns: Could we successfully find an animation? Which action? Notes: Uses some holster code Purpose: Animation / Utility ]] -- function SWEP:ChooseProceduralReloadAnim() local self2 = self:GetTable() if not self:VMIV() then return end if not self2.DisableIdleAnimations then self:SendViewModelAnim(ACT_VM_IDLE) end return true, ACT_VM_IDLE end --[[ Function Name: ChooseReloadAnim Syntax: self:ChooseReloadAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Purpose: Animation / Utility ]] -- function SWEP:ChooseReloadAnim() local self2 = self:GetTable() if not self:VMIV() then return false, 0 end if self2.GetStatL(self, "IsProceduralReloadBased") then return false, 0 end local ads = self:GetStatL("IronSightsReloadEnabled") and self:GetIronSightsDirect() if self:GetActivityEnabled(ACT_VM_RELOAD_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation((ads and self:GetActivityEnabled(ACT_VM_RELOAD_SILENCED_ADS)) and "reload_silenced_is" or "reload_silenced") elseif self:GetActivityEnabled(ACT_VM_RELOAD_EMPTY) and (self:Clip1() == 0 or self:IsJammed()) and not self:GetStatL("LoopedReload") then typev, tanim = self:ChooseAnimation((ads and self:GetActivityEnabled(ACT_VM_RELOAD_EMPTY_ADS)) and "reload_empty_is" or "reload_empty") else typev, tanim = self:ChooseAnimation((ads and self:GetActivityEnabled(ACT_VM_RELOAD_ADS)) and "reload_is" or "reload") end local fac = 1 if self:GetStatL("LoopedReload") and self:GetStatL("LoopedReloadInsertTime") then fac = self:GetStatL("LoopedReloadInsertTime") end self:SetAnimCycle(self2.ViewModelFlip and 0 or 1) self2.AnimCycle = self:GetAnimCycle() return PlayChosenAnimation(self, typev, tanim, fac, fac ~= 1) end --[[ Function Name: ChooseReloadAnim Syntax: self:ChooseReloadAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Purpose: Animation / Utility ]] -- function SWEP:ChooseShotgunReloadAnim() local self2 = self:GetTable() if not self:VMIV() then return end local ads = self:GetStatL("IronSightsReloadEnabled") and self:GetIronSightsDirect() if self:GetActivityEnabled(ACT_VM_RELOAD_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation((ads and self:GetActivityEnabled(ACT_VM_RELOAD_SILENCED_ADS)) and "reload_silenced_is" or "reload_silenced") elseif self:GetActivityEnabled(ACT_VM_RELOAD_EMPTY) and self2.ShotgunEmptyAnim and (self:Clip1() == 0 or self:IsJammed()) then typev, tanim = self:ChooseAnimation((ads and self:GetActivityEnabled(ACT_VM_RELOAD_EMPTY_ADS)) and "reload_empty_is" or "reload_empty") elseif self:GetActivityEnabled(ACT_SHOTGUN_RELOAD_START) then typev, tanim = self:ChooseAnimation((ads and self:GetActivityEnabled(ACT_SHOTGUN_RELOAD_START_ADS)) and "reload_shotgun_start_is" or "reload_shotgun_start") else return false, select(2, self:ChooseIdleAnim()) end return PlayChosenAnimation(self, typev, tanim) end function SWEP:ChooseShotgunPumpAnim() if not self:VMIV() then return end typev, tanim = self:ChooseAnimation( (self:GetStatL("IronSightsReloadEnabled") and self:GetIronSightsDirect() and self:GetActivityEnabled(ACT_SHOTGUN_RELOAD_START_ADS)) and "reload_shotgun_finish_is" or "reload_shotgun_finish") return PlayChosenAnimation(self, typev, tanim) end --[[ Function Name: ChooseIdleAnim Syntax: self:ChooseIdleAnim(). Returns: True, Which action? Notes: Requires autodetection for full features. Purpose: Animation / Utility ]] -- function SWEP:ChooseIdleAnim() local self2 = self:GetTable() if not self:VMIV() then return end --if self2.Idle_WithHeld then -- self2.Idle_WithHeld = nil -- return --end if TFA.Enum.ShootLoopingStatus[self:GetShootStatus()] then return self:ChooseLoopShootAnim() end if self2.Idle_Mode ~= TFA.Enum.IDLE_BOTH and self2.Idle_Mode ~= TFA.Enum.IDLE_ANI then return end --self:ResetEvents() if self:GetIronSights() then if self2.Sights_Mode == TFA.Enum.LOCOMOTION_LUA then return self:ChooseFlatAnim() else return self:ChooseADSAnim() end elseif self:GetSprinting() and self2.Sprint_Mode ~= TFA.Enum.LOCOMOTION_LUA then return self:ChooseSprintAnim() elseif self:GetWalking() and self2.Walk_Mode ~= TFA.Enum.LOCOMOTION_LUA then return self:ChooseWalkAnim() elseif self:GetCustomizing() and self2.Customize_Mode ~= TFA.Enum.LOCOMOTION_LUA then return self:ChooseCustomizeAnim() end if self:GetActivityEnabled(ACT_VM_IDLE_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation("idle_silenced") elseif self:IsEmpty1() then --self:GetActivityEnabled( ACT_VM_IDLE_EMPTY ) and (self:Clip1() == 0) then if self:GetActivityEnabled(ACT_VM_IDLE_EMPTY) then typev, tanim = self:ChooseAnimation("idle_empty") else --if not self:GetActivityEnabled( ACT_VM_PRIMARYATTACK_EMPTY ) then typev, tanim = self:ChooseAnimation("idle") end else typev, tanim = self:ChooseAnimation("idle") end --else -- return --end return PlayChosenAnimation(self, typev, tanim) end function SWEP:ChooseFlatAnim() local self2 = self:GetTable() if not self:VMIV() then return end --self:ResetEvents() typev, tanim = self:ChooseAnimation("idle") if self:GetActivityEnabled(ACT_VM_IDLE_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation("idle_silenced") elseif self:GetActivityEnabled(ACT_VM_IDLE_EMPTY) and self:IsEmpty1() then typev, tanim = self:ChooseAnimation("idle_empty") end return PlayChosenAnimation(self, typev, tanim, 0.000001) end function SWEP:ChooseADSAnim() local self2 = self:GetTable() local a, b, c = self:PlayAnimation(self2.GetStatL(self, "IronAnimation.loop")) --self:SetNextIdleAnim(CurTime() + 1) if not a then local _ _, b, c = self:ChooseFlatAnim() a = false end return a, b, c end function SWEP:ChooseSprintAnim() return self:PlayAnimation(self:GetStatL("SprintAnimation.loop")) end function SWEP:ChooseWalkAnim() return self:PlayAnimation(self:GetStatL("WalkAnimation.loop")) end function SWEP:ChooseLoopShootAnim() return self:PlayAnimation(self:GetStatL("ShootAnimation.loop")) end function SWEP:ChooseCustomizeAnim() return self:PlayAnimation(self:GetStatL("CustomizeAnimation.loop")) end --[[ Function Name: ChooseShootAnim Syntax: self:ChooseShootAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Purpose: Animation / Utility ]] -- local shouldAnim, shouldBlowback function SWEP:ChooseShootAnim(ifp) local self2 = self:GetTable() if ifp == nil then ifp = IsFirstTimePredicted() end if not self:VMIV() then return end if self2.GetStatL(self, "ShootAnimation.loop") and self2.Primary_TFA.Automatic then if self2.LuaShellEject and ifp then self:EventShell() end if TFA.Enum.ShootReadyStatus[self:GetShootStatus()] then self:SetShootStatus(TFA.Enum.SHOOT_START) local inan = self2.GetStatL(self, "ShootAnimation.in") if not inan then inan = self2.GetStatL(self, "ShootAnimation.loop") end return self:PlayAnimation(inan) end return end if self:GetIronSights() and (self2.Sights_Mode == TFA.Enum.LOCOMOTION_ANI or self2.Sights_Mode == TFA.Enum.LOCOMOTION_HYBRID) and self2.GetStatL(self, "IronAnimation.shoot") then if self2.LuaShellEject and ifp then self:EventShell() end return self:PlayAnimation(self2.GetStatL(self, "IronAnimation.shoot")) end shouldBlowback = self2.GetStatL(self, "BlowbackEnabled") and (not self2.GetStatL(self, "Blowback_Only_Iron") or self:GetIronSights()) shouldAnim = not shouldBlowback or self2.GetStatL(self, "BlowbackAllowAnimation") if shouldBlowback then if sp and SERVER then self:CallOnClient("BlowbackFull", "") end if ifp then self:BlowbackFull(ifp) end if self2.GetStatL(self, "Blowback_Shell_Enabled") and (ifp or sp) then self:EventShell() end end if shouldAnim then success = true if self2.LuaShellEject and (ifp or sp) then self:EventShell() end if self:GetActivityEnabled(ACT_VM_PRIMARYATTACK_SILENCED) and self2.GetSilenced(self) then typev, tanim = self:ChooseAnimation("shoot1_silenced") elseif self:Clip1() <= self2.Primary_TFA.AmmoConsumption and self:GetActivityEnabled(ACT_VM_PRIMARYATTACK_EMPTY) and self2.Primary_TFA.ClipSize >= 1 and not self2.ForceEmptyFireOff then typev, tanim = self:ChooseAnimation("shoot1_last") elseif self:Ammo1() <= self2.Primary_TFA.AmmoConsumption and self:GetActivityEnabled(ACT_VM_PRIMARYATTACK_EMPTY) and self2.Primary_TFA.ClipSize < 1 and not self2.ForceEmptyFireOff then typev, tanim = self:ChooseAnimation("shoot1_last") elseif self:Clip1() == 0 and self:GetActivityEnabled(ACT_VM_DRYFIRE) and not self2.ForceDryFireOff then typev, tanim = self:ChooseAnimation("shoot1_empty") elseif self2.GetStatL(self, "IsAkimbo") and self:GetActivityEnabled(ACT_VM_SECONDARYATTACK) and ((self:GetAnimCycle() == 0 and not self2.Akimbo_Inverted) or (self:GetAnimCycle() == 1 and self2.Akimbo_Inverted)) then typev, tanim = self:ChooseAnimation((self:GetIronSights() and self:GetActivityEnabled(ACT_VM_ISHOOT_M203)) and "shoot2_is" or "shoot2") elseif self:GetIronSights() and self:GetActivityEnabled(ACT_VM_PRIMARYATTACK_1) then typev, tanim = self:ChooseAnimation("shoot1_is") else typev, tanim = self:ChooseAnimation("shoot1") end return PlayChosenAnimation(self, typev, tanim) end self:SendViewModelAnim(ACT_VM_BLOWBACK) return true, ACT_VM_IDLE end SWEP.BlowbackRandomAngleMin = Angle(.1, -.5, -1) SWEP.BlowbackRandomAngleMax = Angle(.2, .5, 1) local minang, maxang function SWEP:BlowbackFull() local self2 = self:GetTable() if IsValid(self) then self2.BlowbackCurrent = 1 self2.BlowbackCurrentRoot = 1 if CLIENT then minang, maxang = self2.GetStatL(self, "BlowbackRandomAngleMin"), self2.GetStatL(self, "BlowbackRandomAngleMax") self2.BlowbackRandomAngle = Angle(math.Rand(minang.p, maxang.p), math.Rand(minang.y, maxang.y), math.Rand(minang.r, maxang.r)) end end end --[[ Function Name: ChooseSilenceAnim Syntax: self:ChooseSilenceAnim( true if we're silencing, false for detaching the silencer). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. This is played when you silence or unsilence a gun. Purpose: Animation / Utility ]] -- function SWEP:ChooseSilenceAnim(val) if not self:VMIV() then return end --self:ResetEvents() typev, tanim = self:ChooseAnimation("idle_silenced") success = false if val then if self:GetActivityEnabled(ACT_VM_ATTACH_SILENCER) then typev, tanim = self:ChooseAnimation("silencer_attach") success = true end elseif self:GetActivityEnabled(ACT_VM_DETACH_SILENCER) then typev, tanim = self:ChooseAnimation("silencer_detach") success = true end if not success then return false, select(2, self:ChooseIdleAnim()) end return PlayChosenAnimation(self, typev, tanim) end --[[ Function Name: ChooseDryFireAnim Syntax: self:ChooseDryFireAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. set SWEP.ForceDryFireOff to false to properly use. Purpose: Animation / Utility ]] -- function SWEP:ChooseDryFireAnim() local self2 = self:GetTable() if not self:VMIV() then return end --self:ResetEvents() typev, tanim = self:ChooseAnimation("shoot1_empty") success = true if self:GetActivityEnabled(ACT_VM_DRYFIRE_SILENCED) and self2.GetSilenced(self) and not self2.ForceDryFireOff then typev, tanim = self:ChooseAnimation("shoot1_silenced_empty") --self:ChooseIdleAnim() else if self:GetActivityEnabled(ACT_VM_DRYFIRE) and not self2.ForceDryFireOff then typev, tanim = self:ChooseAnimation("shoot1_empty") else success = false local _ _, tanim = nil, nil return success, tanim -- ??? end end return PlayChosenAnimation(self, typev, tanim) end --[[ Function Name: ChooseROFAnim Syntax: self:ChooseROFAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Called when we change the firemode. Purpose: Animation / Utility ]] -- function SWEP:ChooseROFAnim() local self2 = self:GetTable() if not self:VMIV() then return end --self:ResetEvents() if self:GetIronSights() and self:GetActivityEnabled(ACT_VM_IFIREMODE) then typev, tanim = self2.ChooseAnimation(self, "rof_is") success = true elseif self:GetActivityEnabled(ACT_VM_FIREMODE) then typev, tanim = self2.ChooseAnimation(self, "rof") success = true else success = false local _ _, tanim = nil, nil return success, tanim -- ??? end return PlayChosenAnimation(self, typev, tanim) end --[[ Function Name: ChooseBashAnim Syntax: self:ChooseBashAnim(). Returns: Could we successfully find an animation? Which action? Notes: Requires autodetection or otherwise the list of valid anims. Called when we bash. Purpose: Animation / Utility ]] -- function SWEP:ChooseBashAnim() local self2 = self:GetTable() if not self:VMIV() then return end typev, tanim = nil, nil success = false local isempty = self2.GetStatL(self, "Primary.ClipSize") > 0 and self:Clip1() == 0 if self2.GetSilenced(self) and self:GetActivityEnabled(ACT_VM_HITCENTER2) then if self:GetActivityEnabled(ACT_VM_MISSCENTER2) and isempty then typev, tanim = self:ChooseAnimation("bash_empty_silenced") success = true else typev, tanim = self:ChooseAnimation("bash_silenced") success = true end elseif self:GetActivityEnabled(ACT_VM_MISSCENTER) and isempty then typev, tanim = self:ChooseAnimation("bash_empty") success = true elseif self:GetActivityEnabled(ACT_VM_HITCENTER) then typev, tanim = self:ChooseAnimation("bash") success = true end if not success then return success, tanim end return PlayChosenAnimation(self, typev, tanim) end --[[THIRDPERSON]] --These holdtypes are used in ironsights. Syntax: DefaultHoldType=NewHoldType SWEP.IronSightHoldTypes = { pistol = "revolver", smg = "rpg", grenade = "melee", ar2 = "rpg", shotgun = "ar2", rpg = "rpg", physgun = "physgun", crossbow = "ar2", melee = "melee2", slam = "camera", normal = "fist", melee2 = "magic", knife = "fist", duel = "duel", camera = "camera", magic = "magic", revolver = "revolver" } --These holdtypes are used while sprinting. Syntax: DefaultHoldType=NewHoldType SWEP.SprintHoldTypes = { pistol = "normal", smg = "passive", grenade = "normal", ar2 = "passive", shotgun = "passive", rpg = "passive", physgun = "normal", crossbow = "passive", melee = "normal", slam = "normal", normal = "normal", melee2 = "melee", knife = "fist", duel = "normal", camera = "slam", magic = "normal", revolver = "normal" } --These holdtypes are used in reloading. Syntax: DefaultHoldType=NewHoldType SWEP.ReloadHoldTypes = { pistol = "pistol", smg = "smg", grenade = "melee", ar2 = "ar2", shotgun = "shotgun", rpg = "ar2", physgun = "physgun", crossbow = "crossbow", melee = "pistol", slam = "smg", normal = "pistol", melee2 = "pistol", knife = "pistol", duel = "duel", camera = "pistol", magic = "pistol", revolver = "revolver" } --These holdtypes are used in reloading. Syntax: DefaultHoldType=NewHoldType SWEP.CrouchHoldTypes = { ar2 = "ar2", smg = "smg", rpg = "ar2" } SWEP.IronSightHoldTypeOverride = "" --This variable overrides the ironsights holdtype, choosing it instead of something from the above tables. Change it to "" to disable. SWEP.SprintHoldTypeOverride = "" --This variable overrides the sprint holdtype, choosing it instead of something from the above tables. Change it to "" to disable. SWEP.ReloadHoldTypeOverride = "" --This variable overrides the reload holdtype, choosing it instead of something from the above tables. Change it to "" to disable. local dynholdtypecvar = GetConVar("sv_tfa_holdtype_dynamic") SWEP.mht_old = "" local mht function SWEP:IsOwnerCrouching() local ply = self:GetOwner() if not ply:IsPlayer() then return false end return (ply:Crouching() or self:KeyDown(IN_DUCK)) and ply:OnGround() and not ply:InVehicle() end function SWEP:ProcessHoldType() local self2 = self:GetTable() mht = self2.GetStatL(self, "HoldType", "ar2") if mht ~= self2.mht_old or not self2.DefaultHoldType then self2.DefaultHoldType = mht self2.SprintHoldType = nil self2.IronHoldType = nil self2.ReloadHoldType = nil self2.CrouchHoldType = nil end self2.mht_old = mht if not self2.SprintHoldType then self2.SprintHoldType = self2.SprintHoldTypes[self2.DefaultHoldType] or "passive" if self2.SprintHoldTypeOverride and self2.SprintHoldTypeOverride ~= "" then self2.SprintHoldType = self2.SprintHoldTypeOverride end end if not self2.IronHoldType then self2.IronHoldType = self2.IronSightHoldTypes[self2.DefaultHoldType] or "rpg" if self2.IronSightHoldTypeOverride and self2.IronSightHoldTypeOverride ~= "" then self2.IronHoldType = self2.IronSightHoldTypeOverride end end if not self2.ReloadHoldType then self2.ReloadHoldType = self2.ReloadHoldTypes[self2.DefaultHoldType] or "ar2" if self2.ReloadHoldTypeOverride and self2.ReloadHoldTypeOverride ~= "" then self2.ReloadHoldType = self2.ReloadHoldTypeOverride end end if not self2.SetCrouchHoldType then self2.SetCrouchHoldType = true self2.CrouchHoldType = self2.CrouchHoldTypes[self2.DefaultHoldType] if self2.CrouchHoldTypeOverride and self2.CrouchHoldTypeOverride ~= "" then self2.CrouchHoldType = self2.CrouchHoldTypeOverride end end local curhold, targhold, stat curhold = self:GetHoldType() targhold = self2.DefaultHoldType stat = self:GetStatus() if dynholdtypecvar:GetBool() then if self:OwnerIsValid() and self:IsOwnerCrouching() and self2.CrouchHoldType then targhold = self2.CrouchHoldType else if self:GetIronSights() then targhold = self2.IronHoldType end if TFA.Enum.ReloadStatus[stat] then targhold = self2.ReloadHoldType end end end if self:GetSprinting() or TFA.Enum.HolsterStatus[stat] or self:IsSafety() then targhold = self2.SprintHoldType end if targhold ~= curhold then self:SetHoldType(targhold) end end