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

798 lines
28 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/
--]]
-- 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.
function SWEP:FixSprintAnimBob()
local self2 = self:GetTable()
if self:GetStatRawL("Sprint_Mode") == TFA.Enum.LOCOMOTION_ANI then
self:SetStatRawL("SprintBobMult", 0)
end
end
function SWEP:FixWalkAnimBob()
local self2 = self:GetTable()
if self:GetStatRawL("Walk_Mode") == TFA.Enum.LOCOMOTION_ANI then
self:SetStatRawL("WalkBobMult_Iron", self:GetStatRawL("WalkBobMult"))
self:SetStatRawL("WalkBobMult", 0)
end
end
function SWEP:PatchAmmoTypeAccessors()
local self2 = self:GetTable()
self:SetStatRawL("GetPrimaryAmmoTypeOld", self:GetStatRawL("GetPrimaryAmmoTypeOld") or self:GetStatRawL("GetPrimaryAmmoType"))
self:SetStatRawL("GetPrimaryAmmoType", function(myself, ...) return myself.GetPrimaryAmmoTypeC(myself, ...) end)
self:SetStatRawL("GetSecondaryAmmoTypeOld", self:GetStatRawL("GetSecondaryAmmoTypeOld") or self:GetStatRawL("GetSecondaryAmmoType"))
self:SetStatRawL("GetSecondaryAmmoType", function(myself, ...) return myself.GetSecondaryAmmoTypeC(myself, ...) end)
end
function SWEP:FixProjectile()
local self2 = self:GetTable()
if self:GetStatRawL("ProjectileEntity") and self:GetStatRawL("ProjectileEntity") ~= "" then
self:SetStatRawL("Primary.Projectile", self:GetStatRawL("ProjectileEntity"))
self:SetStatRawL("ProjectileEntity", nil)
end
if self:GetStatRawL("ProjectileModel") and self:GetStatRawL("ProjectileModel") ~= "" then
self:SetStatRawL("Primary.ProjectileModel", self:GetStatRawL("ProjectileModel"))
self:SetStatRawL("ProjectileModel", nil)
end
if self:GetStatRawL("ProjectileVelocity") and self:GetStatRawL("ProjectileVelocity") ~= "" then
self:SetStatRawL("Primary.ProjectileVelocity", self:GetStatRawL("ProjectileVelocity"))
self:SetStatRawL("ProjectileVelocity", nil)
end
end
local sv_tfa_range_modifier = GetConVar("sv_tfa_range_modifier")
function SWEP:AutoDetectRange()
local self2 = self:GetTable()
if self:GetStatL("Primary.FalloffMetricBased") and not self:GetStatRawL("Primary.RangeFalloffLUT") then
self:SetStatRawL("Primary.RangeFalloffLUT_IsConverted", true)
self:SetStatRawL("Primary.RangeFalloffLUT", {
bezier = false,
range_func = "linear", -- function to spline range
units = "meters",
lut = {
{range = self:GetStatL("Primary.MinRangeStartFalloff"), damage = 1},
{range = self:GetStatL("Primary.MinRangeStartFalloff") + self:GetStatL("Primary.MaxFalloff") / self:GetStatL("Primary.FalloffByMeter"),
damage = (self:GetStatL("Primary.Damage") - self:GetStatL("Primary.MaxFalloff")) / self:GetStatL("Primary.Damage")},
}
})
return
end
if self:GetStatL("Primary.FalloffMetricBased") or self:GetStatL("Primary.RangeFalloffLUT") then return end
if self:GetStatL("Primary.Range") <= 0 then
self:SetStatRawL("Primary.Range", math.sqrt(self:GetStatL("Primary.Damage") / 32) * self:MetersToUnits(350) * self:AmmoRangeMultiplier())
end
if self:GetStatL("Primary.RangeFalloff") <= 0 then
self:SetStatRawL("Primary.RangeFalloff", 0.5)
end
self:SetStatRawL("Primary.RangeFalloffLUT_IsConverted", true)
self:SetStatRawL("Primary.RangeFalloffLUT", {
bezier = false,
range_func = "linear", -- function to spline range
units = "hammer",
lut = {
{range = self:GetStatL("Primary.Range") * self:GetStatL("Primary.RangeFalloff"), damage = 1},
{range = self:GetStatL("Primary.Range"), damage = 1 - sv_tfa_range_modifier:GetFloat()},
}
})
end
function SWEP:FixProceduralReload()
-- do nothing
end
function SWEP:FixRPM()
local self2 = self:GetTable()
if not self:GetStatRawL("Primary.RPM") then
if self:GetStatRawL("Primary.Delay") then
self:SetStatRawL("Primary.RPM", 60 / self:GetStatRawL("Primary.Delay"))
else
self:SetStatRawL("Primary.RPM", 120)
end
end
end
function SWEP:FixCone()
local self2 = self:GetTable()
if self:GetStatRawL("Primary.Cone") then
if (not self:GetStatRawL("Primary.Spread")) or self:GetStatRawL("Primary.Spread") < 0 then
self:SetStatRawL("Primary.Spread", self:GetStatRawL("Primary.Cone"))
end
self:SetStatRawL("Primary.Cone", nil)
end
end
--legacy compatibility
function SWEP:FixIdles()
local self2 = self:GetTable()
if self:GetStatRawL("DisableIdleAnimations") ~= nil and self:GetStatRawL("DisableIdleAnimations") == true then
self:SetStatRawL("Idle_Mode", TFA.Enum.IDLE_LUA)
end
end
function SWEP:FixIS()
local self2 = self:GetTable()
if self:GetStatRawL("SightsPos") and (not self:GetStatRawL("IronSightsPosition") or (self:GetStatRawL("IronSightsPosition").x ~= self:GetStatRawL("SightsPos").x and self:GetStatRawL("SightsPos").x ~= 0)) then
self:SetStatRawL("IronSightsPosition", self:GetStatRawL("SightsPos") or Vector())
self:SetStatRawL("IronSightsAngle", self:GetStatRawL("SightsAng") or Vector())
end
end
local legacy_spread_cv = GetConVar("sv_tfa_spread_legacy")
function SWEP:AutoDetectSpread()
local self2 = self:GetTable()
if legacy_spread_cv and legacy_spread_cv:GetBool() then
self:SetUpSpreadLegacy()
return
end
if self:GetStatRawL("Primary.SpreadMultiplierMax") == -1 or not self:GetStatRawL("Primary.SpreadMultiplierMax") then
self:SetStatRawL("Primary.SpreadMultiplierMax", math.Clamp(math.sqrt(math.sqrt(self:GetStatRawL("Primary.Damage") / 35) * 10 / 5) * 5, 0.01 / self:GetStatRawL("Primary.Spread"), 0.1 / self:GetStatRawL("Primary.Spread")))
end
if self:GetStatRawL("Primary.SpreadIncrement") == -1 or not self:GetStatRawL("Primary.SpreadIncrement") then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadMultiplierMax") * 60 / self:GetStatRawL("Primary.RPM") * 0.85 * 1.5)
end
if self:GetStatRawL("Primary.SpreadRecovery") == -1 or not self:GetStatRawL("Primary.SpreadRecovery") then
self:SetStatRawL("Primary.SpreadRecovery", math.max(self:GetStatRawL("Primary.SpreadMultiplierMax") * math.pow(self:GetStatRawL("Primary.RPM") / 600, 1 / 3) * 0.75, self:GetStatRawL("Primary.SpreadMultiplierMax") / 1.5))
end
end
--[[
Function Name: AutoDetectMuzzle
Syntax: self:AutoDetectMuzzle(). Call only once, or it's redundant.
Returns: Nothing.
Notes: Detects the proper muzzle flash effect if you haven't specified one.
Purpose: Autodetection
]]
--
function SWEP:AutoDetectMuzzle()
local self2 = self:GetTable()
if not self:GetStatRawL("MuzzleFlashEffect") then
local a = string.lower(self:GetStatRawL("Primary.Ammo"))
local cat = string.lower(self:GetStatRawL("Category") and self:GetStatRawL("Category") or "")
if self:GetStatRawL("Silenced") or self:GetSilenced() then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_silenced")
elseif string.find(a, "357") or self:GetStatRawL("Revolver") or string.find(cat, "revolver") then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_revolver")
elseif self:GetStatL("LoopedReload") or a == "buckshot" or a == "slam" or a == "airboatgun" or string.find(cat, "shotgun") then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_shotgun")
elseif string.find(a, "smg") or string.find(cat, "smg") or string.find(cat, "submachine") or string.find(cat, "sub-machine") then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_smg")
elseif string.find(a, "sniper") or string.find(cat, "sniper") then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_sniper")
elseif string.find(a, "pistol") or string.find(cat, "pistol") then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_pistol")
elseif string.find(a, "ar2") or string.find(a, "rifle") or (string.find(cat, "revolver") and not string.find(cat, "rifle")) then
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_rifle")
else
self:SetStatRawL("MuzzleFlashEffect", "tfa_muzzleflash_generic")
end
end
end
--[[
Function Name: AutoDetectDamage
Syntax: self:AutoDetectDamage(). Call only once. Hopefully you call this only once on like SWEP:Initialize() or something.
Returns: Nothing.
Notes: Fixes the damage for GDCW.
Purpose: Autodetection
]]
--
function SWEP:AutoDetectDamage()
local self2 = self:GetTable()
if self:GetStatRawL("Primary.Damage") and self:GetStatRawL("Primary.Damage") ~= -1 then return end
if self:GetStatRawL("Primary.Round") then
local rnd = string.lower(self:GetStatRawL("Primary.Round"))
if string.find(rnd, ".50bmg") then
self:SetStatRawL("Primary.Damage", 185)
elseif string.find(rnd, "5.45x39") then
self:SetStatRawL("Primary.Damage", 22)
elseif string.find(rnd, "5.56x45") then
self:SetStatRawL("Primary.Damage", 30)
elseif string.find(rnd, "338_lapua") then
self:SetStatRawL("Primary.Damage", 120)
elseif string.find(rnd, "338") then
self:SetStatRawL("Primary.Damage", 100)
elseif string.find(rnd, "7.62x51") then
self:SetStatRawL("Primary.Damage", 100)
elseif string.find(rnd, "9x39") then
self:SetStatRawL("Primary.Damage", 32)
elseif string.find(rnd, "9mm") then
self:SetStatRawL("Primary.Damage", 22)
elseif string.find(rnd, "9x19") then
self:SetStatRawL("Primary.Damage", 22)
elseif string.find(rnd, "9x18") then
self:SetStatRawL("Primary.Damage", 20)
end
if string.find(rnd, "ap") then
self:SetStatRawL("Primary.Damage", self:GetStatRawL("Primary.Damage") * 1.2)
end
end
if (not self:GetStatRawL("Primary.Damage")) or (self:GetStatRawL("Primary.Damage") <= 0.01) and self:GetStatRawL("Velocity") then
self:SetStatRawL("Primary.Damage", self:GetStatRawL("Velocity") / 5)
end
if (not self:GetStatRawL("Primary.Damage")) or (self:GetStatRawL("Primary.Damage") <= 0.01) then
self:SetStatRawL("Primary.Damage", (self:GetStatRawL("Primary.KickUp") + self:GetStatRawL("Primary.KickUp") + self:GetStatRawL("Primary.KickUp")) * 10)
end
end
--[[
Function Name: AutoDetectDamageType
Syntax: self:AutoDetectDamageType(). Call only once. Hopefully you call this only once on like SWEP:Initialize() or something.
Returns: Nothing.
Notes: Sets a damagetype
Purpose: Autodetection
]]
--
function SWEP:AutoDetectDamageType()
local self2 = self:GetTable()
if self:GetStatRawL("Primary.DamageType") == -1 or not self:GetStatRawL("Primary.DamageType") then
if self:GetStatRawL("DamageType") and not self:GetStatRawL("Primary.DamageType") then
self:SetStatRawL("Primary.DamageType", self:GetStatRawL("DamageType"))
else
self:SetStatRawL("Primary.DamageType", DMG_BULLET)
end
end
end
--[[
Function Name: AutoDetectForce
Syntax: self:AutoDetectForce(). Call only once. Hopefully you call this only once on like SWEP:Initialize() or something.
Returns: Nothing.
Notes: Detects force from damage
Purpose: Autodetection
]]
--
function SWEP:AutoDetectForce()
local self2 = self:GetTable()
if self:GetStatRawL("Primary.Force") == -1 or not self:GetStatRawL("Primary.Force") then
self:SetStatRawL("Primary.Force", self:GetStatRawL("Force") or (math.sqrt(self:GetStatRawL("Primary.Damage") / 16) * 3 / math.sqrt(self:GetStatRawL("Primary.NumShots"))))
end
end
function SWEP:AutoDetectPenetrationPower()
local self2 = self:GetTable()
if self:GetStatRawL("Primary.PenetrationPower") == -1 or not self:GetStatRawL("Primary.PenetrationPower") then
local am = string.lower(self:GetStatL("Primary.Ammo"))
local m = 1
if (am == "pistol") then
m = 0.4
elseif (am == "357") then
m = 1.75
elseif (am == "smg1") then
m = 0.34
elseif (am == "ar2") then
m = 1.1
elseif (am == "buckshot") then
m = 0.3
elseif (am == "airboatgun") then
m = 2.25
elseif (am == "sniperpenetratedround") then
m = 3
end
self:SetStatRawL("Primary.PenetrationPower", self:GetStatRawL("PenetrationPower") or math.sqrt(self:GetStatRawL("Primary.Force") * 200 * m))
end
end
--[[
Function Name: AutoDetectKnockback
Syntax: self:AutoDetectKnockback(). Call only once. Hopefully you call this only once on like SWEP:Initialize() or something.
Returns: Nothing.
Notes: Detects knockback from force
Purpose: Autodetection
]]
--
function SWEP:AutoDetectKnockback()
local self2 = self:GetTable()
if self:GetStatRawL("Primary.Knockback") == -1 or not self:GetStatRawL("Primary.Knockback") then
self:SetStatRawL("Primary.Knockback", self:GetStatRawL("Knockback") or math.max(math.pow(self:GetStatRawL("Primary.Force") - 3.25, 2), 0) * math.pow(self:GetStatRawL("Primary.NumShots"), 1 / 3))
end
end
--[[
Function Name: IconFix
Syntax: self:IconFix(). Call only once. Hopefully you call this only once on like SWEP:Initialize() or something.
Returns: Nothing.
Notes: Fixes the icon. Call this if you give it a texture path, or just nothing.
Purpose: Autodetection
]]
--
local selicon_final = {}
function SWEP:IconFix()
local self2 = self:GetTable()
if not surface then return end
local class = self2.ClassName
if selicon_final[class] then
self:SetStatRawL("WepSelectIcon", selicon_final[class])
return
end
if self2.WepSelectIcon and type(self2.WepSelectIcon) == "string" then
self:SetStatRawL("WepSelectIcon", surface.GetTextureID(self2.WepSelectIcon))
else
if file.Exists("materials/vgui/hud/" .. class .. ".png", "GAME") then
self:SetStatRawL("WepSelectIcon", Material("vgui/hud/" .. class .. ".png", "smooth noclamp")) -- NOTHING should access this variable directly and our DrawWeaponSelection override supports IMaterial.
elseif file.Exists("materials/vgui/hud/" .. class .. ".vmt", "GAME") then
self:SetStatRawL("WepSelectIcon", surface.GetTextureID("vgui/hud/" .. class))
end
end
selicon_final[class] = self2.WepSelectIcon
end
--[[
Function Name: CorrectScopeFOV
Syntax: self:CorrectScopeFOV( fov ). Call only once. Hopefully you call this only once on like SWEP:Initialize() or something.
Returns: Nothing.
Notes: If you're using scopezoom instead of FOV, this translates it.
Purpose: Autodetection
]]
--
function SWEP:CorrectScopeFOV(fov)
local self2 = self:GetTable()
fov = fov or self:GetStatRawL("DefaultFOV")
if not self:GetStatRawL("Secondary.OwnerFOV") or self:GetStatRawL("Secondary.OwnerFOV") <= 0 then
if self:GetStatRawL("Scoped") then
self:SetStatRawL("Secondary.OwnerFOV", fov / (self:GetStatRawL("Secondary.ScopeZoom") and self:GetStatRawL("Secondary.ScopeZoom") or 2))
else
self:SetStatRawL("Secondary.OwnerFOV", 32)
end
end
end
--[[
Function Name: CreateFireModes
Syntax: self:CreateFireModes( is first draw). Call as much as you like. isfirstdraw controls whether the default fire mode is set.
Returns: Nothing.
Notes: Autodetects fire modes depending on what params you set up.
Purpose: Autodetection
]]
--
SWEP.FireModeCache = {}
function SWEP:CreateFireModes(isfirstdraw)
local self2 = self:GetTable()
if not self2.FireModes then
self:SetStatRawL("FireModes", {})
local burstcnt = self:FindEvenBurstNumber()
if self2.SelectiveFire then
if self2.OnlyBurstFire then
if burstcnt then
self2.FireModes[1] = burstcnt .. "Burst"
self2.FireModes[2] = "Single"
else
self2.FireModes[1] = "Single"
end
else
self2.FireModes[1] = "Automatic"
if self2.DisableBurstFire then
self2.FireModes[2] = "Single"
else
if burstcnt then
self2.FireModes[2] = burstcnt .. "Burst"
self2.FireModes[3] = "Single"
else
self2.FireModes[2] = "Single"
end
end
end
else
if self2.Primary_TFA.Automatic then
self2.FireModes[1] = "Automatic"
if self2.OnlyBurstFire and burstcnt then
self2.FireModes[1] = burstcnt .. "Burst"
end
else
self2.FireModes[1] = "Single"
end
end
end
if self2.FireModes[#self2.FireModes] ~= "Safe" then
self2.FireModes[#self2.FireModes + 1] = "Safe"
end
if not self2.FireModeCache or #self2.FireModeCache <= 0 then
for k, v in ipairs(self2.FireModes) do
self2.FireModeCache[v] = k
end
if type(self2.DefaultFireMode) == "number" then
self:SetFireMode(self2.DefaultFireMode or (self2.Primary_TFA.Automatic and 1 or #self2.FireModes - 1))
else
self:SetFireMode(self2.FireModeCache[self2.DefaultFireMode] or (self2.Primary_TFA.Automatic and 1 or #self2.FireModes - 1))
end
end
end
--[[
Function Name: CacheAnimations
Syntax: self:CacheAnimations(). Call as much as you like.
Returns: Nothing.
Notes: This is what autodetects animations for the SWEP.SequenceEnabled and SWEP.SequenceLength tables.
Purpose: Autodetection
]]
--
--SWEP.actlist = {ACT_VM_DRAW, ACT_VM_DRAW_EMPTY, ACT_VM_DRAW_SILENCED, ACT_VM_DRAW_DEPLOYED, ACT_VM_HOLSTER, ACT_VM_HOLSTER_EMPTY, ACT_VM_IDLE, ACT_VM_IDLE_EMPTY, ACT_VM_IDLE_SILENCED, ACT_VM_PRIMARYATTACK, ACT_VM_PRIMARYATTACK_1, ACT_VM_PRIMARYATTACK_EMPTY, ACT_VM_PRIMARYATTACK_SILENCED, ACT_VM_SECONDARYATTACK, ACT_VM_RELOAD, ACT_VM_RELOAD_EMPTY, ACT_VM_RELOAD_SILENCED, ACT_VM_ATTACH_SILENCER, ACT_VM_RELEASE, ACT_VM_DETACH_SILENCER, ACT_VM_FIDGET, ACT_VM_FIDGET_EMPTY, ACT_VM_FIDGET_SILENCED, ACT_SHOTGUN_RELOAD_START, ACT_VM_DRYFIRE, ACT_VM_DRYFIRE_SILENCED }
--If you really want, you can remove things from SWEP.actlist and manually enable animations and set their lengths.
SWEP.SequenceEnabled = {}
SWEP.SequenceLength = {}
SWEP.SequenceLengthOverride = {} --Override this if you want to change the length of a sequence but not the next idle
SWEP.ActCache = {}
local vm, seq
function SWEP:CacheAnimations()
local self2 = self:GetTable()
table.Empty(self2.ActCache)
if self:GetStatRawL("CanBeSilenced") and self2.SequenceEnabled[ACT_VM_IDLE_SILENCED] == nil then
self2.SequenceEnabled[ACT_VM_IDLE_SILENCED] = true
end
if not self:VMIV() then return end
vm = self2.OwnerViewModel
if IsValid(vm) then
self:BuildAnimActivities()
for _, v in ipairs(table.GetKeys(self2.AnimationActivities)) do
if isnumber(v) then
seq = vm:SelectWeightedSequence(v)
if seq ~= -1 and vm:GetSequenceActivity(seq) == v and not self2.ActCache[seq] then
self2.SequenceEnabled[v] = true
self2.SequenceLength[v] = vm:SequenceDuration(seq)
self2.ActCache[seq] = v
else
self2.SequenceEnabled[v] = false
self2.SequenceLength[v] = 0.0
end
else
local s = vm:LookupSequence(v)
if s and s > 0 then
self2.SequenceEnabled[v] = true
self2.SequenceLength[v] = vm:SequenceDuration(s)
self2.ActCache[s] = v
else
self2.SequenceEnabled[v] = false
self2.SequenceLength[v] = 0.0
end
end
end
else
return false
end
if self:GetStatRawL("ProceduralHolsterEnabled") == nil then
if self2.SequenceEnabled[ACT_VM_HOLSTER] then
self:SetStatRawL("ProceduralHolsterEnabled", false)
else
self:SetStatRawL("ProceduralHolsterEnabled", true)
end
end
self:SetStatRawL("HasDetectedValidAnimations", true)
return true
end
function SWEP:GetType()
local self2 = self:GetTable()
if self:GetStatRawL("Type") then return self:GetStatRawL("Type") end
local at = string.lower(self:GetStatRawL("Primary.Ammo") or "")
local ht = string.lower((self:GetStatRawL("DefaultHoldType") or self:GetStatRawL("HoldType")) or "")
local rpm = self:GetStatRawL("Primary.RPM_Displayed") or self:GetStatRawL("Primary.RPM") or 600
if self:GetStatRawL("Primary.ProjectileEntity") or self:GetStatRawL("ProjectileEntity") then
if (self:GetStatRawL("ProjectileVelocity") or self:GetStatRawL("Primary.ProjectileVelocity")) > 400 then
self:SetStatRawL("Type", "Launcher")
else
self:SetStatRawL("Type", "Grenade")
end
return
end
if at == "buckshot" then
self:SetStatRawL("Type", "Shotgun")
return self:GetType()
end
if self:GetStatRawL("Pistol") or (at == "pistol" and ht == "pistol") then
self:SetStatRawL("Type", "Pistol")
return self:GetType()
end
if self:GetStatRawL("SMG") or (at == "smg1" and (ht == "smg" or ht == "pistol" or ht == "357")) then
self:SetStatRawL("Type", "Sub-Machine Gun")
return self:GetType()
end
if self:GetStatRawL("Revolver") or (at == "357" and ht == "revolver") then
self:SetStatRawL("Type", "Revolver")
return self:GetType()
end
--Detect Sniper Type
if ( (self:GetStatRawL("Scoped") or self:GetStatRawL("Scoped_3D")) and rpm < 600 ) or at == "sniperpenetratedround" then
if rpm > 180 and (self:GetStatRawL("Primary.Automatic") or self:GetStatRawL("Primary.SelectiveFire")) then
self:SetStatRawL("Type", "Designated Marksman Rifle")
return self:GetType()
else
self:SetStatRawL("Type", "Sniper Rifle")
return self:GetType()
end
end
--Detect based on holdtype
if ht == "pistol" then
if self:GetStatRawL("Primary.Automatic") then
self:SetStatRawL("Type", "Machine Pistol")
else
self:SetStatRawL("Type", "Pistol")
end
return self:GetType()
end
if ht == "duel" then
if at == "pistol" then
self:SetStatRawL("Type", "Dual Pistols")
return self:GetType()
elseif at == "357" then
self:SetStatRawL("Type", "Dual Revolvers")
return self:GetType()
elseif at == "smg1" then
self:SetStatRawL("Type", "Dual Sub-Machine Guns")
return self:GetType()
else
self:SetStatRawL("Type", "Dual Guns")
return self:GetType()
end
end
--If it's using rifle ammo, it's a rifle or a carbine
if at == "ar2" then
if self:GetStatRawL("Primary.ClipSize") >= 60 then
self:SetStatRawL("Type", "Light Machine Gun")
return self:GetType()
elseif ht == "rpg" or ht == "revolver" then
self:SetStatRawL("Type", "Carbine")
return self:GetType()
else
self:SetStatRawL("Type", "Rifle")
return self:GetType()
end
end
--Check SMG one last time
if ht == "smg" or at == "smg1" then
self:SetStatRawL("Type", "Sub-Machine Gun")
return self:GetType()
end
--Fallback to generic
self:SetStatRawL("Type", "Weapon")
return self:GetType()
end
function SWEP:SetUpSpreadLegacy()
local self2 = self:GetTable()
local ht = self:GetStatRawL("DefaultHoldType") and self:GetStatRawL("DefaultHoldType") or self:GetStatRawL("HoldType")
if not self:GetStatRawL("Primary.SpreadMultiplierMax") or self:GetStatRawL("Primary.SpreadMultiplierMax") <= 0 or self:GetStatRawL("AutoDetectSpreadMultiplierMax") then
self:SetStatRawL("Primary.SpreadMultiplierMax", 2.5 * math.max(self:GetStatRawL("Primary.RPM"), 400) / 600 * math.sqrt(self:GetStatRawL("Primary.Damage") / 30 * self:GetStatRawL("Primary.NumShots"))) --How far the spread can expand when you shoot.
if ht == "smg" then
self:SetStatRawL("Primary.SpreadMultiplierMax", self:GetStatRawL("Primary.SpreadMultiplierMax") * 0.8)
end
if ht == "revolver" then
self:SetStatRawL("Primary.SpreadMultiplierMax", self:GetStatRawL("Primary.SpreadMultiplierMax") * 2)
end
if self:GetStatRawL("Scoped") then
self:SetStatRawL("Primary.SpreadMultiplierMax", self:GetStatRawL("Primary.SpreadMultiplierMax") * 1.5)
end
self:SetStatRawL("AutoDetectSpreadMultiplierMax", true)
end
if not self:GetStatRawL("Primary.SpreadIncrement") or self:GetStatRawL("Primary.SpreadIncrement") <= 0 or self:GetStatRawL("AutoDetectSpreadIncrement") then
self:SetStatRawL("AutoDetectSpreadIncrement", true)
self:SetStatRawL("Primary.SpreadIncrement", 1 * math.Clamp(math.sqrt(self:GetStatRawL("Primary.RPM")) / 24.5, 0.7, 3) * math.sqrt(self:GetStatRawL("Primary.Damage") / 30 * self:GetStatRawL("Primary.NumShots"))) --What percentage of the modifier is added on, per shot.
if ht == "revolver" then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * 2)
end
if ht == "pistol" then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * 1.35)
end
if ht == "ar2" or ht == "rpg" then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * 0.65)
end
if ht == "smg" then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * 1.75)
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * (math.Clamp((self:GetStatRawL("Primary.RPM") - 650) / 150, 0, 1) + 1))
end
if ht == "pistol" and self:GetStatRawL("Primary.Automatic") == true then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * 1.5)
end
if self:GetStatRawL("Scoped") then
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * 1.25)
end
self:SetStatRawL("Primary.SpreadIncrement", self:GetStatRawL("Primary.SpreadIncrement") * math.sqrt(self:GetStatRawL("Primary.Recoil") * (self:GetStatRawL("Primary.KickUp") + self:GetStatRawL("Primary.KickDown") + self:GetStatRawL("Primary.KickHorizontal"))) * 0.8)
end
if not self:GetStatRawL("Primary.SpreadRecovery") or self:GetStatRawL("Primary.SpreadRecovery") <= 0 or self:GetStatRawL("AutoDetectSpreadRecovery") then
self:SetStatRawL("AutoDetectSpreadRecovery", true)
self:SetStatRawL("Primary.SpreadRecovery", math.sqrt(math.max(self:GetStatRawL("Primary.RPM"), 300)) / 29 * 4) --How much the spread recovers, per second.
if ht == "smg" then
self:SetStatRawL("Primary.SpreadRecovery", self:GetStatRawL("Primary.SpreadRecovery") * (1 - math.Clamp((self:GetStatRawL("Primary.RPM") - 600) / 200, 0, 1) * 0.33))
end
end
end
SWEP.LowAmmoSoundTypeBlacklist = {
["launcher"] = true,
["grenade"] = true,
}
SWEP.LowAmmoSoundByType = {
["handgun"] = "TFA.LowAmmo.Handgun",
["pistol"] = "TFA.LowAmmo.Handgun",
["dualpistols"] = "TFA.LowAmmo.Handgun",
["machinepistol"] = "TFA.LowAmmo.Handgun",
["handcannon"] = "TFA.LowAmmo.Revolver",
["revolver"] = "TFA.LowAmmo.Revolver",
["dualrevolvers"] = "TFA.LowAmmo.Revolver",
["shotgun"] = "TFA.LowAmmo.Shotgun",
["machinegun"] = "TFA.LowAmmo.MachineGun",
["lightmachinegun"] = "TFA.LowAmmo.MachineGun",
["heavymachinegun"] = "TFA.LowAmmo.MachineGun",
["carbine"] = "TFA.LowAmmo.AssaultRifle",
["rifle"] = "TFA.LowAmmo.AssaultRifle",
["assaultrifle"] = "TFA.LowAmmo.AssaultRifle",
["dmr"] = "TFA.LowAmmo.DMR",
["designatedmarksmanrifle"] = "TFA.LowAmmo.DMR",
["sniperrifle"] = "TFA.LowAmmo.Sniper",
["smg"] = "TFA.LowAmmo.SMG",
["submachinegun"] = "TFA.LowAmmo.SMG",
}
SWEP.LastAmmoSoundByType = {
["handgun"] = "TFA.LowAmmo.Handgun_Dry",
["pistol"] = "TFA.LowAmmo.Handgun_Dry",
["dualpistols"] = "TFA.LowAmmo.Handgun_Dry",
["machinepistol"] = "TFA.LowAmmo.Handgun_Dry",
["handcannon"] = "TFA.LowAmmo.Revolver_Dry",
["revolver"] = "TFA.LowAmmo.Revolver_Dry",
["dualrevolvers"] = "TFA.LowAmmo.Revolver_Dry",
["shotgun"] = "TFA.LowAmmo.Shotgun_Dry",
["machinegun"] = "TFA.LowAmmo.MachineGun_Dry",
["lightmachinegun"] = "TFA.LowAmmo.MachineGun_Dry",
["heavymachinegun"] = "TFA.LowAmmo.MachineGun_Dry",
["carbine"] = "TFA.LowAmmo.AssaultRifle_Dry",
["rifle"] = "TFA.LowAmmo.AssaultRifle_Dry",
["assaultrifle"] = "TFA.LowAmmo.AssaultRifle_Dry",
["dmr"] = "TFA.LowAmmo.DMR_Dry",
["designatedmarksmanrifle"] = "TFA.LowAmmo.DMR_Dry",
["sniperrifle"] = "TFA.LowAmmo.Sniper_Dry",
["smg"] = "TFA.LowAmmo.SMG_Dry",
["submachinegun"] = "TFA.LowAmmo.SMG_Dry",
}
function SWEP:AutoDetectLowAmmoSound()
if not self.FireSoundAffectedByClipSize then return end
local t1, t2 = self:GetType():lower():gsub("[^%w]+", ""), (self:GetStatRawL("Type_Displayed") or ""):lower():gsub("[^%w]+", "")
if self.LowAmmoSoundTypeBlacklist[t2] or self.LowAmmoSoundTypeBlacklist[t1] then return end
local clip1 = self:GetStatRawL("Primary.ClipSize")
if (not clip1 or clip1 <= 4) then return end
if not self.LowAmmoSound then
local snd = self.LowAmmoSoundByType[t2] or self.LowAmmoSoundByType[t1] or "TFA.LowAmmo"
if (t2 == "shotgun" or t1 == "shotgun") and not self:GetStatL("LoopedReload") then
snd = "TFA.LowAmmo.AutoShotgun"
end
self:SetStatRawL("LowAmmoSound", snd)
end
if not self.LastAmmoSound then
local snd = self.LastAmmoSoundByType[t2] or self.LastAmmoSoundByType[t1] or "TFA.LowAmmo_Dry"
if (t2 == "shotgun" or t1 == "shotgun") and not self:GetStatL("LoopedReload") then
snd = "TFA.LowAmmo.AutoShotgun_Dry"
end
self:SetStatRawL("LastAmmoSound", snd)
end
end