240 lines
7.1 KiB
Lua
240 lines
7.1 KiB
Lua
SWEP.StatCache = {}
|
|
SWEP.HookCache = {}
|
|
SWEP.StatScoreCache = {} -- used by cust menu
|
|
SWEP.MiscCache = {}
|
|
|
|
SWEP.ExcludeFromRawStats = {
|
|
["FullName"] = true,
|
|
["PrintName"] = true,
|
|
["Description"] = true,
|
|
}
|
|
|
|
SWEP.IntegerStats = {
|
|
["ClipSize"] = true,
|
|
["Num"] = true,
|
|
}
|
|
|
|
SWEP.AllowNegativeStats = {
|
|
["RecoilKick"] = true,
|
|
}
|
|
|
|
function SWEP:InvalidateCache()
|
|
self.StatCache = {}
|
|
self.HookCache = {}
|
|
self.StatScoreCache = {}
|
|
self.MiscCache = {}
|
|
self.RecoilPatternCache = {}
|
|
|
|
self.AutoSightPos = nil
|
|
self.AutoSightAng = nil
|
|
end
|
|
|
|
function SWEP:RunHook(val, data)
|
|
if !self.HookCache[val] then
|
|
self.HookCache[val] = {}
|
|
|
|
if self:GetTable()[val] then
|
|
table.insert(self.HookCache[val], self:GetTable()[val])
|
|
end
|
|
|
|
for slot, slottbl in pairs(self.Attachments) do
|
|
if !slottbl.Installed then continue end
|
|
|
|
local atttbl = TacRP.GetAttTable(slottbl.Installed)
|
|
|
|
if atttbl[val] then
|
|
table.insert(self.HookCache[val], atttbl[val])
|
|
end
|
|
end
|
|
end
|
|
|
|
for _, chook in pairs(self.HookCache[val]) do
|
|
local d = chook(self, data)
|
|
if d != nil then
|
|
data = d
|
|
end
|
|
end
|
|
|
|
data = hook.Run("TacRP_" .. val, self, data) or data
|
|
|
|
return data
|
|
end
|
|
|
|
function SWEP:GetBaseValue(val)
|
|
local stat = self:GetTable()[val]
|
|
|
|
local b = TacRP.GetBalanceMode()
|
|
if b > 0 and self.BalanceStats != nil then
|
|
if TacRP.BalanceDefaults[b] and TacRP.BalanceDefaults[b][val] != nil then
|
|
stat = TacRP.BalanceDefaults[b][val]
|
|
end
|
|
for j = b, 1, -1 do
|
|
if self.BalanceStats[b] and self.BalanceStats[b][val] != nil then
|
|
stat = self.BalanceStats[b][val]
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if isnumber(stat) then
|
|
if self.IntegerStats[val] then
|
|
stat = math.ceil(stat)
|
|
end
|
|
if !self.AllowNegativeStats[val] then
|
|
stat = math.max(stat, 0)
|
|
end
|
|
end
|
|
|
|
return stat
|
|
end
|
|
|
|
function SWEP:GetValue(val, static, invert)
|
|
|
|
local cachei = invert and 2 or 1
|
|
|
|
if static == nil then
|
|
static = self.StaticStats
|
|
end
|
|
|
|
local stat = nil
|
|
|
|
-- Generate a cache if it doesn't exist already
|
|
if !self.StatCache[val] or !self.StatCache[val][cachei] then
|
|
|
|
self.StatCache[val] = self.StatCache[val] or {}
|
|
|
|
stat = self:GetBaseValue(val)
|
|
|
|
local modifiers = {
|
|
["stat"] = nil, -- return this unless hook is set
|
|
["hook"] = nil, -- if set, always call hook and use the following values
|
|
["func"] = {}, -- modifying functions
|
|
["set"] = stat, -- override and no prefix
|
|
["prio"] = 0, -- override priority
|
|
["add"] = 0,
|
|
["mul"] = 1,
|
|
}
|
|
|
|
-- local priority = 0
|
|
|
|
if !self.ExcludeFromRawStats[val] then
|
|
for slot, slottbl in pairs(self.Attachments) do
|
|
if !slottbl.Installed then continue end
|
|
|
|
local atttbl = TacRP.GetAttTable(slottbl.Installed)
|
|
|
|
local att_priority = atttbl["Priority_" .. val] or 1
|
|
|
|
if atttbl[val] != nil and att_priority > modifiers.prio then
|
|
-- stat = atttbl[val]
|
|
-- priority = att_priority
|
|
modifiers.set = atttbl[val]
|
|
modifiers.prio = att_priority
|
|
end
|
|
end
|
|
end
|
|
|
|
for slot, slottbl in pairs(self.Attachments) do
|
|
if !slottbl.Installed then continue end
|
|
|
|
local atttbl = TacRP.GetAttTable(slottbl.Installed)
|
|
|
|
local att_priority = atttbl["Override_Priority_" .. val] or 1
|
|
|
|
if atttbl["Override_" .. val] != nil and att_priority > modifiers.prio then
|
|
-- stat = atttbl["Override_" .. val]
|
|
-- priority = att_priority
|
|
modifiers.set = atttbl["Override_" .. val]
|
|
modifiers.prio = att_priority
|
|
end
|
|
|
|
if atttbl["Add_" .. val] then -- isnumber(stat) and
|
|
-- stat = stat + atttbl["Add_" .. val] * (invert and -1 or 1)
|
|
modifiers.add = modifiers.add + atttbl["Add_" .. val] * (invert and -1 or 1)
|
|
end
|
|
|
|
if atttbl["Mult_" .. val] then -- isnumber(stat) and
|
|
if invert then
|
|
-- stat = stat / atttbl["Mult_" .. val]
|
|
modifiers.mul = modifiers.mul / atttbl["Mult_" .. val]
|
|
else
|
|
-- stat = stat * atttbl["Mult_" .. val]
|
|
modifiers.mul = modifiers.mul * atttbl["Mult_" .. val]
|
|
end
|
|
end
|
|
|
|
if atttbl["Func_" .. val] then
|
|
table.insert(modifiers.func, atttbl["Func_" .. val])
|
|
end
|
|
end
|
|
|
|
if isfunction(self["Func_" .. val]) then
|
|
table.insert(modifiers.func, self["Func_" .. val])
|
|
end
|
|
|
|
-- Check for stat hooks. If any exist, we must call it whenever we try to get the stat.
|
|
-- Cache this check so we don't unnecessarily call hook.Run a million times when nobody wants to hook us.
|
|
if table.Count(hook.GetTable()["TacRP_Stat_" .. val] or {}) > 0 then
|
|
modifiers.hook = true
|
|
end
|
|
|
|
-- Calculate the final value
|
|
if isnumber(modifiers.set) then
|
|
modifiers.stat = (modifiers.set + modifiers.add) * modifiers.mul
|
|
if self.IntegerStats[val] then
|
|
modifiers.stat = math.ceil(modifiers.stat)
|
|
end
|
|
if !self.AllowNegativeStats[val] then
|
|
modifiers.stat = math.max(modifiers.stat, 0)
|
|
end
|
|
else
|
|
modifiers.stat = modifiers.set
|
|
end
|
|
|
|
-- Cache our final value, presence of hooks, and summed modifiers
|
|
self.StatCache[val][cachei] = modifiers
|
|
end
|
|
|
|
local cache = self.StatCache[val][cachei]
|
|
if !static and (cache.hook or #cache.func > 0) then
|
|
-- Run the hook
|
|
-- Hooks are expected to modify "set", "prio", "add" and "mul", so we can do all calculations in the right order.
|
|
local modifiers = {set = nil, prio = 0, add = 0, mul = 1}
|
|
|
|
if #cache.func > 0 then
|
|
for _, f in ipairs(cache.func) do
|
|
f(self, modifiers)
|
|
end
|
|
end
|
|
if cache.hook then
|
|
hook.Run("TacRP_Stat_" .. val, self, modifiers)
|
|
if !istable(modifiers) then modifiers = {set = nil, prio = 0, add = 0, mul = 1} end -- some hook isn't cooperating!
|
|
end
|
|
|
|
if modifiers.prio > cache.prio then
|
|
stat = modifiers.set
|
|
else
|
|
stat = cache.set
|
|
end
|
|
|
|
if isnumber(stat) then
|
|
if invert then
|
|
stat = (stat - modifiers.add - cache.add) / modifiers.mul / cache.mul
|
|
else
|
|
stat = (stat + modifiers.add + cache.add) * modifiers.mul * cache.mul
|
|
end
|
|
|
|
if self.IntegerStats[val] then
|
|
stat = math.ceil(stat)
|
|
end
|
|
if !self.AllowNegativeStats[val] then
|
|
stat = math.max(stat, 0)
|
|
end
|
|
end
|
|
else
|
|
stat = cache.stat
|
|
end
|
|
|
|
return stat
|
|
end
|