mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
420 lines
11 KiB
Lua
420 lines
11 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.
|
|
|
|
TFA.Attachments = TFA.Attachments or {}
|
|
TFA.Attachments.Atts = {}
|
|
|
|
TFA.Attachments.Colors = {
|
|
["active"] = Color(252, 151, 50, 255),
|
|
["error"] = Color(225, 0, 0, 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 UpdateWeaponQueue = {}
|
|
|
|
local function UpdateWeapon(wep, ply)
|
|
if not wep.HasInitAttachments or wep.AttachmentCount < 1 then return end
|
|
|
|
UpdateWeaponQueue[ply] = UpdateWeaponQueue[ply] or {}
|
|
|
|
if UpdateWeaponQueue[ply][wep] then return end
|
|
UpdateWeaponQueue[ply][wep] = true
|
|
|
|
for category, data in pairs(wep.Attachments or {}) do
|
|
if type(category) ~= "string" then
|
|
net.Start("TFA_Attachment_Set")
|
|
net.WriteUInt(category, 8)
|
|
|
|
if data.atts and data.atts[data.sel] then
|
|
net.WriteString(data.atts[data.sel])
|
|
else
|
|
net.WriteString("")
|
|
end
|
|
|
|
net.WriteEntity(wep)
|
|
net.Send(ply)
|
|
end
|
|
end
|
|
|
|
UpdateWeaponQueue[ply][wep] = nil
|
|
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 then return end
|
|
UpdateWeapon(wep, ply)
|
|
end)
|
|
|
|
net.Receive("TFA_Attachment_Set", function(len, ply)
|
|
local wep = ply:GetActiveWeapon()
|
|
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
|
|
net.Receive("TFA_Attachment_Set", function(len)
|
|
local cat = net.ReadUInt(8)
|
|
local ind = net.ReadString()
|
|
|
|
local wep = net.ReadEntity()
|
|
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 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)
|
|
end
|
|
|
|
function TFA.Attachments.Register(id, ATTACHMENT)
|
|
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
|
|
|
|
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
|
|
|
|
TFARegisterAttachment = TFA.Attachments.Register
|
|
TFA.Attachments.Path = "tfa/att/"
|
|
TFA_ATTACHMENT_ISUPDATING = false
|
|
|
|
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
|
|
|
|
local inheritanceCached = {}
|
|
|
|
local function patchInheritance(t, basetbl)
|
|
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 _, id in ipairs(tbl) do
|
|
local path = TFA.Attachments.Path .. id
|
|
|
|
local status
|
|
|
|
ProtectedCall(function()
|
|
status = hook.Run("TFABase_ShouldLoadAttachment", id, path)
|
|
end)
|
|
|
|
if status ~= false then
|
|
ATTACHMENT = {}
|
|
|
|
setmetatable(ATTACHMENT, {
|
|
__index = basefunc
|
|
})
|
|
|
|
ATTACHMENT.ID = string.lower(string.Replace(id, ".lua", ""))
|
|
|
|
ProtectedCall(function()
|
|
hook.Run("TFABase_PreBuildAttachment", id, path, ATTACHMENT)
|
|
end)
|
|
|
|
if SERVER then
|
|
AddCSLuaFile(path)
|
|
include(path)
|
|
else
|
|
include(path)
|
|
end
|
|
|
|
ProtectedCall(function()
|
|
hook.Run("TFABase_BuildAttachment", id, path, ATTACHMENT)
|
|
end)
|
|
|
|
TFA.Attachments.Register(ATTACHMENT)
|
|
ATTACHMENT = nil
|
|
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
|
|
end
|
|
|
|
hook.Add("Initialize", "TFAUpdateAttachmentsIPE", TFAUpdateAttachments)
|
|
hook.Add("InitPostEntity", "TFAUpdateAttachmentsIPE", TFAUpdateAttachments)
|
|
|
|
if not VLL2_FILEDEF then
|
|
TFAUpdateAttachments()
|
|
end
|
|
|
|
concommand.Add("sv_tfa_attachments_reload", function(ply, cmd, args, argStr)
|
|
if SERVER and ply:IsAdmin() then
|
|
TFAUpdateAttachments()
|
|
end
|
|
end, function() end, "Reloads all TFA Attachments", {FCVAR_SERVER_CAN_EXECUTE})
|
|
--[[
|
|
|
|
if SERVER then
|
|
util.AddNetworkString("TFA.Attachments.Atts")
|
|
|
|
net.Receive("TFA.Attachments.Atts", function(length, client)
|
|
if IsValid(client) then
|
|
local wep = client:GetActiveWeapon()
|
|
|
|
if IsValid(wep) and wep.Attach and wep.Detach then
|
|
local attach = net.ReadBool()
|
|
local attachment = net.ReadString()
|
|
|
|
if attach then
|
|
wep:Attach(attachment, true)
|
|
else
|
|
wep:Detach(attachment, true)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
hook.Add("PlayerBindPress", "TFA_Attachment_Binds", function(ply, bind, pressed)
|
|
local first4 = string.sub(bind, 1, 4)
|
|
if IsValid(ply) and pressed and first4 == "slot" then
|
|
local wep = ply:GetActiveWeapon()
|
|
|
|
if IsValid(wep) and wep.CLInspectingProgress and wep.CLInspectingProgress > 0.1 then
|
|
--print(string.sub(bind,5,6))
|
|
local slotstr = string.sub(bind, 5, 6)
|
|
|
|
if slotstr and tonumber(slotstr) and wep.Attachments and wep.Attachments[slotnum] and wep.Attachments[slotnum].atts then
|
|
local attbl = wep.Attachments[slotnum]
|
|
local curatt = 0
|
|
local newatt
|
|
|
|
for k, v in pairs(attbl.atts) do
|
|
if wep.AttachmentCache[v] and wep.AttachmentCache[v].active then
|
|
curatt = k
|
|
end
|
|
end
|
|
|
|
newatt = curatt + 1
|
|
|
|
if newatt > #attbl.atts + 1 then
|
|
newatt = 1
|
|
end
|
|
|
|
if attbl.atts[curatt] then
|
|
wep:Detach(attbl.atts[curatt])
|
|
net.Start("TFA.Attachments.Atts")
|
|
net.WriteBool(false)
|
|
net.WriteString(attbl.atts[curatt])
|
|
net.SendToServer()
|
|
end
|
|
|
|
if attbl.atts[newatt] then
|
|
wep:Attach(attbl.atts[newatt])
|
|
net.Start("TFA.Attachments.Atts")
|
|
net.WriteBool(true)
|
|
net.WriteString(attbl.atts[newatt])
|
|
net.SendToServer()
|
|
end
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
end)
|
|
|
|
]]
|
|
-- |