add sborka
This commit is contained in:
408
garrysmod/addons/tfa_base/lua/tfa/modules/tfa_attachments.lua
Normal file
408
garrysmod/addons/tfa_base/lua/tfa/modules/tfa_attachments.lua
Normal file
@@ -0,0 +1,408 @@
|
||||
TFA.Attachments = TFA.Attachments or {}
|
||||
TFA.Attachments.Atts = {}
|
||||
|
||||
TFA.Attachments.Colors = {
|
||||
["active"] = Color(252, 151, 50, 255),
|
||||
["error"] = Color(225, 0, 0, 255),
|
||||
["error_attached"] = Color(140, 80, 30, 255),
|
||||
["background"] = Color(15, 15, 15, 64),
|
||||
["primary"] = Color(245, 245, 245, 255),
|
||||
["secondary"] = Color(153, 253, 220, 255),
|
||||
["+"] = Color(128, 255, 128, 255),
|
||||
["-"] = Color(255, 128, 128, 255),
|
||||
["="] = Color(192, 192, 192, 255)
|
||||
}
|
||||
|
||||
TFA.Attachments.UIPadding = 2
|
||||
TFA.Attachments.IconSize = 64
|
||||
TFA.Attachments.CategorySpacing = 128
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString("TFA_Attachment_Set")
|
||||
util.AddNetworkString("TFA_Attachment_SetStatus")
|
||||
util.AddNetworkString("TFA_Attachment_Reload")
|
||||
util.AddNetworkString("TFA_Attachment_Request")
|
||||
|
||||
local function UpdateWeapon(wep, ply)
|
||||
for category, data in pairs(wep.Attachments or {}) do
|
||||
if type(category) ~= "string" then
|
||||
net.Start("TFA_Attachment_Set")
|
||||
net.WriteEntity(wep)
|
||||
|
||||
net.WriteUInt(category, 8)
|
||||
if data.atts and data.atts[data.sel] then
|
||||
net.WriteString(data.atts[data.sel])
|
||||
else
|
||||
net.WriteString("")
|
||||
end
|
||||
|
||||
net.Send(ply)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
net.Receive("TFA_Attachment_Request", function(len, ply)
|
||||
if not IsValid(ply) then return end
|
||||
local wep = net.ReadEntity()
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon or not wep.HasInitAttachments or wep.AttachmentCount < 1 then return end
|
||||
local ctime = SysTime()
|
||||
|
||||
local currentScheduleRequest = ply.__TFA_Base_Next_Attachment_Request or ctime
|
||||
local nextScheduleRequest = math.max(ctime + 0.2, currentScheduleRequest + 0.2)
|
||||
ply.__TFA_Base_Next_Attachment_Request = nextScheduleRequest
|
||||
|
||||
if currentScheduleRequest <= ctime then
|
||||
UpdateWeapon(wep, ply)
|
||||
-- elseif currentScheduleRequest - ctime >= 10 then
|
||||
-- ply:Kick("TFA_Attachment_Request spam")
|
||||
else
|
||||
timer.Simple(nextScheduleRequest - ctime, function()
|
||||
if IsValid(ply) and IsValid(wep) then
|
||||
UpdateWeapon(wep, ply)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("TFA_Attachment_Set", function(len, ply)
|
||||
local wep = ply:GetWeapon(net.ReadString())
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then return end
|
||||
|
||||
local cat = net.ReadUInt(8)
|
||||
local ind = net.ReadString()
|
||||
local status = wep:SetTFAAttachment(cat, ind, ply)
|
||||
|
||||
net.Start("TFA_Attachment_SetStatus")
|
||||
net.WriteEntity(wep)
|
||||
net.WriteBool(status)
|
||||
|
||||
if not status then
|
||||
if wep.Attachments and wep.Attachments[cat] then
|
||||
local data = wep.Attachments[cat]
|
||||
net.WriteUInt(cat, 8)
|
||||
|
||||
if data.atts and data.atts[data.sel] then
|
||||
net.WriteString(data.atts[data.sel])
|
||||
else
|
||||
net.WriteString("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
net.Send(ply)
|
||||
end)
|
||||
else
|
||||
sql.Query([[
|
||||
CREATE TABLE IF NOT EXISTS tfa_savedattachments (
|
||||
class VARCHAR(80) NOT NULL,
|
||||
atts TEXT NOT NULL,
|
||||
PRIMARY KEY (class)
|
||||
)
|
||||
]])
|
||||
|
||||
net.Receive("TFA_Attachment_Set", function(len)
|
||||
local wep = net.ReadEntity()
|
||||
|
||||
local cat = net.ReadUInt(8)
|
||||
local ind = net.ReadString()
|
||||
|
||||
if IsValid(wep) and wep.SetTFAAttachment then
|
||||
wep:SetTFAAttachment(cat, ind, false)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("TFA_Attachment_Reload", function(len)
|
||||
TFAUpdateAttachments()
|
||||
end)
|
||||
|
||||
net.Receive("TFA_Attachment_SetStatus", function(len)
|
||||
local weapon = net.ReadEntity()
|
||||
if not IsValid(weapon) then return end
|
||||
local status = net.ReadBool()
|
||||
|
||||
if status then
|
||||
weapon:SaveAttachments()
|
||||
return
|
||||
end
|
||||
surface.PlaySound("buttons/button2.wav")
|
||||
|
||||
local cat = net.ReadUInt(8)
|
||||
local ind = net.ReadString()
|
||||
weapon:SetTFAAttachment(cat, ind, false)
|
||||
end)
|
||||
|
||||
local function request(self)
|
||||
if self._TFA_Attachment_Request then return end
|
||||
if not self.HasInitAttachments or self.AttachmentCount < 1 then return end
|
||||
net.Start("TFA_Attachment_Request")
|
||||
net.WriteEntity(self)
|
||||
net.SendToServer()
|
||||
self._TFA_Attachment_Request = true
|
||||
end
|
||||
|
||||
hook.Add("NotifyShouldTransmit", "TFA_AttachmentsRequest", function(self, notDormant)
|
||||
if not self.IsTFAWeapon or not notDormant then return end
|
||||
request(self)
|
||||
end)
|
||||
|
||||
hook.Add("NetworkEntityCreated", "TFA_AttachmentsRequest", function(self)
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(self) or not self.IsTFAWeapon then return end
|
||||
request(self)
|
||||
end)
|
||||
end)
|
||||
|
||||
hook.Add("OnEntityCreated", "TFA_AttachmentsRequest", function(self)
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(self) or not self.IsTFAWeapon then return end
|
||||
request(self)
|
||||
end)
|
||||
end)
|
||||
|
||||
local LoadQuery = [[SELECT atts FROM tfa_savedattachments WHERE class = '%s']]
|
||||
function TFA.GetSavedAttachments(Weapon)
|
||||
if not IsValid(Weapon) or not Weapon.IsTFAWeapon then return end
|
||||
|
||||
local data = sql.QueryRow(string.format(LoadQuery, sql.SQLStr(Weapon:GetClass(), true)))
|
||||
|
||||
if data and data.atts then
|
||||
return util.JSONToTable(data.atts)
|
||||
end
|
||||
end
|
||||
|
||||
local SaveQuery = [[REPLACE INTO tfa_savedattachments (class, atts) VALUES ('%s', '%s');]]
|
||||
function TFA.SetSavedAttachments(Weapon)
|
||||
if not IsValid(Weapon) or not Weapon.IsTFAWeapon or not next(Weapon.Attachments or {}) then return end
|
||||
|
||||
local seltbl = {}
|
||||
for cat, catTbl in pairs(Weapon.Attachments or {}) do
|
||||
if cat ~= "BaseClass" and catTbl.atts then
|
||||
seltbl[cat] = catTbl.atts[catTbl.sel or -1] or ""
|
||||
end
|
||||
end
|
||||
|
||||
return sql.Query(string.format(SaveQuery, sql.SQLStr(Weapon:GetClass(), true), sql.SQLStr(util.TableToJSON(seltbl), true)))
|
||||
end
|
||||
end
|
||||
|
||||
local function basefunc(t, k)
|
||||
if k == "Base" then return end
|
||||
|
||||
if t.Base then
|
||||
local bt = TFA.Attachments.Atts[t.Base]
|
||||
if bt then return bt[k] end
|
||||
end
|
||||
end
|
||||
|
||||
function TFA.Attachments.SetupBaseTable(id, path)
|
||||
local ATTACHMENT = {}
|
||||
|
||||
setmetatable(ATTACHMENT, {
|
||||
__index = basefunc
|
||||
})
|
||||
|
||||
ATTACHMENT.ID = id
|
||||
|
||||
ProtectedCall(function()
|
||||
hook.Run("TFABase_PreBuildAttachment", id, path, ATTACHMENT)
|
||||
end)
|
||||
|
||||
return ATTACHMENT
|
||||
end
|
||||
|
||||
function TFA.Attachments.Register(id, ATTACHMENT, path)
|
||||
if istable(id) then
|
||||
ATTACHMENT = id
|
||||
id = ATTACHMENT.ID
|
||||
end
|
||||
|
||||
assert(istable(ATTACHMENT), "Invalid attachment argument provided")
|
||||
assert(isstring(id), "Invalid attachment ID provided")
|
||||
local size = table.Count(ATTACHMENT)
|
||||
|
||||
if size == 0 or size == 1 and ATTACHMENT.ID ~= nil then
|
||||
local id2 = id or ATTACHMENT.ID
|
||||
|
||||
if id2 then
|
||||
ErrorNoHalt("[TFA Base] Attempt to register an empty attachment " .. id2 .. "\n")
|
||||
else
|
||||
ErrorNoHalt("[TFA Base] Attempt to register an empty attachment\n")
|
||||
end
|
||||
|
||||
ErrorNoHalt(debug.traceback() .. "\n")
|
||||
MsgC("\n")
|
||||
return
|
||||
end
|
||||
|
||||
ProtectedCall(function()
|
||||
hook.Run("TFABase_BuildAttachment", id, path, ATTACHMENT)
|
||||
end)
|
||||
|
||||
ATTACHMENT.ID = ATTACHMENT.ID or id
|
||||
|
||||
if ATTACHMENT.ID and ATTACHMENT.ID ~= "base" then
|
||||
ATTACHMENT.Base = ATTACHMENT.Base or "base"
|
||||
end
|
||||
|
||||
--[[if not TFA_ATTACHMENT_ISUPDATING and istable(ATTACHMENT.WeaponTable) then
|
||||
TFA.MigrateStructure(ATTACHMENT, ATTACHMENT.WeaponTable, id or "<attachment>", false)
|
||||
end]]
|
||||
|
||||
ProtectedCall(function()
|
||||
hook.Run("TFABase_RegisterAttachment", id, ATTACHMENT)
|
||||
end)
|
||||
|
||||
TFA.Attachments.Atts[ATTACHMENT.ID or ATTACHMENT.Name] = ATTACHMENT
|
||||
end
|
||||
|
||||
function TFA.Attachments.RegisterFromTable(id, tbl, path)
|
||||
local status
|
||||
|
||||
ProtectedCall(function()
|
||||
status = hook.Run("TFABase_ShouldLoadAttachment", id, path)
|
||||
end)
|
||||
|
||||
if status == false then return end
|
||||
|
||||
local ATTACHMENT = TFA.Attachments.SetupBaseTable(id)
|
||||
|
||||
for k, v in pairs(tbl) do
|
||||
ATTACHMENT[k] = v
|
||||
end
|
||||
|
||||
TFA.Attachments.Register(id, ATTACHMENT)
|
||||
end
|
||||
|
||||
TFARegisterAttachment = TFA.Attachments.Register
|
||||
TFA.Attachments.Path = "tfa/att/"
|
||||
TFA.Attachments.Path_Batch = "tfa/attbatch/"
|
||||
TFA_ATTACHMENT_ISUPDATING = false
|
||||
|
||||
local inheritanceCached = {}
|
||||
local missingBaseWarningShown = {}
|
||||
|
||||
local function patchInheritance(t, basetbl)
|
||||
if t.Base and t.Base ~= "base" and not TFA.Attachments.Atts[t.Base] then
|
||||
if t.ID and not missingBaseWarningShown[t.ID] then
|
||||
missingBaseWarningShown[t.ID] = true
|
||||
|
||||
print("[TFA Base] [!] Attachment '" .. t.ID .. "' depends on unknown attachment '" .. t.Base .. "'!")
|
||||
end
|
||||
|
||||
t.Base = "base"
|
||||
end
|
||||
|
||||
if not basetbl and t.Base then
|
||||
basetbl = TFA.Attachments.Atts[t.Base]
|
||||
|
||||
if basetbl and istable(basetbl) and basetbl.ID and not inheritanceCached[basetbl.ID] then
|
||||
inheritanceCached[basetbl.ID] = true
|
||||
patchInheritance(basetbl)
|
||||
end
|
||||
end
|
||||
|
||||
if not (basetbl and istable(basetbl)) then return end
|
||||
|
||||
for k, v in pairs(t) do
|
||||
local baseT = basetbl[k]
|
||||
|
||||
if istable(v) and baseT then
|
||||
patchInheritance(v, baseT)
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(basetbl) do
|
||||
if rawget(t, k) == nil then
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TFAUpdateAttachments(network)
|
||||
if SERVER and network ~= false then
|
||||
net.Start("TFA_Attachment_Reload")
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
TFA.AttachmentColors = TFA.Attachments.Colors --for compatibility
|
||||
TFA.Attachments.Atts = {}
|
||||
TFA_ATTACHMENT_ISUPDATING = true
|
||||
local tbl = file.Find(TFA.Attachments.Path .. "*base*", "LUA")
|
||||
local addtbl = file.Find(TFA.Attachments.Path .. "*", "LUA")
|
||||
|
||||
for _, v in ipairs(addtbl) do
|
||||
if not string.find(v, "base") then
|
||||
table.insert(tbl, #tbl + 1, v)
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(tbl)
|
||||
|
||||
for _, fname in ipairs(tbl) do
|
||||
local path = TFA.Attachments.Path .. fname
|
||||
local id = fname:lower():Replace(".lua", "")
|
||||
|
||||
local status
|
||||
|
||||
ProtectedCall(function()
|
||||
status = hook.Run("TFABase_ShouldLoadAttachment", id, path)
|
||||
end)
|
||||
|
||||
if status ~= false then
|
||||
ATTACHMENT = TFA.Attachments.SetupBaseTable(id, path)
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile(path)
|
||||
include(path)
|
||||
else
|
||||
include(path)
|
||||
end
|
||||
|
||||
TFA.Attachments.Register(id, ATTACHMENT, path)
|
||||
ATTACHMENT = nil
|
||||
end
|
||||
end
|
||||
|
||||
local tbl2 = file.Find(TFA.Attachments.Path_Batch .. "*", "LUA")
|
||||
|
||||
for _, fname in ipairs(tbl2) do
|
||||
local path = TFA.Attachments.Path_Batch .. fname
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile(path)
|
||||
include(path)
|
||||
else
|
||||
include(path)
|
||||
end
|
||||
end
|
||||
|
||||
ProtectedCall(function()
|
||||
hook.Run("TFAAttachmentsLoaded")
|
||||
end)
|
||||
|
||||
for _, v in pairs(TFA.Attachments.Atts) do
|
||||
patchInheritance(v)
|
||||
|
||||
--[[if istable(v.WeaponTable) then
|
||||
TFA.MigrateStructure(v, v.WeaponTable, v.ID or "<attachment>", false)
|
||||
end]]
|
||||
end
|
||||
|
||||
ProtectedCall(function()
|
||||
hook.Run("TFAAttachmentsInitialized")
|
||||
end)
|
||||
|
||||
TFA_ATTACHMENT_ISUPDATING = false
|
||||
|
||||
TFA.ATTACHMENTS_LOADED = true
|
||||
end
|
||||
|
||||
if not VLL2_FILEDEF and TFA.ATTACHMENTS_LOADED then
|
||||
TFAUpdateAttachments(false)
|
||||
end
|
||||
|
||||
concommand.Add("sv_tfa_attachments_reload", function(ply, cmd, args, argStr)
|
||||
if SERVER and (not IsValid(ply) or ply:IsAdmin()) then
|
||||
TFAUpdateAttachments()
|
||||
end
|
||||
end, function() end, "Reloads all TFA Attachments", {FCVAR_SERVER_CAN_EXECUTE})
|
||||
Reference in New Issue
Block a user