mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
165
lua/tfa/modules/cl_tfa_attachment_icon.lua
Normal file
165
lua/tfa/modules/cl_tfa_attachment_icon.lua
Normal file
@@ -0,0 +1,165 @@
|
||||
--[[
|
||||
| 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 padding = TFA.Attachments.UIPadding
|
||||
local PANEL = {}
|
||||
PANEL.Wep = nil
|
||||
PANEL.ID = nil
|
||||
PANEL.Att = nil --Weapon attachment
|
||||
PANEL.Attachment = nil --Actual TFA attachment table
|
||||
|
||||
function PANEL:Init()
|
||||
self.Wep = nil --Weapon Entity
|
||||
self.ID = nil --Attachment ID
|
||||
self.Att = nil --Attachment Category
|
||||
self.Attachment = nil --TFA Attachment Name
|
||||
self:SetMouseInputEnabled(true)
|
||||
self:SetZPos( 500 )
|
||||
end
|
||||
|
||||
function PANEL:SetWeapon(wep)
|
||||
if IsValid(wep) then
|
||||
self.Wep = wep
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetGunAttachment(att)
|
||||
if att ~= nil then
|
||||
self.Att = att
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetAttachment(att)
|
||||
self.Attachment = att
|
||||
end
|
||||
|
||||
function PANEL:SetID(id)
|
||||
if id ~= nil then
|
||||
self.ID = id
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:GetSelected()
|
||||
if not IsValid(self.Wep) then return false end
|
||||
if not self.Att then return end
|
||||
if not self.ID then return end
|
||||
if not self.Wep.Attachments[self.Att] then return end
|
||||
|
||||
return self.Wep.Attachments[self.Att].sel == self.ID
|
||||
end
|
||||
|
||||
function PANEL:AttachSound( attached )
|
||||
if self.Attachment and TFA.Attachments.Atts[self.Attachment] then
|
||||
local att = TFA.Attachments.Atts[self.Attachment]
|
||||
|
||||
local snd = attached and att.AttachSound or att.DetachSound
|
||||
|
||||
if snd and IsValid(self.Wep) then
|
||||
self.Wep:EmitSound(snd)
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
chat.PlaySound()
|
||||
end
|
||||
|
||||
function PANEL:OnMousePressed()
|
||||
if not IsValid(self.Wep) or ( not self.Attachment ) or self.Attachment == "" then return end
|
||||
|
||||
if self:GetSelected() then
|
||||
self.Wep:SetTFAAttachment( self.Att, -1, true )
|
||||
self:AttachSound( false )
|
||||
elseif self.Wep.Attachments[self.Att] and self.Wep:CanAttach(self.Attachment) then
|
||||
self.Wep:SetTFAAttachment( self.Att, self.ID, true )
|
||||
self:AttachSound( true )
|
||||
end
|
||||
end
|
||||
|
||||
local function abbrev( str )
|
||||
local tbl = string.Explode(" ",str,false)
|
||||
local retstr = ""
|
||||
for k,v in ipairs(tbl) do
|
||||
local tmpstr = utf8.sub(v,1,1)
|
||||
retstr = retstr .. ( ( k == 1 ) and string.upper( tmpstr ) or string.lower( tmpstr ) )
|
||||
end
|
||||
return retstr
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
if not IsValid(self.Wep) then return end
|
||||
if self.Attachment == nil then return end
|
||||
if not TFA.Attachments.Atts[self.Attachment] then self:SetMouseInputEnabled(false) return end
|
||||
local sel = self:GetSelected()
|
||||
local col = sel and TFA.Attachments.Colors["active"] or TFA.Attachments.Colors["background"]
|
||||
|
||||
if not sel and not self.Wep:CanAttach(self.Attachment) then
|
||||
col = TFA.Attachments.Colors["error"]
|
||||
end
|
||||
|
||||
draw.RoundedBox(0, 0, 0, w, h, ColorAlpha( col, self.Wep:GetInspectingProgress() * 225))
|
||||
|
||||
if not TFA.Attachments.Atts[self.Attachment].Icon then
|
||||
TFA.Attachments.Atts[self.Attachment].Icon = "entities/tfa_qmark.png"
|
||||
end
|
||||
|
||||
if not TFA.Attachments.Atts[self.Attachment].Icon_Cached then
|
||||
TFA.Attachments.Atts[self.Attachment].Icon_Cached = Material( TFA.Attachments.Atts[self.Attachment].Icon, "noclamp smooth" )
|
||||
end
|
||||
|
||||
local attachmentIcon = TFA.Attachments.Atts[self.Attachment].Icon_Cached
|
||||
|
||||
local iconOverride = self.Wep:GetStat("AttachmentIconOverride." .. self.Attachment)
|
||||
if iconOverride and type(iconOverride) == "IMaterial" then
|
||||
attachmentIcon = iconOverride
|
||||
end
|
||||
|
||||
surface.SetDrawColor(ColorAlpha(color_white, self.Wep:GetInspectingProgress() * 255))
|
||||
surface.SetMaterial(attachmentIcon)
|
||||
surface.DrawTexturedRect(padding, padding, w - padding * 2, h - padding * 2)
|
||||
if not TFA.Attachments.Atts[self.Attachment].ShortName then
|
||||
TFA.Attachments.Atts[self.Attachment].ShortName = abbrev( language.GetPhrase(TFA.Attachments.Atts[self.Attachment].Name) or "")
|
||||
TFA.Attachments.Atts[self.Attachment].ShortNameGenerated = true
|
||||
end
|
||||
draw.SimpleText( string.upper( TFA.Attachments.Atts[self.Attachment].ShortName ) , "TFAAttachmentIconFontTiny", padding / 4, h, ColorAlpha(TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * ( sel and 192 or 64 ) ), TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM)
|
||||
end
|
||||
|
||||
vgui.Register("TFAAttachmentIcon", PANEL, "Panel")
|
||||
|
||||
-- cleanup generated shortnames
|
||||
cvars.AddChangeCallback("gmod_language", function()
|
||||
for id, att in pairs(TFA.Attachments.Atts or {}) do
|
||||
if att.ShortNameGenerated then
|
||||
att.ShortName = nil
|
||||
att.ShortNameGenerated = nil
|
||||
end
|
||||
end
|
||||
end, "tfa_attachment_clearshortnames")
|
||||
291
lua/tfa/modules/cl_tfa_attachment_panel.lua
Normal file
291
lua/tfa/modules/cl_tfa_attachment_panel.lua
Normal file
@@ -0,0 +1,291 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile()
|
||||
return
|
||||
end
|
||||
|
||||
local dimensions, padding
|
||||
local tooltip_mincount = 1
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.HasInitialized = false
|
||||
PANEL.Wep = nil
|
||||
PANEL.Att = nil
|
||||
PANEL.x = -1
|
||||
PANEL.y = -1
|
||||
PANEL.AttachmentTable = {}
|
||||
PANEL.AttachmentIcons = {}
|
||||
PANEL.VAtt = 0
|
||||
|
||||
function PANEL:Init()
|
||||
self.HasInitialized = false
|
||||
self.Wep = nil
|
||||
self.Att = nil
|
||||
self.x = -1
|
||||
self.y = -1
|
||||
self.AttachmentTable = {}
|
||||
self.AttachmentIcons = {}
|
||||
self:SetMouseInputEnabled(true)
|
||||
end
|
||||
|
||||
function PANEL:Initialize()
|
||||
if not IsValid(self.Wep) then return false end
|
||||
|
||||
if not self.Att then return end
|
||||
|
||||
self.AttachmentTable = self.Wep.Attachments[ self.VAtt ]
|
||||
self.VGUIAttachmentTable = self.Wep.VGUIAttachments[ self.VAtt ]
|
||||
|
||||
dimensions = math.Round(TFA.ScaleH(TFA.Attachments.IconSize))
|
||||
padding = math.Round(TFA.ScaleH(TFA.Attachments.UIPadding))
|
||||
|
||||
local attCnt = #self.VGUIAttachmentTable.atts
|
||||
local truewidth = dimensions * attCnt + padding * ( math.max(0,attCnt-1) + 2 )
|
||||
local finalwidth = math.max( truewidth, dimensions * tooltip_mincount + padding * ( math.max(0,tooltip_mincount-1) + 2 ) )
|
||||
|
||||
self:SetSize( finalwidth, dimensions + padding * 2 ) --+ tooltipheightmax + padding * 2 )
|
||||
self:DockPadding( 0, 0, 0, 0 )
|
||||
|
||||
local toppanel = self:Add("DPanel")
|
||||
|
||||
--toppanel:Dock( FILL )
|
||||
--toppanel:Dock(TOP)
|
||||
|
||||
toppanel:SetWidth( finalwidth )
|
||||
toppanel:SetHeight( self:GetTall() )
|
||||
toppanel:DockPadding( padding,padding, padding, padding )
|
||||
toppanel.Paint = function(myself,w,h)
|
||||
if not IsValid(self.Wep) then return end
|
||||
draw.RoundedBox( 0, 0, 0, w, h, ColorAlpha( TFA.Attachments.Colors["secondary"], ( self.Wep:GetInspectingProgress() or 0 ) * 128 ) )
|
||||
end
|
||||
|
||||
self.FinalWidth = finalwidth
|
||||
self.TopDockPanel = toppanel
|
||||
|
||||
--self:InitializeTooltip()
|
||||
|
||||
--[[
|
||||
|
||||
local tooltip = self:Add("TFAAttachmentTip")
|
||||
tooltip:SetWeapon( self.Wep )
|
||||
tooltip:SetAttachment( self.Att )
|
||||
--tooltip:SetHeight( tooltipheightmax + padding * 2 )
|
||||
tooltip:SetSize( finalwidth, tooltipheightmax + padding * 2 )
|
||||
tooltip:SetPos(0, toppanel:GetTall() )
|
||||
self.ToolTip = tooltip
|
||||
|
||||
]]--
|
||||
|
||||
--local keyz = table.GetKeys( self.AttachmentTable.atts )
|
||||
--table.sort(keyz)
|
||||
--PrintTable(keyz)
|
||||
--for _,k in ipairs(keyz) do
|
||||
-- local v = self.AttachmentTable.atts[k]
|
||||
|
||||
self.HasInitialized = true
|
||||
return true
|
||||
end
|
||||
|
||||
function PANEL:PopulateIcons()
|
||||
dimensions = math.Round(TFA.ScaleH(TFA.Attachments.IconSize))
|
||||
padding = math.Round(TFA.ScaleH(TFA.Attachments.UIPadding))
|
||||
|
||||
local i = 0
|
||||
|
||||
for k,v in ipairs( self.VGUIAttachmentTable.atts ) do
|
||||
local p = self.TopDockPanel:Add("TFAAttachmentIcon")
|
||||
|
||||
p:SetWeapon( self.Wep )
|
||||
p:SetGunAttachment( self.Att )
|
||||
p:SetAttachment( v[1] )
|
||||
p:SetID( v[2] )
|
||||
|
||||
p:SetSize(dimensions, dimensions)
|
||||
p:SetPos(dimensions * i + padding * ( i + 1 ), padding)
|
||||
|
||||
i = i + 1
|
||||
--p:SetPos(0,0)
|
||||
--p:DockMargin( 0,0, padding, 0 )
|
||||
--p:Dock(LEFT)
|
||||
self.AttachmentIcons[k] = p
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function PANEL:InitializeTooltip()
|
||||
local tooltip = vgui.Create("TFAAttachmentTip")
|
||||
tooltip.Anchor = self
|
||||
tooltip:SetWeapon(self.Wep)
|
||||
tooltip:SetAttachment(self.Att)
|
||||
tooltip:SetWidth(self.FinalWidth)
|
||||
tooltip:SetPos(0, self.TopDockPanel:GetTall())
|
||||
self.ToolTip = tooltip
|
||||
tooltip.LastTouched = 0
|
||||
tooltip.LastFrameAffectedImportant = 0
|
||||
|
||||
return tooltip
|
||||
end
|
||||
|
||||
function PANEL:SetupTooltip(tooltip)
|
||||
tooltip.Anchor = self
|
||||
tooltip:SetWidth(math.max(self.FinalWidth, tooltip:GetWide()))
|
||||
tooltip:SetPos(0, self.TopDockPanel:GetTall())
|
||||
self.ToolTip = tooltip
|
||||
|
||||
return tooltip
|
||||
end
|
||||
|
||||
--[[
|
||||
function PANEL:CalcVAtt()
|
||||
if not self.VAtt then
|
||||
self.VAtt = 0
|
||||
local keyz = table.GetKeys( self.Wep.Attachments or {} )
|
||||
table.RemoveByValue( keyz, "BaseClass" )
|
||||
table.sort( keyz, function(a,b)
|
||||
--A and B are keys
|
||||
local v1 = self.Wep.Attachments[a]
|
||||
local v2 = self.Wep.Attachments[b]
|
||||
if v1 and v2 and v1.order then
|
||||
return v1.order < ( v2.order or math.huge )
|
||||
else
|
||||
return a < b
|
||||
end
|
||||
end)
|
||||
for k,v in ipairs(keyz) do
|
||||
if self.Att == v then
|
||||
self.VAtt = k
|
||||
end
|
||||
end
|
||||
--self:SetZPos( 100 - self.VAtt )
|
||||
end
|
||||
end
|
||||
]]--
|
||||
|
||||
function PANEL:Think()
|
||||
if not IsValid(self.ToolTip) then return end
|
||||
|
||||
--self:CalcVAtt()
|
||||
|
||||
local header
|
||||
local texttable
|
||||
|
||||
for _,v in pairs( self.AttachmentIcons ) do
|
||||
if v:IsHovered() then
|
||||
header = TFA.Attachments.Atts[v.Attachment].Name
|
||||
texttable = TFA.Attachments.Atts[v.Attachment].Description
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not header then
|
||||
for _,v in pairs( self.AttachmentIcons ) do
|
||||
if v:GetSelected() then
|
||||
header = TFA.Attachments.Atts[v.Attachment].Name
|
||||
texttable = {}--TFA.Attachments.Atts[v.Attachment].Description
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if header and header ~= "" or self.ToolTip.LastTouched < RealTime() then
|
||||
if texttable and #texttable == 0 and self.ToolTip.LastFrameAffectedImportant > RealTime() then
|
||||
return
|
||||
end
|
||||
|
||||
self.ToolTip:SetHeader(header)
|
||||
self.ToolTip:SetTextTable(texttable)
|
||||
self.ToolTip:SetActive( texttable and #texttable > 0 )
|
||||
self.ToolTip:SetContentPanel( self.ContentPanel )
|
||||
self.ToolTip.LastTouched = RealTime() + 0.1
|
||||
|
||||
if texttable and #texttable ~= 0 then
|
||||
self.ToolTip.LastFrameAffectedImportant = RealTime() + 0.1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetContentPanel( p )
|
||||
if IsValid(p) then
|
||||
self.ContentPanel = p
|
||||
else
|
||||
self.ContentPanel = nil
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetWeapon( wepv )
|
||||
if IsValid(wepv) then
|
||||
self.Wep = wepv
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetAttachment( att )
|
||||
if att ~= nil then
|
||||
self.VAtt = att
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetCategory( att )
|
||||
if att ~= nil then
|
||||
self.Att = att
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:GetAnchoredH()
|
||||
return true
|
||||
end
|
||||
|
||||
-- @Deprecated
|
||||
function PANEL:Position()
|
||||
-- self:SetPos( math.floor( self:GetParent():GetWide() - 32 - self:GetWide() ), math.max( self.VAtt - 1, 0 ) * dimensions + math.max( self.VAtt - 1, 0 ) * padding * 4 + math.max( self.VAtt - 1, 0 ) * spacing )
|
||||
-- self.HAnchored = true
|
||||
end
|
||||
|
||||
function PANEL:Paint( w, h )
|
||||
if not self.HasInitialized then return false end
|
||||
|
||||
if not IsValid(self.Wep)
|
||||
or not IsValid(self.Wep:GetOwner())
|
||||
or not self.Wep:GetOwner():IsPlayer()
|
||||
or self.Wep:GetOwner():GetActiveWeapon() ~= self.Wep
|
||||
or (self.Wep:GetInspectingProgress() or 0) < 0.01 then
|
||||
if IsValid(self.ToolTip) then
|
||||
self.ToolTip:Remove()
|
||||
end
|
||||
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register( "TFAAttachmentPanel", PANEL, "Panel" )
|
||||
261
lua/tfa/modules/cl_tfa_attachment_tip.lua
Normal file
261
lua/tfa/modules/cl_tfa_attachment_tip.lua
Normal file
@@ -0,0 +1,261 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile()
|
||||
return
|
||||
end
|
||||
|
||||
local padding = TFA.Attachments.UIPadding
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.Wep = nil
|
||||
PANEL.Header = nil
|
||||
PANEL.TextTable = {}
|
||||
PANEL.DefaultWidth = 0
|
||||
PANEL.DefaultHeight = 0
|
||||
|
||||
function PANEL:SetWidthNeue( val )
|
||||
self.DefaultWidth = val
|
||||
end
|
||||
|
||||
function PANEL:SetHeightNeue( val )
|
||||
self.DefaultHeight = val
|
||||
end
|
||||
|
||||
function PANEL:Init()
|
||||
self.Wep = nil
|
||||
self.Header = nil
|
||||
self.TextTable = {}
|
||||
self.DefaultHeight = 0
|
||||
self.DefaultWidth = 0
|
||||
self:SetMouseInputEnabled(false)
|
||||
self:SetZPos(0)
|
||||
self.SetWidthOld = self.SetWidthOld or self.SetWidth
|
||||
self.SetWidth = self.SetWidthNeue
|
||||
self.SetHeightOld = self.SetHeightOld or self.SetHeight
|
||||
self.SetHeight = self.SetHeightNeue
|
||||
end
|
||||
|
||||
function PANEL:SetWeapon( wepv )
|
||||
if IsValid(wepv) then
|
||||
self.Wep = wepv
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetAttachment( att )
|
||||
if att ~= nil then
|
||||
self:SetZPos( 200 - att )
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetHeader( h )
|
||||
self.Header = h
|
||||
end
|
||||
|
||||
function PANEL:SetTextTable( t )
|
||||
self.TextTable = t or {}
|
||||
end
|
||||
|
||||
PANEL.HeaderFont = "TFAAttachmentTTHeader"
|
||||
PANEL.BodyFont = "TFAAttachmentTTBody"
|
||||
|
||||
function PANEL:GetHeaderHeight()
|
||||
if not IsValid(self.Wep) then return 0 end
|
||||
if not self.Header then return 0 end
|
||||
surface.SetFont(self.HeaderFont)
|
||||
local _, th = surface.GetTextSize( language.GetPhrase(self.Header) )
|
||||
return th + padding * 2
|
||||
end
|
||||
|
||||
function PANEL:GetHeaderSize()
|
||||
if not IsValid(self.Wep) then return 0, 0 end
|
||||
if not self.Header then return 0, 0 end
|
||||
surface.SetFont(self.HeaderFont)
|
||||
local tw, th = surface.GetTextSize( language.GetPhrase(self.Header) )
|
||||
return tw + padding * 2, th + padding * 2
|
||||
end
|
||||
|
||||
function PANEL:GetTextTableHeight()
|
||||
if not self.TextTable or #self.TextTable <= 0 then return 0 end
|
||||
local hv = padding
|
||||
surface.SetFont(self.BodyFont)
|
||||
for _,v in pairs(self.TextTable) do
|
||||
if type(v) == "string" then
|
||||
v = language.GetPhrase(v)
|
||||
local _, th = surface.GetTextSize( v )
|
||||
hv = hv + th
|
||||
end
|
||||
end
|
||||
hv = hv + padding
|
||||
return hv
|
||||
end
|
||||
|
||||
function PANEL:GetTextTableSize( )
|
||||
if not self.TextTable or #self.TextTable <= 0 then return 0, 0 end
|
||||
local mw = 0
|
||||
local hv = padding
|
||||
surface.SetFont(self.BodyFont)
|
||||
for _,v in pairs(self.TextTable) do
|
||||
if type(v) == "string" then
|
||||
v = language.GetPhrase(v)
|
||||
local tw, th = surface.GetTextSize( v )
|
||||
hv = hv + th
|
||||
mw = math.max( mw, tw )
|
||||
end
|
||||
end
|
||||
hv = hv + padding
|
||||
return mw + padding * 2, hv
|
||||
end
|
||||
|
||||
function PANEL:DrawHeader( w, h )
|
||||
if not self.Header then return 0 end
|
||||
surface.SetFont(self.HeaderFont)
|
||||
|
||||
local header = language.GetPhrase(self.Header)
|
||||
local _, th = surface.GetTextSize( header )
|
||||
draw.RoundedBox( 0, 0, 0, w, th + padding * 2, ColorAlpha( TFA.Attachments.Colors["background"], self.Wep:GetInspectingProgress() * 192 ) )
|
||||
if self.AnchoredH then
|
||||
draw.DrawText( header, self.HeaderFont, self:GetWide() / 2 , padding, ColorAlpha( TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * 225 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP )
|
||||
--draw.RoundedBox( 0, w / 2 - tw / 2, padding + th + padding / 4, tw, padding / 2, ColorAlpha( TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * 225 ) )
|
||||
|
||||
--draw.DrawText( header, self.HeaderFont, self:GetWide() - padding, padding, ColorAlpha( TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * 225 ), TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP )
|
||||
--draw.RoundedBox( 0, w - padding - tw, padding + th + padding / 4, tw, padding / 2, ColorAlpha( TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * 225 ) )
|
||||
else
|
||||
draw.DrawText( header, self.HeaderFont, padding, padding, ColorAlpha( TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * 225 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
|
||||
--draw.RoundedBox( 0, padding, padding + th + padding / 4, tw, padding / 2, ColorAlpha( TFA.Attachments.Colors["primary"], self.Wep:GetInspectingProgress() * 225 ) )
|
||||
end
|
||||
return th + padding * 2
|
||||
end
|
||||
|
||||
function PANEL:DrawTextTable( x, y )
|
||||
if not self.TextTable then return 0 end
|
||||
--y = y + padding
|
||||
local hv = padding
|
||||
local acol = TFA.Attachments.Colors["primary"]
|
||||
surface.SetFont(self.BodyFont)
|
||||
for _,v in pairs(self.TextTable) do
|
||||
if type(v) == "table" or type(v) == "vector" then
|
||||
if v.r then
|
||||
acol = Color( v.r or 0, v.g or 0, v.b or 0, v.a or 255 )
|
||||
elseif v.x then
|
||||
acol = Color( v.x or 0, v.y or 0, v.z or 0, v.a or 255 )
|
||||
end
|
||||
end
|
||||
if type(v) == "string" then
|
||||
v = language.GetPhrase(v)
|
||||
local _, th = surface.GetTextSize( v )
|
||||
if self.AnchoredH then
|
||||
--draw.DrawText( v, self.BodyFont, x + self:GetWide() - padding, y + hv, ColorAlpha( acol, self.Wep:GetInspectingProgress() * 225 ), TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP )
|
||||
draw.DrawText( v, self.BodyFont, x + padding * 2, y + hv, ColorAlpha( acol, self.Wep:GetInspectingProgress() * 225 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
|
||||
else
|
||||
draw.DrawText( v, self.BodyFont, x + padding * 2, y + hv, ColorAlpha( acol, self.Wep:GetInspectingProgress() * 225 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
|
||||
end
|
||||
hv = hv + th
|
||||
end
|
||||
end
|
||||
hv = hv + padding
|
||||
return hv
|
||||
end
|
||||
|
||||
function PANEL:CalcSize()
|
||||
local header_w, header_h = self:GetHeaderSize()
|
||||
local text_w, text_h = self:GetTextTableSize()
|
||||
self:SetWidthOld( math.max( self.DefaultWidth, math.max( header_w, text_w ) + padding * 2 ))
|
||||
local h = header_h + text_h
|
||||
if text_h > 0 then
|
||||
h = h + padding * 2
|
||||
end
|
||||
if IsValid( self.ContentPanel ) and not self:GetActive() then
|
||||
local _, cph = self.ContentPanel:LocalToScreen(0,self.ContentPanel:GetTall())
|
||||
local _, yy = self:LocalToScreen(0,0)
|
||||
h = math.min( h, cph - yy )
|
||||
end
|
||||
self:SetHeightOld( h )
|
||||
end
|
||||
|
||||
function PANEL:CalcPos()
|
||||
if IsValid(self.Anchor) then
|
||||
local x,y = self.Anchor:LocalToScreen(0,0)
|
||||
y = y
|
||||
if self.Anchor:GetAnchoredH() then
|
||||
self.AnchoredH = true
|
||||
if IsValid( self.ContentPanel ) and self:GetActive() then
|
||||
local _, cph = self.ContentPanel:LocalToScreen(0,self.ContentPanel:GetTall())
|
||||
self:SetPos( x + self.Anchor:GetWide() - self:GetWide() , math.min( y + self.Anchor:GetTall(), cph - self:GetTall() ) )
|
||||
else
|
||||
self:SetPos( x + self.Anchor:GetWide() - self:GetWide() , math.min( y + self.Anchor:GetTall(), ScrH() - self:GetTall() ) )
|
||||
end
|
||||
else
|
||||
self.AnchoredH = false
|
||||
self:SetPos( x, y + self.Anchor:GetTall() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
self:CalcSize()
|
||||
self:CalcPos()
|
||||
end
|
||||
|
||||
function PANEL:SetContentPanel( p )
|
||||
if IsValid(p) then
|
||||
self.ContentPanel = p
|
||||
else
|
||||
self.ContentPanel = nil
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Paint( w, h )
|
||||
if not IsValid(self.Wep) then return end
|
||||
if ( self.Wep:GetInspectingProgress() or 0 ) < 0.01 then self:Remove() end
|
||||
if IsValid( self.ContentPanel ) and not self:GetActive() then
|
||||
local _, cph = self.ContentPanel:LocalToScreen(0,math.max(self.ContentPanel:GetTall(),32))
|
||||
local _, yy = self:LocalToScreen(0,0)
|
||||
if cph - yy <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
draw.RoundedBox( 0, 0, 0, w, h, ColorAlpha( TFA.Attachments.Colors["background"], self.Wep:GetInspectingProgress() * 192 ) )
|
||||
local hh = self:DrawHeader( w, h )
|
||||
self:DrawTextTable( 0, hh )
|
||||
render.SetScissorRect(0,0,ScrW(),ScrH(),false)
|
||||
end
|
||||
|
||||
function PANEL:SetActive( a )
|
||||
self.Active = a
|
||||
end
|
||||
|
||||
function PANEL:GetActive( a )
|
||||
return self.Active
|
||||
end
|
||||
|
||||
vgui.Register( "TFAAttachmentTip", PANEL, "Panel" )
|
||||
64
lua/tfa/modules/cl_tfa_changelog.lua
Normal file
64
lua/tfa/modules/cl_tfa_changelog.lua
Normal file
@@ -0,0 +1,64 @@
|
||||
--[[
|
||||
| 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 changes = TFA_BASE_VERSION_CHANGES or ""
|
||||
local cvar_changelog = GetConVar("sv_tfa_changelog")
|
||||
|
||||
local sp = game.SinglePlayer()
|
||||
local pdatavar = "tfa_base_version_" .. util.CRC(game.GetIPAddress())
|
||||
|
||||
local function CheckAndDisplayChangeLog(ply)
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
if not cvar_changelog:GetBool() then return end
|
||||
|
||||
if not sp or not ply:IsAdmin() then return end
|
||||
|
||||
local version = tonumber(ply:GetPData(pdatavar))
|
||||
|
||||
if not version or version < TFA_BASE_VERSION then
|
||||
chat.AddText("Updated to TFA Base Version: " .. TFA_BASE_VERSION_STRING)
|
||||
|
||||
if changes ~= "" then
|
||||
chat.AddText(changes)
|
||||
end
|
||||
end
|
||||
|
||||
ply:SetPData(pdatavar, TFA_BASE_VERSION)
|
||||
end
|
||||
|
||||
hook.Add("HUDPaint", "TFA_DISPLAY_CHANGELOG", function()
|
||||
if not LocalPlayer():IsValid() then return end
|
||||
|
||||
CheckAndDisplayChangeLog(LocalPlayer())
|
||||
|
||||
hook.Remove("HUDPaint", "TFA_DISPLAY_CHANGELOG")
|
||||
end)
|
||||
453
lua/tfa/modules/cl_tfa_commands.lua
Normal file
453
lua/tfa/modules/cl_tfa_commands.lua
Normal file
@@ -0,0 +1,453 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
if GetConVar("cl_tfa_inspection_bokeh") == nil then
|
||||
CreateClientConVar("cl_tfa_inspection_bokeh", 0, true, false, "Enable inspection bokeh DOF")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_inspection_bokeh_radius") == nil then
|
||||
CreateClientConVar("cl_tfa_inspection_bokeh_radius", 0.1, true, false, "Inspection bokeh DOF radius", 0.01, 1)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_inspect_hide_in_screenshots") == nil then
|
||||
CreateClientConVar("cl_tfa_inspect_hide_in_screenshots", 0, true, false, "Hide inspection panel in screenshots")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_inspect_hide") == nil then
|
||||
CreateClientConVar("cl_tfa_inspect_hide", 0, true, false, "Hide inspection panel")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_inspect_hide_hud") == nil then
|
||||
CreateClientConVar("cl_tfa_inspect_hide_hud", 0, true, false, "Hide HUD when inspecting weapon (DLib required)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_inspect_newbars") == nil then
|
||||
CreateClientConVar("cl_tfa_inspect_newbars", 0, true, false, "Use new stat bars in inspection screen")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_inspect_spreadinmoa") == nil then
|
||||
CreateClientConVar("cl_tfa_inspect_spreadinmoa", 0, true, false, "Show accuracy in MOA instead of degrees on inspection screen")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewbob_intensity") == nil then
|
||||
CreateClientConVar("cl_tfa_viewbob_intensity", 1, true, false, "View bob intensity multiplier")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_gunbob_intensity") == nil then
|
||||
CreateClientConVar("cl_tfa_gunbob_intensity", 1, true, false, "Gun bob intensity multiplier")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_gunbob_custom") == nil then
|
||||
CreateClientConVar("cl_tfa_gunbob_custom", 1, true, false, "Use custom gun bob")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_3dscope_quality") == nil then
|
||||
CreateClientConVar("cl_tfa_3dscope_quality", -1, true, true, "3D scope quality (0 to 3)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_3dscope") == nil then
|
||||
CreateClientConVar("cl_tfa_3dscope", 1, true, true, "Enable 3D scopes?")
|
||||
else
|
||||
cvars.RemoveChangeCallback( "cl_tfa_3dscope", "3DScopeEnabledCB" )
|
||||
end
|
||||
|
||||
cvars.AddChangeCallback("cl_tfa_3dscope",function(cv,old,new)
|
||||
local lply = LocalPlayer()
|
||||
if lply:IsValid() and IsValid(lply:GetActiveWeapon()) then
|
||||
local wep = lply:GetActiveWeapon()
|
||||
if wep.UpdateScopeType then
|
||||
wep:UpdateScopeType( true )
|
||||
end
|
||||
end
|
||||
end,"3DScopeEnabledCB")
|
||||
|
||||
if GetConVar("cl_tfa_scope_sensitivity_3d") == nil then
|
||||
CreateClientConVar("cl_tfa_scope_sensitivity_3d", 2, true, true) --0 = no sensitivity mod, 1 = scaled to 2D sensitivity, 2 = compensated, 3 = RT FOV compensated
|
||||
else
|
||||
cvars.RemoveChangeCallback( "cl_tfa_scope_sensitivity_3d", "3DScopeModeCB" )
|
||||
end
|
||||
|
||||
cvars.AddChangeCallback("cl_tfa_scope_sensitivity_3d",function(cv,old,new)
|
||||
local lply = LocalPlayer()
|
||||
if lply:IsValid() and IsValid(lply:GetActiveWeapon()) then
|
||||
local wep = lply:GetActiveWeapon()
|
||||
if wep.UpdateScopeType then
|
||||
wep:UpdateScopeType( true )
|
||||
end
|
||||
end
|
||||
end,"3DScopeModeCB")
|
||||
|
||||
if GetConVar("cl_tfa_3dscope_overlay") == nil then
|
||||
CreateClientConVar("cl_tfa_3dscope_overlay", 0, true, true, "Enable 3D scope shadows?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_scope_sensitivity_autoscale") == nil then
|
||||
CreateClientConVar("cl_tfa_scope_sensitivity_autoscale", 100, true, true, "Compensate sensitivity for FOV?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_scope_sensitivity") == nil then
|
||||
CreateClientConVar("cl_tfa_scope_sensitivity", 100, true, true)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_ironsights_toggle") == nil then
|
||||
CreateClientConVar("cl_tfa_ironsights_toggle", 1, true, true, "Toggle ironsights?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_ironsights_resight") == nil then
|
||||
CreateClientConVar("cl_tfa_ironsights_resight", 1, true, true, "Keep ironsights after reload or sprint?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_ironsights_responsive") == nil then
|
||||
CreateClientConVar("cl_tfa_ironsights_responsive", 0, true, true, "Allow both toggle and held down iron sights")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_ironsights_responsive_timer") == nil then
|
||||
CreateClientConVar("cl_tfa_ironsights_responsive_timer", 0.175, true, true, "Time in seconds to determine responsivness time")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_laser_trails") == nil then
|
||||
CreateClientConVar("cl_tfa_laser_trails", 1, true, true, "Enable laser dot trails?")
|
||||
end
|
||||
|
||||
--Crosshair Params
|
||||
if GetConVar("cl_tfa_hud_crosshair_length") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_length", 1, true, false, "Crosshair length")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_length_use_pixels") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_length_use_pixels", 0, true, false, "Should crosshair length use pixels?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_width") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_width", 1, true, false, "Crosshair width")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_enable_custom") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_enable_custom", 1, true, false, "Enable custom crosshair?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_gap_scale") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_gap_scale", 1, true, false, "Crosshair gap scale")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_dot") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_dot", 0, true, false, "Enable crosshair dot?")
|
||||
end
|
||||
|
||||
--Crosshair Color
|
||||
if GetConVar("cl_tfa_hud_crosshair_color_r") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_color_r", 225, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_color_g") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_color_g", 225, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_color_b") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_color_b", 225, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_color_a") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_color_a", 200, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_color_team") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_color_team", 1, true, false, "Should crosshair use team color of entity being aimed at?")
|
||||
end
|
||||
|
||||
--Crosshair Outline
|
||||
if GetConVar("cl_tfa_hud_crosshair_outline_color_r") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_outline_color_r", 5, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_outline_color_g") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_outline_color_g", 5, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_outline_color_b") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_outline_color_b", 5, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_outline_color_a") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_outline_color_a", 200, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_outline_width") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_outline_width", 1, true, false, "Crosshair outline width")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_outline_enabled") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_outline_enabled", 1, true, false, "Enable crosshair outline?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_triangular") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_triangular", 0, true, false, "Enable triangular Crysis-like crosshair?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_crosshair_pump") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_crosshair_pump", 0, true, false, "Enable pump feedback on crosshair?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_enabled") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_enabled", 1, true, false, "Enable hit marker?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_fadetime") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_fadetime", 0.3, true, false, "Hit marker fade time (in seconds)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_solidtime") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_solidtime", 0.1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_scale") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_scale", 1, true, false, "Hit marker scale")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_color_r") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_color_r", 225, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_color_g") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_color_g", 225, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_color_b") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_color_b", 225, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_color_a") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_color_a", 200, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_3d_all") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_3d_all", 0, true, true)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hitmarker_3d_shotguns") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hitmarker_3d_shotguns", 1, true, true)
|
||||
end
|
||||
|
||||
--Other stuff
|
||||
if GetConVar("cl_tfa_hud_ammodata_fadein") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_ammodata_fadein", 0.2, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_hangtime") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_hangtime", 1, true, true)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_enabled") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_enabled", 1, true, false, "Enable 3D2D hud?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_hud_scale") == nil then
|
||||
CreateClientConVar("cl_tfa_hud_scale", 1, true, false, "Size multiplier of HUD elements", .25, 4)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_gasblur") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_gasblur", 0, true, true, "Enable muzzle gas blur?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_muzzlesmoke") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_muzzlesmoke", 1, true, true, "Enable muzzle smoke trail?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_muzzlesmoke_limited") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_muzzlesmoke_limited", 1, true, true, "Limit muzzle smoke trails?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_muzzleflashsmoke") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_muzzleflashsmoke", 1, true, true, "Enable muzzleflash smoke?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_legacy_shells") == nil then
|
||||
CreateClientConVar("cl_tfa_legacy_shells", 0, true, true, "Use legacy shells?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_ejectionsmoke") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_ejectionsmoke", 1, true, true, "Enable shell ejection smoke?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_ejectionlife") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_ejectionlife", 15, true, true, "How long shells exist in the world")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_impact_enabled") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_impact_enabled", 1, true, true, "Enable custom bullet impact effects?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_impact_ricochet_enabled") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_impact_ricochet_enabled", 1, true, true, "Enable bullet ricochet effect?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_impact_ricochet_sparks") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_impact_ricochet_sparks", 6, true, true, "Enable bullet ricochet sparks?")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_impact_ricochet_sparklife") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_impact_ricochet_sparklife", 2, true, true)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_ads_dof") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_ads_dof", 0, true, true, "Enable iron sights DoF (Depth of Field)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_fx_ads_dof_hd") == nil then
|
||||
CreateClientConVar("cl_tfa_fx_ads_dof_hd", 0, true, true, "Enable better quality for DoF")
|
||||
end
|
||||
|
||||
--viewbob
|
||||
|
||||
if GetConVar("cl_tfa_viewbob_animated") == nil then
|
||||
CreateClientConVar("cl_tfa_viewbob_animated", 1, true, false, "Use animated viewbob?")
|
||||
end
|
||||
|
||||
--Viewmodel Mods
|
||||
if GetConVar("cl_tfa_viewmodel_offset_x") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_offset_x", 0, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_offset_y") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_offset_y", 0, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_offset_z") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_offset_z", 0, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_offset_fov") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_offset_fov", 0, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_multiplier_fov") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_multiplier_fov", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_flip") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_flip", 0, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_centered") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_centered", 0, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_nearwall") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_nearwall", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_enabled") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_enabled", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_pitch") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_pitch", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_pitch_is") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_pitch_is", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_vertical") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_vertical", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_vertical_is") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_vertical_is", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_max_vertical") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_max_vertical", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_max_vertical_is") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_max_vertical_is", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_yaw") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_yaw", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_viewmodel_vp_yaw_is") == nil then
|
||||
CreateClientConVar("cl_tfa_viewmodel_vp_yaw_is", 1, true, false)
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_debug_crosshair") == nil then
|
||||
CreateClientConVar("cl_tfa_debug_crosshair", 0, false, false, "Debug crosshair (Admin only)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_debug_animations") == nil then
|
||||
CreateClientConVar("cl_tfa_debug_animations", 0, false, false, "Debug animations (Admin only)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_debug_rt") == nil then
|
||||
CreateClientConVar("cl_tfa_debug_rt", 0, false, false, "Debug RT scopes (Admin only)")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_debug_cache") == nil then
|
||||
CreateClientConVar("cl_tfa_debug_cache", 0, false, false, "Disable stat caching (may cause heavy performance impact!)")
|
||||
end
|
||||
|
||||
local function UpdateColorCVars()
|
||||
RunConsoleCommand("sv_tfa_apply_player_colors")
|
||||
end
|
||||
|
||||
--Reticule Color
|
||||
if GetConVar("cl_tfa_reticule_color_r") == nil then
|
||||
CreateClientConVar("cl_tfa_reticule_color_r", 255, true, true)
|
||||
cvars.AddChangeCallback("cl_tfa_reticule_color_r", UpdateColorCVars, "TFANetworkPlayerColors")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_reticule_color_g") == nil then
|
||||
CreateClientConVar("cl_tfa_reticule_color_g", 100, true, true)
|
||||
cvars.AddChangeCallback("cl_tfa_reticule_color_g", UpdateColorCVars, "TFANetworkPlayerColors")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_reticule_color_b") == nil then
|
||||
CreateClientConVar("cl_tfa_reticule_color_b", 0, true, true)
|
||||
cvars.AddChangeCallback("cl_tfa_reticule_color_b", UpdateColorCVars, "TFANetworkPlayerColors")
|
||||
end
|
||||
|
||||
--Laser Color
|
||||
if GetConVar("cl_tfa_laser_color_r") == nil then
|
||||
CreateClientConVar("cl_tfa_laser_color_r", 255, true, true)
|
||||
cvars.AddChangeCallback("cl_tfa_laser_color_r", UpdateColorCVars, "TFANetworkPlayerColors")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_laser_color_g") == nil then
|
||||
CreateClientConVar("cl_tfa_laser_color_g", 0, true, true)
|
||||
cvars.AddChangeCallback("cl_tfa_laser_color_g", UpdateColorCVars, "TFANetworkPlayerColors")
|
||||
end
|
||||
|
||||
if GetConVar("cl_tfa_laser_color_b") == nil then
|
||||
CreateClientConVar("cl_tfa_laser_color_b", 0, true, true)
|
||||
cvars.AddChangeCallback("cl_tfa_laser_color_b", UpdateColorCVars, "TFANetworkPlayerColors")
|
||||
end
|
||||
234
lua/tfa/modules/cl_tfa_devtools.lua
Normal file
234
lua/tfa/modules/cl_tfa_devtools.lua
Normal file
@@ -0,0 +1,234 @@
|
||||
--[[
|
||||
| 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 cv_dba = GetConVar("cl_tfa_debug_animations")
|
||||
local cv_dbc = GetConVar("cl_tfa_debug_crosshair")
|
||||
|
||||
local state_strings = {}
|
||||
|
||||
for i = 1, 32 do
|
||||
local strcomp = string.rep("%d", i)
|
||||
local slice = {}
|
||||
|
||||
for i2 = 0, i - 1 do
|
||||
table.insert(slice, "band(rshift(state, " .. i2 .. "), 1) == 0 and 0 or 1")
|
||||
end
|
||||
|
||||
local fn = CompileString([[
|
||||
local rshift = bit.rshift
|
||||
local band = bit.band
|
||||
return function(state)
|
||||
return ]] .. table.concat(slice, ", ") .. [[
|
||||
end
|
||||
]], "tfa_dev_tools")()
|
||||
|
||||
state_strings[i] = function(state)
|
||||
return string.format(strcomp, fn(state))
|
||||
end
|
||||
end
|
||||
|
||||
local lastStatusBarWidth = 300
|
||||
local lastAnimStatusWidth = 300
|
||||
|
||||
local STATUS_BAR_COLOR = Color(255, 255, 255)
|
||||
local STATUS_BAR_COLOR_BG = Color(74, 74, 74)
|
||||
|
||||
local function DrawDebugInfo(w, h, ply, wep)
|
||||
if not cv_dba:GetBool() then return end
|
||||
|
||||
local x, y = w * .5, h * .2
|
||||
|
||||
if wep.event_table_overflow then
|
||||
if wep.EventTableEdict[0] then
|
||||
draw.SimpleTextOutlined("UNPREDICTED Event table state:", "TFASleekDebug", x + 240, y, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
|
||||
local y2 = y + TFA.Fonts.SleekHeightDebug
|
||||
|
||||
if not wep._built_event_debug_string_fn then
|
||||
local str = ""
|
||||
local str2 = ""
|
||||
|
||||
for i = 0, #wep.EventTableEdict do
|
||||
str = str .. "%d"
|
||||
|
||||
if (i + 1) % 32 == 0 then
|
||||
str = str .. "\n"
|
||||
end
|
||||
|
||||
if str2 == "" then
|
||||
str2 = "self.EventTableEdict[" .. i .. "].called and 1 or 0"
|
||||
else
|
||||
str2 = str2 .. ", self.EventTableEdict[" .. i .. "].called and 1 or 0"
|
||||
end
|
||||
end
|
||||
|
||||
wep._built_event_debug_string_fn = CompileString([[
|
||||
local format = string.format
|
||||
return function(self)
|
||||
return format([==[]] .. str .. [[]==], ]] .. str2 .. [[)
|
||||
end
|
||||
]], "TFA Base Debug Tools")()
|
||||
end
|
||||
|
||||
for line in string.gmatch(wep:_built_event_debug_string_fn(), "(%S+)") do
|
||||
draw.SimpleTextOutlined(line, "TFASleekDebug", x + 240, y2, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
|
||||
y2 = y2 + TFA.Fonts.SleekHeightDebug
|
||||
end
|
||||
end
|
||||
elseif wep._EventSlotCount ~= 0 then
|
||||
draw.SimpleTextOutlined("Event table state:", "TFASleekDebug", x + 240, y, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
|
||||
local y2 = y + TFA.Fonts.SleekHeightDebug
|
||||
|
||||
for i = 1, wep._EventSlotCount do
|
||||
local state = wep["GetEventStatus" .. i](wep)
|
||||
local stringbake
|
||||
|
||||
if i ~= wep._EventSlotCount then
|
||||
stringbake = state_strings[32](state)
|
||||
else
|
||||
local fn = state_strings[wep._EventSlotNum % 32 + 1]
|
||||
|
||||
if not fn then break end
|
||||
stringbake = fn(state)
|
||||
end
|
||||
|
||||
draw.SimpleTextOutlined(stringbake, "TFASleekDebug", x + 240, y2, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
|
||||
y2 = y2 + TFA.Fonts.SleekHeightDebug
|
||||
end
|
||||
end
|
||||
|
||||
local statusText = string.format(
|
||||
"%s [%.2f, %.2f, %.2f, %.2f]",
|
||||
TFA.Enum.InverseStatus[wep:GetStatus()] or wep:GetStatus(),
|
||||
CurTime() + (wep.CurTimePredictionAdvance or 0),
|
||||
wep:GetStatusProgress(true),
|
||||
wep:GetStatusStart(),
|
||||
wep:GetStatusEnd())
|
||||
|
||||
draw.SimpleTextOutlined(statusText, "TFASleekDebug", x, y, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, color_black)
|
||||
|
||||
--[[if wep:GetStatusProgress() >= 1 then
|
||||
local stW, stH = surface.GetTextSize(statusText)
|
||||
|
||||
lastStatusBarWidth = math.max(300, stW)
|
||||
end]]
|
||||
|
||||
y = y + TFA.Fonts.SleekHeightDebug + 2
|
||||
|
||||
surface.SetDrawColor(STATUS_BAR_COLOR_BG)
|
||||
surface.DrawRect(x - lastStatusBarWidth / 2, y, lastStatusBarWidth, 4)
|
||||
|
||||
surface.SetDrawColor(STATUS_BAR_COLOR)
|
||||
surface.DrawRect(x - lastStatusBarWidth / 2, y, lastStatusBarWidth * wep:GetStatusProgress(true), 4)
|
||||
|
||||
y = y + 8
|
||||
|
||||
local vm = ply:GetViewModel() or NULL
|
||||
|
||||
if vm:IsValid() then
|
||||
local seq = vm:GetSequence()
|
||||
|
||||
draw.SimpleTextOutlined(string.format("%s [%d] (%s/%d)", vm:GetSequenceName(seq), seq, vm:GetSequenceActivityName(seq), vm:GetSequenceActivity(seq)), "TFASleekDebug", x, y, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, color_black)
|
||||
y = y + TFA.Fonts.SleekHeightDebug
|
||||
|
||||
local cycle = vm:GetCycle()
|
||||
local len = vm:SequenceDuration(seq)
|
||||
local rate = vm:GetPlaybackRate()
|
||||
|
||||
local animStatus = string.format("%.2fs / %.2fs (%.2f) @ %d%%", cycle * len, len, cycle, rate * 100)
|
||||
|
||||
draw.SimpleTextOutlined(animStatus, "TFASleekDebug", x, y, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, color_black)
|
||||
--local stW, stH = surface.GetTextSize(animStatus)
|
||||
--lastAnimStatusWidth = math.max(300, stW)
|
||||
|
||||
y = y + TFA.Fonts.SleekHeightDebug + 2
|
||||
|
||||
surface.SetDrawColor(STATUS_BAR_COLOR_BG)
|
||||
surface.DrawRect(x - lastAnimStatusWidth / 2, y, lastAnimStatusWidth, 4)
|
||||
|
||||
if len * rate >= 0.2 then
|
||||
surface.SetDrawColor(STATUS_BAR_COLOR)
|
||||
surface.DrawRect(x - lastAnimStatusWidth / 2, y, lastAnimStatusWidth * cycle, 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function DrawDebugCrosshair(w, h)
|
||||
if not cv_dbc:GetBool() then return end
|
||||
|
||||
surface.SetDrawColor(color_white)
|
||||
surface.DrawRect(w * .5 - 1, h * .5 - 1, 2, 2)
|
||||
end
|
||||
|
||||
local w, h
|
||||
|
||||
hook.Add("HUDPaint", "tfa_drawdebughud", function()
|
||||
local ply = LocalPlayer() or NULL
|
||||
if not ply:IsValid() or not ply:IsAdmin() then return end
|
||||
|
||||
local wep = ply:GetActiveWeapon() or NULL
|
||||
if not wep:IsValid() or not wep.IsTFAWeapon then return end
|
||||
|
||||
w, h = ScrW(), ScrH()
|
||||
|
||||
DrawDebugInfo(w, h, ply, wep)
|
||||
DrawDebugCrosshair(w, h)
|
||||
end)
|
||||
|
||||
|
||||
net.Receive("RecieveDupe", function(len)
|
||||
local mode = net.ReadUInt(3)
|
||||
if (mode == 1) then
|
||||
local name = net.ReadString()
|
||||
local data = sql.Query("SELECT * FROM stored_dupes WHERE Name = '"..name.."';")
|
||||
net.Start("RecieveDupe")
|
||||
net.WriteString(data and data[1].Data or "")
|
||||
net.WriteUInt(file.Time(net.ReadString(), "GAME"), 32)
|
||||
net.WriteUInt(file.Time(net.ReadString(), "GAME"), 32)
|
||||
net.WriteUInt(file.Time(net.ReadString(), "GAME"), 32)
|
||||
net.WriteUInt(file.Time(net.ReadString(), "GAME"), 32)
|
||||
net.WriteUInt(file.Time(net.ReadString(), "GAME"), 32)
|
||||
net.SendToServer()
|
||||
elseif (mode == 2) then
|
||||
local name = net.ReadString()
|
||||
local data = sql.Query("SELECT * FROM stored_dupes WHERE Name = '"..name.."';")
|
||||
if (data) then
|
||||
local string = net.ReadString()
|
||||
print(sql.Query("UPDATE stored_dupes SET Data = '"..string.."' WHERE Name '"..name.."';"))
|
||||
else
|
||||
local string = net.ReadString()
|
||||
sql.Query("INSERT INTO stored_dupes (Name, Data) VALUES ('"..name.."', '"..string.."');")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (!sql.TableExists("stored_dupes")) then
|
||||
sql.Query("CREATE TABLE stored_dupes ( Name TEXT, Data TEXT )")
|
||||
end
|
||||
109
lua/tfa/modules/cl_tfa_fonts.lua
Normal file
109
lua/tfa/modules/cl_tfa_fonts.lua
Normal file
@@ -0,0 +1,109 @@
|
||||
--[[
|
||||
| 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.Fonts = TFA.Fonts or {}
|
||||
|
||||
local ScaleH = TFA.ScaleH
|
||||
|
||||
local function GetFontHeight(fontname) -- UNCACHED!
|
||||
surface.SetFont(fontname)
|
||||
|
||||
local _, h = surface.GetTextSize("W")
|
||||
|
||||
return h
|
||||
end
|
||||
|
||||
local function CreateFonts()
|
||||
local fontdata = {}
|
||||
|
||||
fontdata.font = "Roboto"
|
||||
fontdata.shadow = false
|
||||
fontdata.extended = true
|
||||
fontdata.size = ScaleH(36)
|
||||
surface.CreateFont("TFASleek", fontdata)
|
||||
TFA.Fonts.SleekHeight = GetFontHeight("TFASleek")
|
||||
|
||||
fontdata.size = ScaleH(30)
|
||||
surface.CreateFont("TFASleekMedium", fontdata)
|
||||
TFA.Fonts.SleekHeightMedium = GetFontHeight("TFASleekMedium")
|
||||
|
||||
fontdata.size = ScaleH(24)
|
||||
surface.CreateFont("TFASleekSmall", fontdata)
|
||||
TFA.Fonts.SleekHeightSmall = GetFontHeight("TFASleekSmall")
|
||||
|
||||
fontdata.size = ScaleH(18)
|
||||
surface.CreateFont("TFASleekTiny", fontdata)
|
||||
TFA.Fonts.SleekHeightTiny = GetFontHeight("TFASleekTiny")
|
||||
|
||||
fontdata.size = 24
|
||||
surface.CreateFont("TFASleekDebug", fontdata)
|
||||
TFA.Fonts.SleekHeightDebug = 24
|
||||
|
||||
fontdata = {}
|
||||
|
||||
fontdata.font = "Roboto"
|
||||
fontdata.extended = true
|
||||
fontdata.weight = 500
|
||||
fontdata.size = ScaleH(64)
|
||||
surface.CreateFont("TFA_INSPECTION_TITLE", fontdata)
|
||||
TFA.Fonts.InspectionHeightTitle = GetFontHeight("TFA_INSPECTION_TITLE")
|
||||
|
||||
fontdata.size = ScaleH(32)
|
||||
surface.CreateFont("TFA_INSPECTION_DESCR", fontdata)
|
||||
TFA.Fonts.InspectionHeightDescription = GetFontHeight("TFA_INSPECTION_DESCR")
|
||||
|
||||
fontdata.size = ScaleH(24)
|
||||
surface.CreateFont("TFA_INSPECTION_SMALL", fontdata)
|
||||
TFA.Fonts.InspectionHeightSmall = GetFontHeight("TFA_INSPECTION_SMALL")
|
||||
|
||||
fontdata = {}
|
||||
fontdata.extended = true
|
||||
fontdata.weight = 500
|
||||
|
||||
fontdata.font = "Roboto"
|
||||
fontdata.size = ScaleH(12)
|
||||
surface.CreateFont("TFAAttachmentIconFont", fontdata)
|
||||
fontdata.size = ScaleH(10)
|
||||
surface.CreateFont("TFAAttachmentIconFontTiny", fontdata)
|
||||
|
||||
fontdata.font = "Roboto Condensed"
|
||||
fontdata.size = ScaleH(24)
|
||||
surface.CreateFont("TFAAttachmentTTHeader", fontdata)
|
||||
|
||||
fontdata.font = "Roboto Lt"
|
||||
fontdata.size = ScaleH(18)
|
||||
surface.CreateFont("TFAAttachmentTTBody", fontdata)
|
||||
end
|
||||
|
||||
CreateFonts()
|
||||
|
||||
hook.Add("OnScreenSizeChanged", "TFA_Fonts_Regenerate", CreateFonts)
|
||||
cvars.AddChangeCallback("cl_tfa_hud_scale", CreateFonts, "TFA_RecreateFonts")
|
||||
125
lua/tfa/modules/cl_tfa_hitmarker.lua
Normal file
125
lua/tfa/modules/cl_tfa_hitmarker.lua
Normal file
@@ -0,0 +1,125 @@
|
||||
--[[
|
||||
| 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 ScrW, ScrH = ScrW, ScrH
|
||||
|
||||
local markers = {}
|
||||
|
||||
local cl_drawhud = GetConVar("cl_drawhud")
|
||||
local enabledcvar = GetConVar("cl_tfa_hud_hitmarker_enabled")
|
||||
local solidtimecvar = GetConVar("cl_tfa_hud_hitmarker_solidtime")
|
||||
local fadetimecvar = GetConVar("cl_tfa_hud_hitmarker_fadetime")
|
||||
local scalecvar = GetConVar("cl_tfa_hud_hitmarker_scale")
|
||||
local tricross_cvar = GetConVar("cl_tfa_hud_crosshair_triangular")
|
||||
|
||||
local rcvar = GetConVar("cl_tfa_hud_hitmarker_color_r")
|
||||
local gcvar = GetConVar("cl_tfa_hud_hitmarker_color_g")
|
||||
local bcvar = GetConVar("cl_tfa_hud_hitmarker_color_b")
|
||||
local acvar = GetConVar("cl_tfa_hud_hitmarker_color_a")
|
||||
|
||||
net.Receive("tfaHitmarker", function()
|
||||
if not enabledcvar:GetBool() then return end
|
||||
|
||||
local marker = {
|
||||
time = RealTime()
|
||||
}
|
||||
|
||||
table.insert(markers, marker)
|
||||
end)
|
||||
|
||||
net.Receive("tfaHitmarker3D", function()
|
||||
if not enabledcvar:GetBool() then return end
|
||||
|
||||
local marker = {
|
||||
pos = net.ReadVector(),
|
||||
time = RealTime()
|
||||
}
|
||||
|
||||
table.insert(markers, marker)
|
||||
end)
|
||||
|
||||
local mat_regular = Material("vgui/tfa_hitmarker.png", "smooth mips")
|
||||
local mat_triang = Material("vgui/tfa_hitmarker_triang.png", "smooth mips")
|
||||
|
||||
local cl_tfa_hud_crosshair_enable_custom = GetConVar("cl_tfa_hud_crosshair_enable_custom")
|
||||
|
||||
hook.Add("HUDPaint", "tfaDrawHitmarker", function()
|
||||
if not enabledcvar:GetBool() or not cl_drawhud:GetBool() then return end
|
||||
|
||||
local solidtime = solidtimecvar:GetFloat()
|
||||
local fadetime = math.max(fadetimecvar:GetFloat(), 0.001)
|
||||
|
||||
local r = rcvar:GetFloat()
|
||||
local g = gcvar:GetFloat()
|
||||
local b = bcvar:GetFloat()
|
||||
local a = acvar:GetFloat()
|
||||
|
||||
local w, h = ScrW(), ScrH()
|
||||
local sprh = math.floor((h / 1080) * 64 * scalecvar:GetFloat())
|
||||
local sprh2 = sprh / 2
|
||||
local mX, mY = w / 2, h / 2
|
||||
local ltime = RealTime()
|
||||
|
||||
if cl_tfa_hud_crosshair_enable_custom:GetBool() and isnumber(TFA.LastCrosshairPosX) and isnumber(TFA.LastCrosshairPosY) then
|
||||
local weapon = LocalPlayer():GetActiveWeapon()
|
||||
|
||||
if IsValid(weapon) and weapon.IsTFAWeapon then
|
||||
mX, mY = TFA.LastCrosshairPosX, TFA.LastCrosshairPosY
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(markers) do
|
||||
if v.time then
|
||||
local alpha = math.Clamp(v.time - ltime + solidtime + fadetime, 0, fadetime) / fadetime
|
||||
|
||||
if alpha > 0 then
|
||||
local x, y = mX, mY
|
||||
local visible = true
|
||||
|
||||
if v.pos then
|
||||
local pos = v.pos:ToScreen()
|
||||
x, y = pos.x, pos.y
|
||||
visible = pos.visible
|
||||
end
|
||||
|
||||
if visible then
|
||||
surface.SetDrawColor(r, g, b, a * alpha)
|
||||
surface.SetMaterial(tricross_cvar:GetBool() and mat_triang or mat_regular)
|
||||
surface.DrawTexturedRect(x - sprh2, y - sprh2, sprh, sprh)
|
||||
end
|
||||
else
|
||||
markers[k] = nil
|
||||
end
|
||||
else
|
||||
markers[k] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
107
lua/tfa/modules/cl_tfa_inspection.lua
Normal file
107
lua/tfa/modules/cl_tfa_inspection.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
if CLIENT then
|
||||
local doblur = GetConVar("cl_tfa_inspection_bokeh")
|
||||
local blurdist = GetConVar("cl_tfa_inspection_bokeh_radius")
|
||||
local tfablurintensity = 0
|
||||
local blur_mat = Material("pp/bokehblur")
|
||||
local tab = {}
|
||||
tab["$pp_colour_addr"] = 0
|
||||
tab["$pp_colour_addg"] = 0
|
||||
tab["$pp_colour_addb"] = 0
|
||||
tab["$pp_colour_brightness"] = 0
|
||||
tab["$pp_colour_contrast"] = 1
|
||||
tab["$pp_colour_colour"] = 1
|
||||
tab["$pp_colour_mulr"] = 0
|
||||
tab["$pp_colour_mulg"] = 0
|
||||
tab["$pp_colour_mulb"] = 0
|
||||
|
||||
local function MyDrawBokehDOF()
|
||||
render.UpdateScreenEffectTexture()
|
||||
render.UpdateFullScreenDepthTexture()
|
||||
blur_mat:SetTexture("$BASETEXTURE", render.GetScreenEffectTexture())
|
||||
blur_mat:SetTexture("$DEPTHTEXTURE", render.GetResolvedFullFrameDepth())
|
||||
blur_mat:SetFloat("$size", tfablurintensity * 6)
|
||||
blur_mat:SetFloat("$focus", 0)
|
||||
blur_mat:SetFloat("$focusradius", blurdist:GetFloat())
|
||||
render.SetMaterial(blur_mat)
|
||||
render.DrawScreenQuad()
|
||||
end
|
||||
|
||||
local cv_dxlevel = GetConVar("mat_dxlevel")
|
||||
|
||||
local function Render()
|
||||
tfablurintensity = 0
|
||||
|
||||
if cv_dxlevel:GetInt() < 90 then return end
|
||||
if TFA.DrawingRenderTarget then return end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then return end
|
||||
|
||||
tfablurintensity = wep:GetInspectingProgress()
|
||||
|
||||
if tfablurintensity > 0.01 then
|
||||
if doblur and doblur:GetBool() then
|
||||
MyDrawBokehDOF()
|
||||
end
|
||||
|
||||
tab["$pp_colour_brightness"] = -tfablurintensity * 0.02
|
||||
tab["$pp_colour_contrast"] = 1 - tfablurintensity * 0.1
|
||||
|
||||
DrawColorModify(tab)
|
||||
end
|
||||
end
|
||||
|
||||
local function InitTFABlur()
|
||||
hook.Add("PreDrawViewModels", "PreDrawViewModels_TFA_INSPECT", Render)
|
||||
|
||||
local pp_bokeh = GetConVar( "pp_bokeh" )
|
||||
hook.Remove("NeedsDepthPass","NeedsDepthPass_Bokeh")
|
||||
hook.Add("NeedsDepthPass", "aaaaaaaaaaaaaaaaaaNeedsDepthPass_TFA_Inspect", function()
|
||||
if not ( doblur and doblur:GetBool() ) then return end
|
||||
|
||||
if tfablurintensity > 0.01 or ( pp_bokeh and pp_bokeh:GetBool() ) then
|
||||
DOFModeHack(true)
|
||||
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity","InitTFABlur",InitTFABlur)
|
||||
|
||||
InitTFABlur()
|
||||
end
|
||||
71
lua/tfa/modules/cl_tfa_materials.lua
Normal file
71
lua/tfa/modules/cl_tfa_materials.lua
Normal file
@@ -0,0 +1,71 @@
|
||||
--[[
|
||||
| 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_SCOPE_ACOG = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_closedsight"),
|
||||
reticletex = surface.GetTextureID("scope/gdcw_acogchevron"),
|
||||
dottex = surface.GetTextureID("scope/gdcw_acogcross")
|
||||
}
|
||||
|
||||
TFA_SCOPE_MILDOT = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_scopesight")
|
||||
}
|
||||
|
||||
TFA_SCOPE_SVD = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_svdsight")
|
||||
}
|
||||
|
||||
TFA_SCOPE_PARABOLIC = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_parabolicsight")
|
||||
}
|
||||
|
||||
TFA_SCOPE_ELCAN = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_elcansight"),
|
||||
reticletex = surface.GetTextureID("scope/gdcw_elcanreticle")
|
||||
}
|
||||
|
||||
TFA_SCOPE_GREENDUPLEX = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_closedsight"),
|
||||
reticletex = surface.GetTextureID("scope/gdcw_nvgilluminatedduplex")
|
||||
}
|
||||
|
||||
TFA_SCOPE_AIMPOINT = {
|
||||
scopetex = surface.GetTextureID("scope/gdcw_closedsight"),
|
||||
reticletex = surface.GetTextureID("scope/aimpoint")
|
||||
}
|
||||
|
||||
TFA_SCOPE_MATADOR = {
|
||||
scopetex = surface.GetTextureID("scope/rocketscope")
|
||||
}
|
||||
|
||||
TFA_SCOPE_SCOPESCALE = 4
|
||||
TFA_SCOPE_RETICLESCALE = 1
|
||||
TFA_SCOPE_DOTSCALE = 1
|
||||
92
lua/tfa/modules/cl_tfa_models.lua
Normal file
92
lua/tfa/modules/cl_tfa_models.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
--[[
|
||||
| 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.ClientsideModels = TFA.ClientsideModels or {}
|
||||
|
||||
timer.Create("TFA_UpdateClientsideModels", 0.1, 0, function()
|
||||
local i = 1
|
||||
|
||||
while i <= #TFA.ClientsideModels do
|
||||
local t = TFA.ClientsideModels[i]
|
||||
|
||||
if not t then
|
||||
table.remove(TFA.ClientsideModels, i)
|
||||
elseif not IsValid(t.wep) then
|
||||
t.mdl:Remove()
|
||||
table.remove(TFA.ClientsideModels, i)
|
||||
elseif IsValid(t.wep:GetOwner()) and t.wep:GetOwner().GetActiveWeapon and t.wep ~= t.wep:GetOwner():GetActiveWeapon() then
|
||||
t.mdl:Remove()
|
||||
table.remove(TFA.ClientsideModels, i)
|
||||
elseif t.wep.IsHidden and t.wep:IsHidden() then
|
||||
t.mdl:Remove()
|
||||
table.remove(TFA.ClientsideModels, i)
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
if #TFA.ClientsideModels == 0 then
|
||||
timer.Stop("TFA_UpdateClientsideModels")
|
||||
end
|
||||
end)
|
||||
|
||||
if #TFA.ClientsideModels == 0 then
|
||||
timer.Stop("TFA_UpdateClientsideModels")
|
||||
end
|
||||
|
||||
function TFA.RegisterClientsideModel(cmdl, wepv) -- DEPRECATED
|
||||
-- don't use please
|
||||
-- pleaz
|
||||
TFA.ClientsideModels[#TFA.ClientsideModels + 1] = {
|
||||
["mdl"] = cmdl,
|
||||
["wep"] = wepv
|
||||
}
|
||||
|
||||
timer.Start("TFA_UpdateClientsideModels")
|
||||
end
|
||||
|
||||
local function NotifyShouldTransmit(ent, notdormant)
|
||||
if notdormant or not ent.IsTFAWeapon then return end
|
||||
if ent:GetOwner() == LocalPlayer() then return end
|
||||
|
||||
ent:CleanModels(ent:GetStatRaw("ViewModelElements", TFA.LatestDataVersion))
|
||||
ent:CleanModels(ent:GetStatRaw("WorldModelElements", TFA.LatestDataVersion))
|
||||
end
|
||||
|
||||
local function EntityRemoved(ent)
|
||||
if not ent.IsTFAWeapon then return end
|
||||
|
||||
ent:CleanModels(ent:GetStatRaw("ViewModelElements", TFA.LatestDataVersion))
|
||||
ent:CleanModels(ent:GetStatRaw("WorldModelElements", TFA.LatestDataVersion))
|
||||
end
|
||||
|
||||
hook.Add("NotifyShouldTransmit", "TFA_ClientsideModels", NotifyShouldTransmit)
|
||||
hook.Add("EntityRemoved", "TFA_ClientsideModels", EntityRemoved)
|
||||
203
lua/tfa/modules/cl_tfa_particles_lua.lua
Normal file
203
lua/tfa/modules/cl_tfa_particles_lua.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
--[[
|
||||
| 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 vector_origin = Vector()
|
||||
|
||||
TFA.Particles = TFA.Particles or {}
|
||||
TFA.Particles.FlareParts = {}
|
||||
TFA.Particles.VMAttachments = {}
|
||||
|
||||
local VMAttachments = TFA.Particles.VMAttachments
|
||||
local FlareParts = TFA.Particles.FlareParts
|
||||
|
||||
local ply, vm, wep
|
||||
|
||||
local IsValid_ = FindMetaTable("Entity").IsValid
|
||||
local GetModel = FindMetaTable("Entity").GetModel
|
||||
local lastVMModel, lastVMAtts
|
||||
|
||||
local lastRequired = 0
|
||||
local RealTime = RealTime
|
||||
local FrameTime = FrameTime
|
||||
local LocalPlayer = LocalPlayer
|
||||
local ipairs = ipairs
|
||||
local istable = istable
|
||||
local isfunction = isfunction
|
||||
local WorldToLocal = WorldToLocal
|
||||
local table = table
|
||||
|
||||
local thinkAttachments = {}
|
||||
local slowThinkers = 0
|
||||
|
||||
hook.Add("PreDrawEffects", "TFAMuzzleUpdate", function()
|
||||
if lastRequired < RealTime() then return end
|
||||
|
||||
if not ply then
|
||||
ply = LocalPlayer()
|
||||
end
|
||||
|
||||
if not IsValid_(vm) then
|
||||
vm = ply:GetViewModel()
|
||||
if not IsValid_(vm) then return end
|
||||
end
|
||||
|
||||
local vmmodel = GetModel(vm)
|
||||
|
||||
if vmmodel ~= lastVMModel then
|
||||
lastVMModel = vmmodel
|
||||
lastVMAtts = vm:GetAttachments()
|
||||
end
|
||||
|
||||
if not lastVMAtts then return end
|
||||
|
||||
if slowThinkers == 0 then
|
||||
for i in pairs(thinkAttachments) do
|
||||
VMAttachments[i] = vm:GetAttachment(i)
|
||||
end
|
||||
else
|
||||
for i = 1, #lastVMAtts do
|
||||
VMAttachments[i] = vm:GetAttachment(i)
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(FlareParts) do
|
||||
if v and v.ThinkFunc then
|
||||
v:ThinkFunc()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function TFA.Particles.RegisterParticleThink(particle, partfunc)
|
||||
if not particle or not isfunction(partfunc) then return end
|
||||
|
||||
if not ply then
|
||||
ply = LocalPlayer()
|
||||
end
|
||||
|
||||
if not IsValid_(vm) then
|
||||
vm = ply:GetViewModel()
|
||||
if not IsValid_(vm) then return end
|
||||
end
|
||||
|
||||
particle.ThinkFunc = partfunc
|
||||
|
||||
if IsValid(particle.FollowEnt) and particle.Att then
|
||||
local angpos = particle.FollowEnt:GetAttachment(particle.Att)
|
||||
|
||||
if angpos then
|
||||
particle.OffPos = WorldToLocal(particle:GetPos(), particle:GetAngles(), angpos.Pos, angpos.Ang)
|
||||
end
|
||||
end
|
||||
|
||||
local att = particle.Att
|
||||
|
||||
local isFast = partfunc == TFA.Particles.FollowMuzzle and att ~= nil
|
||||
local isVM = particle.FollowEnt == vm
|
||||
|
||||
if isFast then
|
||||
if isVM then
|
||||
thinkAttachments[att] = (thinkAttachments[att] or 0) + 1
|
||||
end
|
||||
else
|
||||
slowThinkers = slowThinkers + 1
|
||||
end
|
||||
|
||||
table.insert(FlareParts, particle)
|
||||
|
||||
timer.Simple(particle:GetDieTime(), function()
|
||||
if particle then
|
||||
table.RemoveByValue(FlareParts, particle)
|
||||
end
|
||||
|
||||
if not isFast then
|
||||
slowThinkers = slowThinkers - 1
|
||||
elseif isVM and att then
|
||||
thinkAttachments[att] = thinkAttachments[att] - 1
|
||||
if thinkAttachments[att] <= 0 then thinkAttachments[att] = nil end
|
||||
end
|
||||
end)
|
||||
|
||||
lastRequired = RealTime() + 0.5
|
||||
end
|
||||
|
||||
function TFA.Particles.FollowMuzzle(self, first)
|
||||
if lastRequired < RealTime() then
|
||||
lastRequired = RealTime() + 0.5
|
||||
return
|
||||
end
|
||||
|
||||
lastRequired = RealTime() + 0.5
|
||||
|
||||
if self.isfirst == nil then
|
||||
self.isfirst = false
|
||||
first = true
|
||||
end
|
||||
|
||||
if not IsValid_(ply) or not IsValid_(vm) then return end
|
||||
wep = ply:GetActiveWeapon()
|
||||
if IsValid(wep) and wep.IsCurrentlyScoped and wep:IsCurrentlyScoped() then return end
|
||||
|
||||
if not IsValid(self.FollowEnt) then return end
|
||||
local owent = self.FollowEnt:GetOwner() or self.FollowEnt
|
||||
if not IsValid(owent) then return end
|
||||
|
||||
local firvel
|
||||
|
||||
if first then
|
||||
firvel = owent:GetVelocity() * FrameTime() * 1.1
|
||||
else
|
||||
firvel = vector_origin
|
||||
end
|
||||
|
||||
if not self.Att or not self.OffPos then return end
|
||||
|
||||
if self.FollowEnt == vm then
|
||||
local angpos = VMAttachments[self.Att]
|
||||
|
||||
if angpos then
|
||||
local tmppos = LocalToWorld(self.OffPos, self:GetAngles(), angpos.Pos, angpos.Ang)
|
||||
local npos = tmppos + self:GetVelocity() * FrameTime()
|
||||
self.OffPos = WorldToLocal(npos + firvel, self:GetAngles(), angpos.Pos, angpos.Ang)
|
||||
self:SetPos(npos + firvel)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local angpos = self.FollowEnt:GetAttachment(self.Att)
|
||||
|
||||
if angpos then
|
||||
local tmppos = LocalToWorld(self.OffPos, self:GetAngles(), angpos.Pos, angpos.Ang)
|
||||
local npos = tmppos + self:GetVelocity() * FrameTime()
|
||||
self.OffPos = WorldToLocal(npos + firvel * 0.5, self:GetAngles(), angpos.Pos, angpos.Ang)
|
||||
self:SetPos(npos + firvel)
|
||||
end
|
||||
end
|
||||
66
lua/tfa/modules/cl_tfa_projtex.lua
Normal file
66
lua/tfa/modules/cl_tfa_projtex.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
--[[
|
||||
| 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 ply = LocalPlayer()
|
||||
local LocalPlayer = LocalPlayer
|
||||
|
||||
hook.Add("PreRender", "TFACleanupProjectedTextures", function()
|
||||
if not IsValid(ply) then
|
||||
ply = LocalPlayer()
|
||||
if not IsValid(ply) then return end
|
||||
end
|
||||
|
||||
local wep = ply:GetActiveWeapon()
|
||||
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then
|
||||
if IsValid(ply.TFAFlashlightGun) then
|
||||
ply.TFAFlashlightGun:Remove()
|
||||
end
|
||||
|
||||
if IsValid(ply.TFALaserDot) then
|
||||
ply.TFALaserDot:Remove()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PrePlayerDraw", "TFACleanupProjectedTextures", function(plyv)
|
||||
local wep = plyv:GetActiveWeapon()
|
||||
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then
|
||||
if IsValid(plyv.TFAFlashlightGun) then
|
||||
plyv.TFAFlashlightGun:Remove()
|
||||
end
|
||||
|
||||
if IsValid(plyv.TFALaserDot) then
|
||||
plyv.TFALaserDot:Remove()
|
||||
end
|
||||
end
|
||||
end)
|
||||
176
lua/tfa/modules/cl_tfa_rendertarget.lua
Normal file
176
lua/tfa/modules/cl_tfa_rendertarget.lua
Normal file
@@ -0,0 +1,176 @@
|
||||
--[[
|
||||
| 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.DrawingRenderTarget = false
|
||||
|
||||
local props = {
|
||||
["$translucent"] = 1
|
||||
}
|
||||
|
||||
local TFA_RTMat = CreateMaterial("tfa_rtmaterial", "UnLitGeneric", props) --Material("models/weapons/TFA/shared/optic")
|
||||
local TFA_RTScreen, TFA_RTScreenO = {}, {}
|
||||
local tgt
|
||||
local old_bt
|
||||
local ply, vm, wep
|
||||
local w, h
|
||||
local qualitySizes
|
||||
|
||||
local function callFunc()
|
||||
if wep.RTCode then
|
||||
wep:RTCode(TFA_RTMat, w, h)
|
||||
end
|
||||
|
||||
if wep:GetStatL("RTDrawEnabled") then
|
||||
wep:CallAttFunc("RTCode", TFA_RTMat, w, h)
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("OnScreenSizeChanged", "TFA_rendertargets", function()
|
||||
qualitySizes = nil
|
||||
TFA_RTScreen, TFA_RTScreenO = {}, {}
|
||||
end)
|
||||
|
||||
local function TFARenderScreen()
|
||||
ply = GetViewEntity()
|
||||
|
||||
if not IsValid(ply) or not ply:IsPlayer() then
|
||||
ply = LocalPlayer()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not IsValid(vm) then
|
||||
vm = ply:GetViewModel()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
wep = ply:GetActiveWeapon()
|
||||
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then return end
|
||||
|
||||
if not wep.MaterialCached then
|
||||
wep.MaterialCached = true
|
||||
wep.MaterialCached_V = nil
|
||||
wep.MaterialCached_W = nil
|
||||
end
|
||||
|
||||
local skinStat = wep:GetStatL("Skin")
|
||||
if isnumber(skinStat) then
|
||||
if vm:GetSkin() ~= skinStat then
|
||||
vm:SetSkin(skinStat)
|
||||
end
|
||||
end
|
||||
|
||||
if wep:GetStatL("MaterialTable_V") and not wep.MaterialCached_V then
|
||||
wep.MaterialCached_V = {}
|
||||
vm:SetSubMaterial()
|
||||
local collectedKeys = table.GetKeys(wep:GetStatL("MaterialTable_V"))
|
||||
table.Merge(collectedKeys, table.GetKeys(wep:GetStatL("MaterialTable")))
|
||||
|
||||
for _, k in pairs(collectedKeys) do
|
||||
if k ~= "BaseClass" then
|
||||
local v = wep:GetStatL("MaterialTable_V")[k]
|
||||
|
||||
if not wep.MaterialCached_V[k] then
|
||||
vm:SetSubMaterial(k - 1, v)
|
||||
wep.MaterialCached_V[k] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not (wep:GetStatL("RTDrawEnabled") or wep.RTCode ~= nil) then return end
|
||||
w, h = ScrW(), ScrH()
|
||||
|
||||
if not qualitySizes then
|
||||
qualitySizes = {
|
||||
[0] = h,
|
||||
[1] = math.Round(h * 0.5),
|
||||
[2] = math.Round(h * 0.25),
|
||||
[3] = math.Round(h * 0.125),
|
||||
}
|
||||
end
|
||||
|
||||
local quality = TFA.RTQuality()
|
||||
|
||||
if wep:GetStatL("RTOpaque") then
|
||||
tgt = TFA_RTScreenO[quality]
|
||||
|
||||
if not tgt then
|
||||
local size = qualitySizes[quality]
|
||||
tgt = GetRenderTargetEx("TFA_RT_ScreenO_" .. size, size, size, RT_SIZE_NO_CHANGE, MATERIAL_RT_DEPTH_SHARED, 0, CREATERENDERTARGETFLAGS_UNFILTERABLE_OK, IMAGE_FORMAT_RGB888)
|
||||
TFA_RTScreenO[quality] = tgt
|
||||
end
|
||||
else
|
||||
tgt = TFA_RTScreen[quality]
|
||||
|
||||
if not tgt then
|
||||
local size = qualitySizes[quality]
|
||||
tgt = GetRenderTargetEx("TFA_RT_Screen_" .. size, size, size, RT_SIZE_NO_CHANGE, MATERIAL_RT_DEPTH_SHARED, 0, CREATERENDERTARGETFLAGS_UNFILTERABLE_OK, IMAGE_FORMAT_RGBA8888)
|
||||
TFA_RTScreen[quality] = tgt
|
||||
end
|
||||
end
|
||||
|
||||
TFA.LastRTUpdate = CurTime() + 0.01
|
||||
|
||||
render.PushRenderTarget(tgt)
|
||||
render.Clear(0, 0, 0, 255, true, true)
|
||||
|
||||
TFA.DrawingRenderTarget = true
|
||||
render.CullMode(MATERIAL_CULLMODE_CCW)
|
||||
ProtectedCall(callFunc)
|
||||
TFA.DrawingRenderTarget = false
|
||||
|
||||
render.SetScissorRect(0, 0, 0, 0, false)
|
||||
render.PopRenderTarget()
|
||||
|
||||
if old_bt ~= tgt then
|
||||
TFA_RTMat:SetTexture("$basetexture", tgt)
|
||||
old_bt = tgt
|
||||
end
|
||||
|
||||
if wep:GetStatL("RTMaterialOverride", -1) >= 0 then
|
||||
wep:GetOwner():GetViewModel():SetSubMaterial(wep:GetStatL("RTMaterialOverride"), "!tfa_rtmaterial")
|
||||
end
|
||||
end
|
||||
|
||||
hook.Remove("PostRender", "TFASCREENS")
|
||||
|
||||
hook.Add("PreRender", "TFASCREENS", function()
|
||||
if not TFA.RT_DRAWING then
|
||||
TFA.RT_DRAWING = true
|
||||
TFARenderScreen()
|
||||
TFA.RT_DRAWING = false
|
||||
end
|
||||
end)
|
||||
|
||||
TFA.RT_DRAWING = false
|
||||
111
lua/tfa/modules/cl_tfa_rtbgblur.lua
Normal file
111
lua/tfa/modules/cl_tfa_rtbgblur.lua
Normal file
@@ -0,0 +1,111 @@
|
||||
--[[
|
||||
| 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 FT = FrameTime
|
||||
|
||||
local tfablurintensity = 0
|
||||
|
||||
local cv_3dscopes = GetConVar("cl_tfa_3dscope")
|
||||
|
||||
local cv_mode = CreateClientConVar("cl_tfa_fx_rtscopeblur_mode", "1", true, false)
|
||||
local funcs = {}
|
||||
|
||||
local cv_blur_passes = CreateClientConVar("cl_tfa_fx_rtscopeblur_passes", "3", true, false)
|
||||
local cv_blur_intensity = CreateClientConVar("cl_tfa_fx_rtscopeblur_intensity", "4", true, false)
|
||||
local blurTex = Material("pp/blurscreen")
|
||||
funcs[1] = function()
|
||||
surface.SetDrawColor(color_white)
|
||||
render.SetMaterial(blurTex)
|
||||
local passes = cv_blur_passes:GetInt()
|
||||
|
||||
for _ = 1, passes do
|
||||
render.UpdateScreenEffectTexture()
|
||||
|
||||
blurTex:SetFloat("$blur", tfablurintensity * cv_blur_intensity:GetFloat() / math.sqrt(passes) )
|
||||
blurTex:Recompute()
|
||||
|
||||
render.DrawScreenQuad()
|
||||
end
|
||||
end
|
||||
|
||||
local blur_mat = Material("pp/bokehblur")
|
||||
funcs[2] = function()
|
||||
render.UpdateScreenEffectTexture()
|
||||
render.UpdateFullScreenDepthTexture()
|
||||
|
||||
blur_mat:SetTexture("$BASETEXTURE", render.GetScreenEffectTexture())
|
||||
blur_mat:SetTexture("$DEPTHTEXTURE", render.GetResolvedFullFrameDepth())
|
||||
|
||||
blur_mat:SetFloat("$size", tfablurintensity * cv_blur_intensity:GetFloat() * 1.5 )
|
||||
blur_mat:SetFloat("$focus", 0)
|
||||
blur_mat:SetFloat("$focusradius", 0.25)
|
||||
|
||||
render.SetMaterial(blur_mat)
|
||||
render.DrawScreenQuad()
|
||||
end
|
||||
|
||||
hook.Add("PostDrawTranslucentRenderables", "tfa_draw_rt_blur", function()
|
||||
if TFA.DrawingRenderTarget then return end
|
||||
|
||||
if not cv_3dscopes:GetBool() then return end
|
||||
|
||||
local mode = cv_mode:GetInt()
|
||||
if not isfunction(funcs[mode]) then return end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
if not IsValid(ply) or ply:ShouldDrawLocalPlayer() then return end
|
||||
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon or not wep.GetStat then return end
|
||||
if not wep:GetStatL("RTBGBlur") then return end
|
||||
if not wep:GetStatL("RTDrawEnabled") and not wep:GetStatL("RTMaterialOverride") and not wep.RTCode then return end
|
||||
|
||||
if wep.GLDeployed and wep:GLDeployed() then
|
||||
tfablurintensity = Lerp(FT() * 12.5, tfablurintensity, 0)
|
||||
else
|
||||
local progress = math.Clamp(wep.CLIronSightsProgress or 0, 0, 1)
|
||||
tfablurintensity = Lerp(FT() * 25, tfablurintensity, progress)
|
||||
end
|
||||
|
||||
if tfablurintensity > 0.05 then
|
||||
funcs[mode]()
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("NeedsDepthPass", "aaaaaaaaaaaaaaaaaaNeedsDepthPass_TJA_IronSight", function()
|
||||
if tfablurintensity > 0.05 and cv_mode:GetInt() == 2 then
|
||||
if not cv_3dscopes:GetBool() then return end
|
||||
|
||||
DOFModeHack(true)
|
||||
|
||||
return true
|
||||
end
|
||||
end)
|
||||
147
lua/tfa/modules/cl_tfa_settingsmenu.lua
Normal file
147
lua/tfa/modules/cl_tfa_settingsmenu.lua
Normal file
@@ -0,0 +1,147 @@
|
||||
--[[
|
||||
| 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 IsSinglePlayer = game.SinglePlayer()
|
||||
|
||||
function TFA.NumSliderNet(_parent, label, convar, min, max, decimals, ...)
|
||||
local gconvar = assert(GetConVar(convar), "Unknown ConVar: " .. convar .. "!")
|
||||
local newpanel
|
||||
|
||||
if IsSinglePlayer then
|
||||
newpanel = _parent:NumSlider(label, convar, min, max, decimals, ...)
|
||||
else
|
||||
newpanel = _parent:NumSlider(label, nil, min, max, decimals, ...)
|
||||
end
|
||||
|
||||
decimals = decimals or 0
|
||||
local sf = "%." .. decimals .. "f"
|
||||
|
||||
if not IsSinglePlayer then
|
||||
local ignore = false
|
||||
|
||||
newpanel.Think = function(_self)
|
||||
if _self._wait_for_update and _self._wait_for_update > RealTime() then return end
|
||||
local float = gconvar:GetFloat()
|
||||
|
||||
if _self:GetValue() ~= float then
|
||||
ignore = true
|
||||
_self:SetValue(float)
|
||||
ignore = false
|
||||
end
|
||||
end
|
||||
|
||||
newpanel.OnValueChanged = function(_self, _newval)
|
||||
if ignore then return end
|
||||
|
||||
if not LocalPlayer():IsAdmin() then return end
|
||||
_self._wait_for_update = RealTime() + 1
|
||||
|
||||
timer.Create("tfa_vgui_" .. convar, 0.5, 1, function()
|
||||
if not LocalPlayer():IsAdmin() then return end
|
||||
|
||||
net.Start("TFA_SetServerCommand")
|
||||
net.WriteString(convar)
|
||||
net.WriteString(string.format(sf, _newval))
|
||||
net.SendToServer()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return newpanel
|
||||
end
|
||||
|
||||
function TFA.CheckBoxNet(_parent, label, convar, ...)
|
||||
local gconvar = assert(GetConVar(convar), "Unknown ConVar: " .. convar .. "!")
|
||||
local newpanel
|
||||
|
||||
if IsSinglePlayer then
|
||||
newpanel = _parent:CheckBox(label, convar, ...)
|
||||
else
|
||||
newpanel = _parent:CheckBox(label, nil, ...)
|
||||
end
|
||||
|
||||
if not IsSinglePlayer then
|
||||
if not IsValid(newpanel.Button) then return newpanel end
|
||||
|
||||
newpanel.Button.Think = function(_self)
|
||||
local bool = gconvar:GetBool()
|
||||
|
||||
if _self:GetChecked() ~= bool then
|
||||
_self:SetChecked(bool)
|
||||
end
|
||||
end
|
||||
|
||||
newpanel.OnChange = function(_self, _bVal)
|
||||
if not LocalPlayer():IsAdmin() then return end
|
||||
if _bVal == gconvar:GetBool() then return end
|
||||
|
||||
net.Start("TFA_SetServerCommand")
|
||||
net.WriteString(convar)
|
||||
net.WriteString(_bVal and "1" or "0")
|
||||
net.SendToServer()
|
||||
end
|
||||
end
|
||||
|
||||
return newpanel
|
||||
end
|
||||
|
||||
function TFA.ComboBoxNet(_parent, label, convar, ...)
|
||||
local gconvar = assert(GetConVar(convar), "Unknown ConVar: " .. convar .. "!")
|
||||
local combobox, leftpanel
|
||||
|
||||
if IsSinglePlayer then
|
||||
combobox, leftpanel = _parent:ComboBox(label, convar, ...)
|
||||
else
|
||||
combobox, leftpanel = _parent:ComboBox(label, nil, ...)
|
||||
end
|
||||
|
||||
if not IsSinglePlayer then
|
||||
combobox.Think = function(_self)
|
||||
local value = gconvar:GetString()
|
||||
|
||||
if _self:GetValue() ~= value then
|
||||
_self:SetValue(value)
|
||||
end
|
||||
end
|
||||
|
||||
combobox.OnSelect = function(_self, _index, _value, _data)
|
||||
if not LocalPlayer():IsAdmin() then return end
|
||||
local _newval = tostring(_data or _value)
|
||||
|
||||
net.Start("TFA_SetServerCommand")
|
||||
net.WriteString(convar)
|
||||
net.WriteString(_newval)
|
||||
net.SendToServer()
|
||||
end
|
||||
end
|
||||
|
||||
return combobox, leftpanel
|
||||
end
|
||||
358
lua/tfa/modules/cl_tfa_stencilsights.lua
Normal file
358
lua/tfa/modules/cl_tfa_stencilsights.lua
Normal file
@@ -0,0 +1,358 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
-- stencil functions
|
||||
local useStencils = render.SupportsPixelShaders_2_0() and render.SupportsVertexShaders_2_0()
|
||||
|
||||
local function defineCanvas(ref)
|
||||
render.UpdateScreenEffectTexture()
|
||||
render.ClearStencil()
|
||||
render.SetStencilEnable(true)
|
||||
render.SetStencilCompareFunction(STENCIL_ALWAYS)
|
||||
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||
render.SetStencilFailOperation(STENCIL_KEEP)
|
||||
render.SetStencilZFailOperation(STENCIL_REPLACE)
|
||||
render.SetStencilWriteMask(255)
|
||||
render.SetStencilTestMask(255)
|
||||
render.SetStencilReferenceValue(ref or 54)
|
||||
end
|
||||
|
||||
local function drawOn()
|
||||
render.SetStencilCompareFunction(STENCIL_EQUAL)
|
||||
end
|
||||
|
||||
local function stopCanvas()
|
||||
render.SetStencilEnable(false)
|
||||
end
|
||||
|
||||
-- main draw functions
|
||||
local CachedMaterials = {}
|
||||
|
||||
local DrawFunctions = {}
|
||||
|
||||
do -- Flat reticle, stays at center or moves with recoil
|
||||
local function ScreenScaleH(num)
|
||||
return num * (ScrH() / 480)
|
||||
end
|
||||
|
||||
DrawFunctions[TFA.Enum.RETICLE_FLAT] = function(vm, ply, wep, SightElementTable)
|
||||
local ReticleMaterial = wep:GetStat("StencilSight_ReticleMaterial")
|
||||
if not ReticleMaterial then return end
|
||||
|
||||
if type(ReticleMaterial) == "string" then
|
||||
CachedMaterials[ReticleMaterial] = CachedMaterials[ReticleMaterial] or Material(ReticleMaterial, "noclamp nocull smooth")
|
||||
ReticleMaterial = CachedMaterials[ReticleMaterial]
|
||||
end
|
||||
|
||||
local ReticleSize = wep:GetStat("StencilSight_ReticleSize")
|
||||
if not ReticleSize then return end
|
||||
|
||||
if wep:GetStat("StencilSight_ScaleReticleByScreenHeight", true) then
|
||||
ReticleSize = ScreenScaleH(ReticleSize)
|
||||
end
|
||||
|
||||
if wep:GetStat("StencilSight_ScaleReticleByProgress", true) then
|
||||
ReticleSize = ReticleSize * wep.IronSightsProgress
|
||||
end
|
||||
|
||||
local w, h = ScrW(), ScrH()
|
||||
|
||||
local x, y = w * .5, h * .5
|
||||
if wep:GetStat("StencilSight_FollowRecoil", true) then
|
||||
x, y = TFA.LastCrosshairPosX or x, TFA.LastCrosshairPosY or y
|
||||
end
|
||||
|
||||
local TargetColor = wep:GetStat("StencilSight_ReticleTint", color_white)
|
||||
|
||||
if wep:GetStat("StencilSight_ReticleTintBySightColor", false) and IsValid(wep:GetOwner()) then
|
||||
local Owner = wep:GetOwner()
|
||||
|
||||
local _GetNWVector = Owner.GetNW2Vector or Owner.GetNWVector
|
||||
|
||||
local ColorVec = _GetNWVector(Owner, "TFAReticuleColor")
|
||||
|
||||
if ColorVec then
|
||||
TargetColor = Color(ColorVec.x, ColorVec.y, ColorVec.z)
|
||||
end
|
||||
end
|
||||
|
||||
if wep:GetStat("StencilSight_FadeReticleByProgress", false) then
|
||||
TargetColor = ColorAlpha(TargetColor, wep.IronSightsProgress * 255)
|
||||
end
|
||||
|
||||
cam.Start2D(0, 0, w, h)
|
||||
surface.SetMaterial(ReticleMaterial)
|
||||
surface.SetDrawColor(TargetColor)
|
||||
surface.DrawTexturedRect(x - ReticleSize * .5, y - ReticleSize * .5, ReticleSize, ReticleSize)
|
||||
cam.End2D()
|
||||
end
|
||||
end
|
||||
|
||||
do -- Model reticle, for when you don't have an attach point
|
||||
if IsValid(TFA.SightReticleEnt) then
|
||||
TFA.SightReticleEnt:Remove()
|
||||
TFA.SightReticleEnt = nil
|
||||
end
|
||||
|
||||
TFA.SightReticleEnt = ClientsideModel("models/error.mdl", RENDERGROUP_VIEWMODEL)
|
||||
TFA.SightReticleEnt:SetNoDraw(true)
|
||||
|
||||
local SightReticleEnt = TFA.SightReticleEnt
|
||||
|
||||
DrawFunctions[TFA.Enum.RETICLE_MODEL] = function(vm, ply, wep, SightElementTable)
|
||||
if not SightElementTable.reticle then return end
|
||||
|
||||
local SightElementModel = SightElementTable.curmodel
|
||||
|
||||
SightReticleEnt:SetModel(SightElementTable.reticle)
|
||||
if SightReticleEnt:GetModel() == "models/error.mdl" then return end
|
||||
|
||||
local matrix = Matrix()
|
||||
matrix:Scale(SightElementTable.size)
|
||||
SightReticleEnt:EnableMatrix("RenderMultiply", matrix)
|
||||
|
||||
if SightReticleEnt:GetParent() ~= SightElementModel then
|
||||
SightReticleEnt:SetParent(SightElementModel)
|
||||
SightReticleEnt:SetPos(SightElementModel:GetPos())
|
||||
SightReticleEnt:SetAngles(SightElementModel:GetAngles())
|
||||
|
||||
if not SightReticleEnt:IsEffectActive(EF_BONEMERGE) then
|
||||
SightReticleEnt:AddEffects(EF_BONEMERGE)
|
||||
SightReticleEnt:AddEffects(EF_BONEMERGE_FASTCULL)
|
||||
end
|
||||
end
|
||||
|
||||
if wep.ViewModelFlip then render.CullMode(MATERIAL_CULLMODE_CW) end
|
||||
if wep:GetStat("StencilSight_FadeReticleByProgress", false) then
|
||||
local oldBlend = render.GetBlend()
|
||||
|
||||
render.SetBlend(wep.IronSightsProgress)
|
||||
SightReticleEnt:DrawModel()
|
||||
render.SetBlend(oldBlend)
|
||||
else
|
||||
SightReticleEnt:DrawModel()
|
||||
end
|
||||
if wep.ViewModelFlip then render.CullMode(MATERIAL_CULLMODE_CCW) end
|
||||
|
||||
if wep:GetStat("StencilSight_EnableQuad") then
|
||||
DrawFunctions[TFA.Enum.RETICLE_QUAD](vm, ply, wep, SightElementTable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do -- Quad/Attach reticle, TFA INS2 method
|
||||
local function GetTargetPosition(wep, SightElementTable)
|
||||
local TargetEntity = SightElementTable.curmodel
|
||||
if not IsValid(TargetEntity) then return end
|
||||
|
||||
local Type = wep:GetStat("StencilSight_PositionType", TFA.Enum.SIGHTSPOS_ATTACH)
|
||||
|
||||
local pos, ang
|
||||
|
||||
if Type == TFA.Enum.SIGHTSPOS_ATTACH then
|
||||
local AttachmentID = wep:GetStat("StencilSight_ReticleAttachment")
|
||||
if not AttachmentID then return end
|
||||
|
||||
if type(AttachmentID) == "string" then
|
||||
AttachmentID = TargetEntity:LookupAttachment(AttachmentID)
|
||||
end
|
||||
|
||||
if not AttachmentID or AttachmentID <= 0 then return end
|
||||
|
||||
local Attachment = TargetEntity:GetAttachment(AttachmentID)
|
||||
if not Attachment.Pos or not Attachment.Ang then return end
|
||||
|
||||
pos, ang = Attachment.Pos, Attachment.Ang
|
||||
elseif Type == TFA.Enum.SIGHTSPOS_BONE then
|
||||
local BoneID = wep:GetStat("StencilSight_ReticleBone")
|
||||
|
||||
if type(BoneID) == "string" then
|
||||
BoneID = TargetEntity:LookupBone(BoneID)
|
||||
end
|
||||
|
||||
if not BoneID or BoneID < 0 then return end
|
||||
|
||||
pos, ang = TargetEntity:GetBonePosition(BoneID)
|
||||
|
||||
if pos == TargetEntity:GetPos() then
|
||||
pos = TargetEntity:GetBoneMatrix(BoneID):GetTranslation()
|
||||
ang = TargetEntity:GetBoneMatrix(BoneID):GetAngles()
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local OffsetPos = wep:GetStat("StencilSight_ReticleOffsetPos")
|
||||
if OffsetPos then
|
||||
pos = pos + ang:Right() * OffsetPos.x + ang:Forward() * OffsetPos.y + ang:Up() * OffsetPos.z
|
||||
end
|
||||
|
||||
local OffsetAng = wep:GetStat("StencilSight_ReticleOffsetAng")
|
||||
if OffsetAng then
|
||||
ang:RotateAroundAxis(ang:Right(), OffsetAng.p)
|
||||
ang:RotateAroundAxis(ang:Up(), OffsetAng.y)
|
||||
ang:RotateAroundAxis(ang:Forward(), OffsetAng.r)
|
||||
end
|
||||
|
||||
return pos, ang
|
||||
end
|
||||
|
||||
DrawFunctions[TFA.Enum.RETICLE_QUAD] = function(vm, ply, wep, SightElementTable)
|
||||
local ReticleMaterial = wep:GetStat("StencilSight_ReticleMaterial")
|
||||
if not ReticleMaterial then return end
|
||||
|
||||
if type(ReticleMaterial) == "string" then
|
||||
CachedMaterials[ReticleMaterial] = CachedMaterials[ReticleMaterial] or Material(ReticleMaterial, "noclamp nocull smooth")
|
||||
ReticleMaterial = CachedMaterials[ReticleMaterial]
|
||||
end
|
||||
|
||||
local ReticleSize = wep:GetStat("StencilSight_ReticleSize")
|
||||
if not ReticleSize then return end
|
||||
|
||||
if wep:GetStat("StencilSight_ScaleReticleByProgress", false) then
|
||||
ReticleSize = ReticleSize * wep.IronSightsProgress
|
||||
end
|
||||
|
||||
local TargetColor = wep:GetStat("StencilSight_ReticleTint", color_white)
|
||||
|
||||
if wep:GetStat("StencilSight_ReticleTintBySightColor", false) and IsValid(wep:GetOwner()) then
|
||||
local Owner = wep:GetOwner()
|
||||
|
||||
local _GetNWVector = Owner.GetNW2Vector or Owner.GetNWVector
|
||||
|
||||
local ColorVec = _GetNWVector(Owner, "TFAReticuleColor")
|
||||
|
||||
if ColorVec then
|
||||
TargetColor = Color(ColorVec.x, ColorVec.y, ColorVec.z)
|
||||
end
|
||||
end
|
||||
|
||||
if wep:GetStat("StencilSight_FadeReticleByProgress", false) then
|
||||
TargetColor = ColorAlpha(TargetColor, wep.IronSightsProgress * 255)
|
||||
end
|
||||
|
||||
local p, a = GetTargetPosition(wep, SightElementTable)
|
||||
if not p or not a then return end
|
||||
|
||||
render.OverrideDepthEnable(true, true)
|
||||
|
||||
render.SetMaterial(ReticleMaterial)
|
||||
render.DrawQuadEasy(p, a:Forward() * -1, ReticleSize, ReticleSize, TargetColor, 180 + a.r * (wep.ViewModelFlip and 1 or -1))
|
||||
|
||||
render.OverrideDepthEnable(false, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- hook logic
|
||||
if IsValid(TFA.SightMaskEnt) then
|
||||
TFA.SightMaskEnt:Remove()
|
||||
TFA.SightMaskEnt = nil
|
||||
end
|
||||
|
||||
TFA.SightMaskEnt = ClientsideModel("models/error.mdl", RENDERGROUP_VIEWMODEL)
|
||||
TFA.SightMaskEnt:SetNoDraw(true)
|
||||
|
||||
local SightMaskEnt = TFA.SightMaskEnt
|
||||
|
||||
local function DrawSight(vm, ply, wep)
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then return end
|
||||
|
||||
local wep2 = wep:GetTable()
|
||||
|
||||
if wep2.TFA_IsDrawingStencilSights then return end
|
||||
wep2.TFA_IsDrawingStencilSights = true
|
||||
|
||||
if not wep2.GetStat(wep, "StencilSight") then wep2.TFA_IsDrawingStencilSights = false return end
|
||||
if wep2.IronSightsProgress < wep2.GetStat(wep, "StencilSight_MinPercent", 0.05) then wep2.TFA_IsDrawingStencilSights = false return end
|
||||
|
||||
local SightElementName = wep2.GetStat(wep, "StencilSight_VElement")
|
||||
if not SightElementName or not wep2.GetStat(wep, "VElements." .. SightElementName .. ".active") then wep2.TFA_IsDrawingStencilSights = false return end
|
||||
|
||||
local SightElementTable = wep2.VElements[SightElementName]
|
||||
if not SightElementTable then wep2.TFA_IsDrawingStencilSights = false return end
|
||||
|
||||
local SightElementModel = SightElementTable.curmodel
|
||||
if not IsValid(SightElementModel) then wep2.TFA_IsDrawingStencilSights = false return end
|
||||
|
||||
if useStencils then
|
||||
defineCanvas()
|
||||
|
||||
local SightMaskModel = SightElementModel
|
||||
|
||||
if wep2.GetStat(wep, "StencilSight_UseMask", false) and SightElementTable.mask then
|
||||
SightMaskEnt:SetModel(SightElementTable.mask)
|
||||
|
||||
if SightMaskEnt:GetModel() ~= "models/error.mdl" then
|
||||
SightMaskModel = SightMaskEnt
|
||||
|
||||
local matrix = Matrix()
|
||||
matrix:Scale(SightElementTable.size)
|
||||
SightMaskEnt:EnableMatrix("RenderMultiply", matrix)
|
||||
|
||||
if SightMaskEnt:GetParent() ~= SightElementModel then
|
||||
SightMaskEnt:SetParent(SightElementModel)
|
||||
SightMaskEnt:SetPos(SightElementModel:GetPos())
|
||||
SightMaskEnt:SetAngles(SightElementModel:GetAngles())
|
||||
|
||||
if not SightMaskEnt:IsEffectActive(EF_BONEMERGE) then
|
||||
SightMaskEnt:AddEffects(EF_BONEMERGE)
|
||||
SightMaskEnt:AddEffects(EF_BONEMERGE_FASTCULL)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if wep.ViewModelFlip then render.CullMode(MATERIAL_CULLMODE_CW) end
|
||||
local oldBlend = render.GetBlend()
|
||||
render.SetBlend(0)
|
||||
SightMaskModel:DrawModel()
|
||||
render.SetBlend(oldBlend)
|
||||
if wep.ViewModelFlip then render.CullMode(MATERIAL_CULLMODE_CCW) end
|
||||
|
||||
drawOn()
|
||||
end
|
||||
|
||||
local funcType = wep2.GetStat(wep, "StencilSight_ReticleType", TFA.Enum.RETICLE_FLAT)
|
||||
|
||||
if DrawFunctions[funcType] then
|
||||
ProtectedCall(function()
|
||||
DrawFunctions[funcType](vm, ply, wep, SightElementTable)
|
||||
end)
|
||||
end
|
||||
|
||||
if useStencils then
|
||||
stopCanvas()
|
||||
end
|
||||
|
||||
wep2.TFA_IsDrawingStencilSights = false
|
||||
end
|
||||
|
||||
hook.Add("PostDrawViewModel", "TFA_DrawStencilSight", DrawSight)
|
||||
896
lua/tfa/modules/cl_tfa_vgui.lua
Normal file
896
lua/tfa/modules/cl_tfa_vgui.lua
Normal file
@@ -0,0 +1,896 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
--Config GUI
|
||||
|
||||
local function tfaOptionServer(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaOptionSV = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_server"
|
||||
}
|
||||
|
||||
tfaOptionSV.Options["#preset.default"] = {
|
||||
sv_tfa_ironsights_enabled = "1",
|
||||
sv_tfa_sprint_enabled = "1",
|
||||
sv_tfa_weapon_strip = "0",
|
||||
sv_tfa_allow_dryfire = "1",
|
||||
sv_tfa_damage_multiplier = "1",
|
||||
sv_tfa_damage_multiplier_npc = "1",
|
||||
sv_tfa_default_clip = "-1",
|
||||
sv_tfa_arrow_lifetime = "30",
|
||||
sv_tfa_force_multiplier = "1",
|
||||
sv_tfa_bullet_penetration_power_mul = "1",
|
||||
sv_tfa_dynamicaccuracy = "1",
|
||||
sv_tfa_range_modifier = "0.5",
|
||||
sv_tfa_spread_multiplier = "1",
|
||||
sv_tfa_bullet_penetration = "1",
|
||||
sv_tfa_bullet_ricochet = "0",
|
||||
sv_tfa_bullet_doordestruction = "1",
|
||||
sv_tfa_melee_doordestruction = "1",
|
||||
sv_tfa_bullet_randomseed = "0",
|
||||
sv_tfa_reloads_legacy = "0",
|
||||
sv_tfa_fixed_crosshair = "0",
|
||||
sv_tfa_cmenu = "1",
|
||||
sv_tfa_penetration_hardlimit = "100",
|
||||
sv_tfa_jamming = "1",
|
||||
sv_tfa_jamming_mult = "1",
|
||||
sv_tfa_jamming_factor = "1",
|
||||
sv_tfa_jamming_factor_inc = "1",
|
||||
sv_tfa_door_respawn = "-1"
|
||||
}
|
||||
|
||||
tfaOptionSV.CVars = table.GetKeys(tfaOptionSV.Options["#preset.default"])
|
||||
|
||||
panel:AddControl("ComboBox", tfaOptionSV)
|
||||
|
||||
--These are the panel controls. Adding these means that you don't have to go into the console.
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.dryfire", "sv_tfa_allow_dryfire")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.dynaccuracy", "sv_tfa_dynamicaccuracy")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.stripempty", "sv_tfa_weapon_strip")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.ironsight", "sv_tfa_ironsights_enabled")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.sprint", "sv_tfa_sprint_enabled")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.cmenu", "sv_tfa_cmenu")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.penetration", "sv_tfa_bullet_penetration")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.ricochet", "sv_tfa_bullet_ricochet")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.doorbust", "sv_tfa_bullet_doordestruction")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.doorbash", "sv_tfa_melee_doordestruction")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.jamming", "sv_tfa_jamming")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.nearlyempty", "sv_tfa_nearlyempty")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.legacyreloads", "sv_tfa_reloads_legacy")
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.fixedcrosshair", "sv_tfa_fixed_crosshair")
|
||||
|
||||
TFA.CheckBoxNet(panel, "#tfa.svsettings.randomseed", "sv_tfa_bullet_randomseed")
|
||||
panel:Help("#tfa.svsettings.randomseed_tip")
|
||||
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.damagemult", "sv_tfa_damage_multiplier", 0, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.damagemultnpc", "sv_tfa_damage_multiplier_npc", 0, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.doorrespawntime", "sv_tfa_door_respawn", -1, 120, 0)
|
||||
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.jamchance", "sv_tfa_jamming_mult", 0.01, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.jamfactormult", "sv_tfa_jamming_factor", 0.01, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.jamfactorinc", "sv_tfa_jamming_factor_inc", 0.01, 10, 2)
|
||||
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.forcemult", "sv_tfa_force_multiplier", 0, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.penpowermul", "sv_tfa_bullet_penetration_power_mul", 0, 40, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.spreadmult", "sv_tfa_spread_multiplier", 0, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.penetrationlimit", "sv_tfa_penetration_hardlimit", 0, 200)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.defaultclip", "sv_tfa_default_clip", -1, 10, 0)
|
||||
TFA.NumSliderNet(panel, "#tfa.svsettings.rangemod", "sv_tfa_range_modifier", 0, 1, 3)
|
||||
end
|
||||
|
||||
local function tfaOptionSights(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaOptionCL = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_sights"
|
||||
}
|
||||
|
||||
tfaOptionCL.Options["#preset.default"] = {
|
||||
cl_tfa_3dscope = "1",
|
||||
cl_tfa_3dscope_overlay = "1",
|
||||
cl_tfa_3dscope_quality = "0",
|
||||
cl_tfa_fx_rtscopeblur_passes = "3",
|
||||
cl_tfa_fx_rtscopeblur_intensity = "4",
|
||||
cl_tfa_fx_rtscopeblur_mode = "1",
|
||||
cl_tfa_scope_sensitivity_3d = "2",
|
||||
cl_tfa_scope_sensitivity_autoscale = "1",
|
||||
cl_tfa_scope_sensitivity = "100",
|
||||
cl_tfa_ironsights_toggle = "0",
|
||||
cl_tfa_ironsights_resight = "1",
|
||||
cl_tfa_ironsights_responsive = "0",
|
||||
cl_tfa_ironsights_responsive_timer = "0.175",
|
||||
}
|
||||
|
||||
tfaOptionCL.CVars = table.GetKeys(tfaOptionCL.Options["#preset.default"])
|
||||
|
||||
panel:AddControl("ComboBox", tfaOptionCL)
|
||||
|
||||
panel:CheckBox("#tfa.sightsettings.3dscopes", "cl_tfa_3dscope")
|
||||
panel:CheckBox("#tfa.sightsettings.3dscopeshadows", "cl_tfa_3dscope_overlay")
|
||||
|
||||
local tfaOption3DSM = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
Label = "#tfa.sightsettings.3dsm",
|
||||
MenuButton = "0",
|
||||
Folder = "TFA 3D Scope Sens."
|
||||
}
|
||||
|
||||
tfaOption3DSM.Options["#tfa.sightsettings.3dsm.nc"] = {
|
||||
cl_tfa_scope_sensitivity_3d = "0"
|
||||
}
|
||||
|
||||
tfaOption3DSM.Options["#tfa.sightsettings.3dsm.nc"] = {
|
||||
cl_tfa_scope_sensitivity_3d = "0"
|
||||
}
|
||||
|
||||
tfaOption3DSM.Options["#tfa.sightsettings.3dsm.sc"] = {
|
||||
cl_tfa_scope_sensitivity_3d = "1"
|
||||
}
|
||||
|
||||
tfaOption3DSM.Options["#tfa.sightsettings.3dsm.3d"] = {
|
||||
cl_tfa_scope_sensitivity_3d = "2"
|
||||
}
|
||||
|
||||
tfaOption3DSM.Options["#tfa.sightsettings.3dsm.rt"] = {
|
||||
cl_tfa_scope_sensitivity_3d = "3"
|
||||
}
|
||||
|
||||
tfaOption3DSM.CVars = table.GetKeys(tfaOption3DSM.Options["#tfa.sightsettings.3dsm.3d"])
|
||||
panel:AddControl("ComboBox", tfaOption3DSM)
|
||||
|
||||
local tfaOption3DSQ = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
Label = "#tfa.sightsettings.3dsq",
|
||||
MenuButton = "0",
|
||||
Folder = "TFA 3D Scope Sens."
|
||||
}
|
||||
|
||||
tfaOption3DSQ.Options["#tfa.sightsettings.3dsq.ul"] = {
|
||||
cl_tfa_3dscope_quality = "0"
|
||||
}
|
||||
|
||||
tfaOption3DSQ.Options["#tfa.sightsettings.3dsq.hq"] = {
|
||||
cl_tfa_3dscope_quality = "1"
|
||||
}
|
||||
|
||||
tfaOption3DSQ.Options["#tfa.sightsettings.3dsq.mq"] = {
|
||||
cl_tfa_3dscope_quality = "2"
|
||||
}
|
||||
|
||||
tfaOption3DSQ.Options["#tfa.sightsettings.3dsq.lq"] = {
|
||||
cl_tfa_3dscope_quality = "3"
|
||||
}
|
||||
|
||||
tfaOption3DSQ.CVars = table.GetKeys(tfaOption3DSQ.Options["#tfa.sightsettings.3dsq.ul"])
|
||||
panel:AddControl("ComboBox", tfaOption3DSQ)
|
||||
|
||||
local tfaOption3DSB = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
Label = "#tfa.sightsettings.3dsb",
|
||||
MenuButton = "0",
|
||||
Folder = "TFA 3D Scope Blur."
|
||||
}
|
||||
|
||||
tfaOption3DSB.Options["#tfa.sightsettings.3dsb.nb"] = {
|
||||
cl_tfa_fx_rtscopeblur_mode = "0"
|
||||
}
|
||||
|
||||
tfaOption3DSB.Options["#tfa.sightsettings.3dsb.sb"] = {
|
||||
cl_tfa_fx_rtscopeblur_mode = "1"
|
||||
}
|
||||
|
||||
tfaOption3DSB.Options["#tfa.sightsettings.3dsb.bb"] = {
|
||||
cl_tfa_fx_rtscopeblur_mode = "2"
|
||||
}
|
||||
|
||||
tfaOption3DSB.CVars = table.GetKeys(tfaOption3DSB.Options["#tfa.sightsettings.3dsb.bb"])
|
||||
panel:AddControl("ComboBox", tfaOption3DSB)
|
||||
|
||||
panel:NumSlider("#tfa.sightsettings.rtbgblurpasses", "cl_tfa_fx_rtscopeblur_passes", 1, 5, 0)
|
||||
panel:NumSlider("#tfa.sightsettings.rtbgblurintensity", "cl_tfa_fx_rtscopeblur_intensity", 0.01, 10, 2)
|
||||
panel:CheckBox("#tfa.sightsettings.adstoggle", "cl_tfa_ironsights_toggle")
|
||||
panel:CheckBox("#tfa.sightsettings.adsresight", "cl_tfa_ironsights_resight")
|
||||
panel:CheckBox("#tfa.sightsettings.responsive", "cl_tfa_ironsights_responsive")
|
||||
panel:NumSlider("#tfa.sightsettings.responsive_timer", "cl_tfa_ironsights_responsive_timer", 0.01, 2, 4)
|
||||
panel:CheckBox("#tfa.sightsettings.scopesensscale", "cl_tfa_scope_sensitivity_autoscale")
|
||||
panel:NumSlider("#tfa.sightsettings.scopesenspct", "cl_tfa_scope_sensitivity", 0.01, 100, 2)
|
||||
end
|
||||
|
||||
local function tfaOptionVM(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaOptionCL = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_viewmodel"
|
||||
}
|
||||
|
||||
tfaOptionCL.Options["#preset.default"] = {
|
||||
cl_tfa_viewbob_animated = "0",
|
||||
cl_tfa_viewbob_intensity = "1",
|
||||
cl_tfa_gunbob_intensity = "1",
|
||||
cl_tfa_gunbob_custom = "1",
|
||||
cl_tfa_viewmodel_offset_x = "0",
|
||||
cl_tfa_viewmodel_offset_y = "0",
|
||||
cl_tfa_viewmodel_offset_z = "0",
|
||||
cl_tfa_viewmodel_offset_fov = "0",
|
||||
cl_tfa_viewmodel_flip = "0",
|
||||
cl_tfa_viewmodel_centered = "0",
|
||||
cl_tfa_viewmodel_nearwall = "1",
|
||||
cl_tfa_laser_trails = "1"
|
||||
}
|
||||
|
||||
tfaOptionCL.CVars = table.GetKeys(tfaOptionCL.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", tfaOptionCL)
|
||||
|
||||
panel:CheckBox("#tfa.vmsettings.viewbobanim", "cl_tfa_viewbob_animated")
|
||||
panel:NumSlider("#tfa.vmsettings.viewbobmult", "cl_tfa_viewbob_intensity", 0, 2, 2)
|
||||
panel:CheckBox("#tfa.vmsettings.gunbobcustom", "cl_tfa_gunbob_custom")
|
||||
panel:NumSlider("#tfa.vmsettings.gunbobmult", "cl_tfa_gunbob_intensity", 0, 2, 2)
|
||||
|
||||
panel:NumSlider("#tfa.vmsettings.offset.x", "cl_tfa_viewmodel_offset_x", -2, 2, 2)
|
||||
panel:NumSlider("#tfa.vmsettings.offset.y", "cl_tfa_viewmodel_offset_y", -2, 2, 2)
|
||||
panel:NumSlider("#tfa.vmsettings.offset.z", "cl_tfa_viewmodel_offset_z", -2, 2, 2)
|
||||
panel:NumSlider("#tfa.vmsettings.offset.fov", "cl_tfa_viewmodel_offset_fov", -5, 5, 2)
|
||||
|
||||
panel:CheckBox("#tfa.vmsettings.centered", "cl_tfa_viewmodel_centered")
|
||||
panel:CheckBox("#tfa.vmsettings.flip", "cl_tfa_viewmodel_flip")
|
||||
|
||||
panel:CheckBox("#tfa.vmsettings.laserdottrail", "cl_tfa_laser_trails")
|
||||
panel:CheckBox("#tfa.vmsettings.nearwall", "cl_tfa_viewmodel_nearwall")
|
||||
end
|
||||
|
||||
local function tfaOptionPerformance(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaOptionPerf = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_performance"
|
||||
}
|
||||
|
||||
tfaOptionPerf.Options["#preset.default"] = {
|
||||
sv_tfa_fx_penetration_decal = "1",
|
||||
cl_tfa_fx_impact_enabled = "1",
|
||||
cl_tfa_fx_impact_ricochet_enabled = "1",
|
||||
cl_tfa_fx_impact_ricochet_sparks = "20",
|
||||
cl_tfa_fx_impact_ricochet_sparklife = "2",
|
||||
cl_tfa_fx_gasblur = "1",
|
||||
cl_tfa_fx_muzzlesmoke = "1",
|
||||
cl_tfa_fx_muzzlesmoke_limited = "1",
|
||||
cl_tfa_fx_muzzleflashsmoke = "1",
|
||||
cl_tfa_fx_ejectionlife = "15",
|
||||
cl_tfa_legacy_shells = "0",
|
||||
cl_tfa_fx_ads_dof = "0",
|
||||
cl_tfa_fx_ads_dof_hd = "0"
|
||||
}
|
||||
|
||||
tfaOptionPerf.CVars = table.GetKeys(tfaOptionPerf.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", tfaOptionPerf)
|
||||
|
||||
panel:Help("#tfa.settings.client")
|
||||
panel:CheckBox("#tfa.perfsettings.gasblur", "cl_tfa_fx_gasblur")
|
||||
panel:CheckBox("#tfa.perfsettings.mzsmoke", "cl_tfa_fx_muzzleflashsmoke")
|
||||
panel:CheckBox("#tfa.perfsettings.mztrail", "cl_tfa_fx_muzzlesmoke")
|
||||
panel:CheckBox("#tfa.perfsettings.mztrail.limit", "cl_tfa_fx_muzzlesmoke_limited")
|
||||
panel:CheckBox("#tfa.perfsettings.ejsmoke", "cl_tfa_fx_ejectionsmoke")
|
||||
panel:CheckBox("#tfa.perfsettings.impactfx", "cl_tfa_fx_impact_enabled")
|
||||
panel:CheckBox("#tfa.perfsettings.ricochetfx", "cl_tfa_fx_impact_ricochet_enabled")
|
||||
|
||||
panel:CheckBox("#tfa.perfsettings.oldshells", "cl_tfa_legacy_shells")
|
||||
|
||||
panel:CheckBox("#tfa.perfsettings.adsdof", "cl_tfa_fx_ads_dof")
|
||||
panel:CheckBox("#tfa.perfsettings.adsdof.hd", "cl_tfa_fx_ads_dof_hd")
|
||||
|
||||
panel:NumSlider("#tfa.perfsettings.ejlife", "cl_tfa_fx_ejectionlife", 0, 60, 0)
|
||||
|
||||
panel:NumSlider("#tfa.perfsettings.ricochetspark.amount", "cl_tfa_fx_impact_ricochet_sparks", 0, 50, 0)
|
||||
panel:AddControl("Slider", {
|
||||
Label = "Ricochet Spark Amount",
|
||||
Command = "cl_tfa_fx_impact_ricochet_sparks",
|
||||
Type = "Integer",
|
||||
Min = "0",
|
||||
Max = "50"
|
||||
})
|
||||
|
||||
panel:NumSlider("#tfa.perfsettings.ricochetspark.life", "cl_tfa_fx_impact_ricochet_sparklife", 0, 5, 2)
|
||||
|
||||
panel:Help("#tfa.settings.server")
|
||||
TFA.CheckBoxNet(panel, "#tfa.perfsettings.penetrationdecal", "sv_tfa_fx_penetration_decal")
|
||||
end
|
||||
|
||||
local function tfaOptionHUD(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaTBLOptionHUD = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_hud"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#preset.default"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "1",
|
||||
cl_tfa_hud_crosshair_color_r = "225",
|
||||
cl_tfa_hud_crosshair_color_g = "225",
|
||||
cl_tfa_hud_crosshair_color_b = "225",
|
||||
cl_tfa_hud_crosshair_color_a = "225",
|
||||
cl_tfa_hud_crosshair_color_team = "1",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "225",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.2",
|
||||
cl_tfa_hud_hangtime = "1",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "0",
|
||||
cl_tfa_hud_crosshair_length = "1",
|
||||
cl_tfa_hud_crosshair_width = "1",
|
||||
cl_tfa_hud_crosshair_gap_scale = "1",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "1",
|
||||
cl_tfa_hud_crosshair_outline_width = "1",
|
||||
cl_tfa_hud_crosshair_dot = "0",
|
||||
cl_tfa_hud_crosshair_triangular = "0",
|
||||
cl_tfa_hud_crosshair_pump = "0",
|
||||
cl_tfa_hud_hitmarker_enabled = "1",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "1",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1",
|
||||
cl_tfa_hud_hitmarker_color_r = "225",
|
||||
cl_tfa_hud_hitmarker_color_g = "225",
|
||||
cl_tfa_hud_hitmarker_color_b = "225",
|
||||
cl_tfa_hud_hitmarker_color_a = "225",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#tfa.hudpreset.cross"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "1",
|
||||
cl_tfa_hud_crosshair_color_r = "255",
|
||||
cl_tfa_hud_crosshair_color_g = "255",
|
||||
cl_tfa_hud_crosshair_color_b = "255",
|
||||
cl_tfa_hud_crosshair_color_a = "200",
|
||||
cl_tfa_hud_crosshair_color_team = "1",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "154",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "152",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "175",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "255",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.2",
|
||||
cl_tfa_hud_hangtime = "1",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "0",
|
||||
cl_tfa_hud_crosshair_length = "0.75",
|
||||
cl_tfa_hud_crosshair_width = "1",
|
||||
cl_tfa_hud_crosshair_gap_scale = "0",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "1",
|
||||
cl_tfa_hud_crosshair_outline_width = "1",
|
||||
cl_tfa_hud_crosshair_dot = "0",
|
||||
cl_tfa_hud_crosshair_triangular = "0",
|
||||
cl_tfa_hud_crosshair_pump = "0",
|
||||
cl_tfa_hud_hitmarker_enabled = "1",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "1",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1",
|
||||
cl_tfa_hud_hitmarker_color_r = "225",
|
||||
cl_tfa_hud_hitmarker_color_g = "225",
|
||||
cl_tfa_hud_hitmarker_color_b = "225",
|
||||
cl_tfa_hud_hitmarker_color_a = "225",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#tfa.hudpreset.dot"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "1",
|
||||
cl_tfa_hud_crosshair_color_r = "72",
|
||||
cl_tfa_hud_crosshair_color_g = "72",
|
||||
cl_tfa_hud_crosshair_color_b = "72",
|
||||
cl_tfa_hud_crosshair_color_a = "85",
|
||||
cl_tfa_hud_crosshair_color_team = "1",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "225",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "225",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "225",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "85",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.1",
|
||||
cl_tfa_hud_hangtime = "0.5",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "0",
|
||||
cl_tfa_hud_crosshair_length = "0",
|
||||
cl_tfa_hud_crosshair_width = "1",
|
||||
cl_tfa_hud_crosshair_gap_scale = "0",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "1",
|
||||
cl_tfa_hud_crosshair_outline_width = "1",
|
||||
cl_tfa_hud_crosshair_dot = "0",
|
||||
cl_tfa_hud_crosshair_triangular = "0",
|
||||
cl_tfa_hud_crosshair_pump = "0",
|
||||
cl_tfa_hud_hitmarker_enabled = "0",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "0",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1",
|
||||
cl_tfa_hud_hitmarker_color_r = "225",
|
||||
cl_tfa_hud_hitmarker_color_g = "225",
|
||||
cl_tfa_hud_hitmarker_color_b = "225",
|
||||
cl_tfa_hud_hitmarker_color_a = "225",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#tfa.hudpreset.rockstar"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "1",
|
||||
cl_tfa_hud_crosshair_color_r = "225",
|
||||
cl_tfa_hud_crosshair_color_g = "225",
|
||||
cl_tfa_hud_crosshair_color_b = "225",
|
||||
cl_tfa_hud_crosshair_color_a = "85",
|
||||
cl_tfa_hud_crosshair_color_team = "1",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "30",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "30",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "30",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "85",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.1",
|
||||
cl_tfa_hud_hangtime = "0.5",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "0",
|
||||
cl_tfa_hud_crosshair_length = "0",
|
||||
cl_tfa_hud_crosshair_width = "2",
|
||||
cl_tfa_hud_crosshair_gap_scale = "0",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "1",
|
||||
cl_tfa_hud_crosshair_outline_width = "1",
|
||||
cl_tfa_hud_crosshair_dot = "0",
|
||||
cl_tfa_hud_crosshair_triangular = "0",
|
||||
cl_tfa_hud_crosshair_pump = "0",
|
||||
cl_tfa_hud_hitmarker_enabled = "1",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "0",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1",
|
||||
cl_tfa_hud_hitmarker_color_r = "225",
|
||||
cl_tfa_hud_hitmarker_color_g = "225",
|
||||
cl_tfa_hud_hitmarker_color_b = "225",
|
||||
cl_tfa_hud_hitmarker_color_a = "8",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#tfa.hudpreset.hl2"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "0",
|
||||
cl_tfa_hud_crosshair_color_r = "255",
|
||||
cl_tfa_hud_crosshair_color_g = "255",
|
||||
cl_tfa_hud_crosshair_color_b = "255",
|
||||
cl_tfa_hud_crosshair_color_a = "225",
|
||||
cl_tfa_hud_crosshair_color_team = "1",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "0",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.01",
|
||||
cl_tfa_hud_hangtime = "0",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "1",
|
||||
cl_tfa_hud_crosshair_length = "0.5",
|
||||
cl_tfa_hud_crosshair_width = "1",
|
||||
cl_tfa_hud_crosshair_gap_scale = "1",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "0",
|
||||
cl_tfa_hud_crosshair_outline_width = "0",
|
||||
cl_tfa_hud_crosshair_dot = "1",
|
||||
cl_tfa_hud_crosshair_triangular = "0",
|
||||
cl_tfa_hud_crosshair_pump = "0",
|
||||
cl_tfa_hud_hitmarker_enabled = "0",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "0",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1",
|
||||
cl_tfa_hud_hitmarker_color_r = "225",
|
||||
cl_tfa_hud_hitmarker_color_g = "225",
|
||||
cl_tfa_hud_hitmarker_color_b = "225",
|
||||
cl_tfa_hud_hitmarker_color_a = "225",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#tfa.hudpreset.hl2plus"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "1",
|
||||
cl_tfa_hud_crosshair_color_r = "255",
|
||||
cl_tfa_hud_crosshair_color_g = "255",
|
||||
cl_tfa_hud_crosshair_color_b = "255",
|
||||
cl_tfa_hud_crosshair_color_a = "225",
|
||||
cl_tfa_hud_crosshair_color_team = "1",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "5",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "0",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.2",
|
||||
cl_tfa_hud_hangtime = "1",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "1",
|
||||
cl_tfa_hud_crosshair_length = "0.5",
|
||||
cl_tfa_hud_crosshair_width = "1",
|
||||
cl_tfa_hud_crosshair_gap_scale = "1",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "0",
|
||||
cl_tfa_hud_crosshair_outline_width = "0",
|
||||
cl_tfa_hud_crosshair_dot = "1",
|
||||
cl_tfa_hud_crosshair_triangular = "0",
|
||||
cl_tfa_hud_crosshair_pump = "0",
|
||||
cl_tfa_hud_hitmarker_enabled = "1",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "1",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1",
|
||||
cl_tfa_hud_hitmarker_color_r = "225",
|
||||
cl_tfa_hud_hitmarker_color_g = "225",
|
||||
cl_tfa_hud_hitmarker_color_b = "225",
|
||||
cl_tfa_hud_hitmarker_color_a = "225",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.Options["#tfa.hudpreset.crysis2"] = {
|
||||
cl_tfa_hud_crosshair_enable_custom = "1",
|
||||
cl_tfa_hud_crosshair_color_r = "231",
|
||||
cl_tfa_hud_crosshair_color_g = "255",
|
||||
cl_tfa_hud_crosshair_color_b = "255",
|
||||
cl_tfa_hud_crosshair_color_a = "255",
|
||||
cl_tfa_hud_crosshair_color_team = "0",
|
||||
cl_tfa_hud_crosshair_outline_color_r = "0",
|
||||
cl_tfa_hud_crosshair_outline_color_g = "0",
|
||||
cl_tfa_hud_crosshair_outline_color_b = "0",
|
||||
cl_tfa_hud_crosshair_outline_color_a = "0",
|
||||
cl_tfa_hud_enabled = "1",
|
||||
cl_tfa_hud_ammodata_fadein = "0.2",
|
||||
cl_tfa_hud_hangtime = "1",
|
||||
cl_tfa_hud_crosshair_length_use_pixels = "0",
|
||||
cl_tfa_hud_crosshair_length = "1",
|
||||
cl_tfa_hud_crosshair_width = "2",
|
||||
cl_tfa_hud_crosshair_gap_scale = "1",
|
||||
cl_tfa_hud_crosshair_outline_enabled = "0",
|
||||
cl_tfa_hud_crosshair_outline_width = "0",
|
||||
cl_tfa_hud_crosshair_dot = "0",
|
||||
cl_tfa_hud_crosshair_triangular = "1",
|
||||
cl_tfa_hud_crosshair_pump = "1",
|
||||
cl_tfa_hud_hitmarker_enabled = "1",
|
||||
cl_tfa_hud_hitmarker_3d_all = "0",
|
||||
cl_tfa_hud_hitmarker_3d_shotguns = "1",
|
||||
cl_tfa_hud_hitmarker_solidtime = "0.1",
|
||||
cl_tfa_hud_hitmarker_fadetime = "0.3",
|
||||
cl_tfa_hud_hitmarker_scale = "1.5",
|
||||
cl_tfa_hud_hitmarker_color_r = "231",
|
||||
cl_tfa_hud_hitmarker_color_g = "255",
|
||||
cl_tfa_hud_hitmarker_color_b = "255",
|
||||
cl_tfa_hud_hitmarker_color_a = "255",
|
||||
cl_tfa_hud_scale = "1"
|
||||
}
|
||||
|
||||
tfaTBLOptionHUD.CVars = table.GetKeys(tfaTBLOptionHUD.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", tfaTBLOptionHUD)
|
||||
|
||||
panel:CheckBox("#tfa.hudsettings.enabled", "cl_tfa_hud_enabled")
|
||||
panel:NumSlider("#tfa.hudsettings.fadein", "cl_tfa_hud_ammodata_fadein", 0.01, 1, 2)
|
||||
panel:NumSlider("#tfa.hudsettings.hangtime", "cl_tfa_hud_hangtime", 0, 5, 2)
|
||||
panel:NumSlider("#tfa.hudsettings.scalemul", "cl_tfa_hud_scale", 0.25, 4, 3)
|
||||
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.enabled", "cl_tfa_hud_crosshair_enable_custom")
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.dot", "cl_tfa_hud_crosshair_dot")
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.triangular", "cl_tfa_hud_crosshair_triangular")
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.pump", "cl_tfa_hud_crosshair_pump")
|
||||
panel:NumSlider("#tfa.hudsettings.crosshair.length", "cl_tfa_hud_crosshair_length", 0, 10, 2)
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.length.usepixels", "cl_tfa_hud_crosshair_length_use_pixels")
|
||||
panel:NumSlider("#tfa.hudsettings.crosshair.gapscale", "cl_tfa_hud_crosshair_gap_scale", 0, 2, 2)
|
||||
panel:NumSlider("#tfa.hudsettings.crosshair.width", "cl_tfa_hud_crosshair_width", 0, 3, 0)
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.teamcolor", "cl_tfa_hud_crosshair_color_team")
|
||||
panel:AddControl("Color", {
|
||||
Label = "#tfa.hudsettings.crosshair.color",
|
||||
Red = "cl_tfa_hud_crosshair_color_r",
|
||||
Green = "cl_tfa_hud_crosshair_color_g",
|
||||
Blue = "cl_tfa_hud_crosshair_color_b",
|
||||
Alpha = "cl_tfa_hud_crosshair_color_a",
|
||||
ShowHSV = 1,
|
||||
ShowRGB = 1,
|
||||
Multiplier = 255
|
||||
})
|
||||
|
||||
panel:CheckBox("#tfa.hudsettings.crosshair.outline.enabled", "cl_tfa_hud_crosshair_outline_enabled")
|
||||
panel:NumSlider("#tfa.hudsettings.crosshair.outline.width", "cl_tfa_hud_crosshair_outline_width", 0, 3, 0)
|
||||
panel:AddControl("Color", {
|
||||
Label = "#tfa.hudsettings.crosshair.outline.color",
|
||||
Red = "cl_tfa_hud_crosshair_outline_color_r",
|
||||
Green = "cl_tfa_hud_crosshair_outline_color_g",
|
||||
Blue = "cl_tfa_hud_crosshair_outline_color_b",
|
||||
Alpha = "cl_tfa_hud_crosshair_outline_color_a",
|
||||
ShowHSV = 1,
|
||||
ShowRGB = 1,
|
||||
Multiplier = 255
|
||||
})
|
||||
|
||||
panel:CheckBox("#tfa.hudsettings.hitmarker.enabled", "cl_tfa_hud_hitmarker_enabled")
|
||||
panel:CheckBox("#tfa.hudsettings.hitmarker.3d.shotguns", "cl_tfa_hud_hitmarker_3d_shotguns")
|
||||
panel:CheckBox("#tfa.hudsettings.hitmarker.3d.all", "cl_tfa_hud_hitmarker_3d_all")
|
||||
panel:NumSlider("#tfa.hudsettings.hitmarker.solidtime", "cl_tfa_hud_hitmarker_solidtime", 0, 1, 2)
|
||||
panel:NumSlider("#tfa.hudsettings.hitmarker.fadetime", "cl_tfa_hud_hitmarker_fadetime", 0, 1, 2)
|
||||
panel:NumSlider("#tfa.hudsettings.hitmarker.scale", "cl_tfa_hud_hitmarker_scale", 0, 5, 2)
|
||||
panel:AddControl("Color", {
|
||||
Label = "#tfa.hudsettings.hitmarker.color",
|
||||
Red = "cl_tfa_hud_hitmarker_color_r",
|
||||
Green = "cl_tfa_hud_hitmarker_color_g",
|
||||
Blue = "cl_tfa_hud_hitmarker_color_b",
|
||||
Alpha = "cl_tfa_hud_hitmarker_color_a",
|
||||
ShowHSV = 1,
|
||||
ShowRGB = 1,
|
||||
Multiplier = 255
|
||||
})
|
||||
end
|
||||
|
||||
local function tfaOptionDeveloper(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaOptionPerf = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_debug"
|
||||
}
|
||||
|
||||
tfaOptionPerf.Options["#preset.default"] = {
|
||||
["cl_tfa_debug_crosshair"] = 0,
|
||||
["cl_tfa_debug_animations"] = 0,
|
||||
["cl_tfa_debug_rt"] = 0,
|
||||
["cl_tfa_debug_cache"] = 0
|
||||
}
|
||||
|
||||
tfaOptionPerf.CVars = table.GetKeys(tfaOptionPerf.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", tfaOptionPerf)
|
||||
|
||||
panel:Help("#tfa.devsettings.adminonly")
|
||||
|
||||
panel:CheckBox("#tfa.devsettings.debug.crosshair", "cl_tfa_debug_crosshair")
|
||||
panel:CheckBox("#tfa.devsettings.debug.animations", "cl_tfa_debug_animations")
|
||||
panel:CheckBox("#tfa.devsettings.debug.rtshadow", "cl_tfa_debug_rt")
|
||||
panel:CheckBox("#tfa.devsettings.debug.cache", "cl_tfa_debug_cache")
|
||||
end
|
||||
|
||||
local function tfaOptionColors(panel)
|
||||
local tfaOptionCO = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_colors"
|
||||
}
|
||||
|
||||
tfaOptionCO.Options["#preset.default"] = {
|
||||
cl_tfa_laser_color_r = "255",
|
||||
cl_tfa_laser_color_g = "0",
|
||||
cl_tfa_laser_color_b = "0",
|
||||
cl_tfa_reticule_color_r = "255",
|
||||
cl_tfa_reticule_color_g = "100",
|
||||
cl_tfa_reticule_color_b = "0"
|
||||
}
|
||||
|
||||
tfaOptionCO.CVars = table.GetKeys(tfaOptionCO.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", tfaOptionCO)
|
||||
|
||||
panel:AddControl("Color", {
|
||||
Label = "#tfa.colorsettings.laser",
|
||||
Red = "cl_tfa_laser_color_r",
|
||||
Green = "cl_tfa_laser_color_g",
|
||||
Blue = "cl_tfa_laser_color_b",
|
||||
ShowHSV = 1,
|
||||
ShowRGB = 1,
|
||||
Multiplier = 255
|
||||
})
|
||||
|
||||
panel:AddControl("Color", {
|
||||
Label = "#tfa.colorsettings.reticule",
|
||||
Red = "cl_tfa_reticule_color_r",
|
||||
Green = "cl_tfa_reticule_color_g",
|
||||
Blue = "cl_tfa_reticule_color_b",
|
||||
ShowHSV = 1,
|
||||
ShowRGB = 1,
|
||||
Multiplier = 255
|
||||
})
|
||||
end
|
||||
|
||||
local function tfaOptionBallistics(panel)
|
||||
--Here are whatever default categories you want.
|
||||
local tfaOptionPerf = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_ballistics"
|
||||
}
|
||||
|
||||
tfaOptionPerf.Options["#preset.default"] = {
|
||||
["sv_tfa_ballistics_enabled"] = nil,
|
||||
["sv_tfa_ballistics_mindist"] = -1,
|
||||
["sv_tfa_ballistics_bullet_life"] = 10,
|
||||
["sv_tfa_ballistics_bullet_damping_air"] = 1,
|
||||
["sv_tfa_ballistics_bullet_damping_water"] = 3,
|
||||
["sv_tfa_ballistics_bullet_velocity"] = 1,
|
||||
["sv_tfa_ballistics_bullet_substeps"] = 3,
|
||||
["sv_tfa_ballistics_custom_gravity"] = 0,
|
||||
["sv_tfa_ballistics_custom_gravity_value"] = 0,
|
||||
["cl_tfa_ballistics_mp"] = 1,
|
||||
["cl_tfa_ballistics_fx_bullet"] = 1,
|
||||
["cl_tfa_ballistics_fx_tracers_style"] = 1,
|
||||
["cl_tfa_ballistics_fx_tracers_mp"] = 1,
|
||||
["cl_tfa_ballistics_fx_tracers_adv"] = 1
|
||||
}
|
||||
|
||||
tfaOptionPerf.CVars = table.GetKeys(tfaOptionPerf.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", tfaOptionPerf)
|
||||
|
||||
panel:Help("#tfa.settings.server")
|
||||
TFA.CheckBoxNet(panel, "#tfa.ballisticsettings.enabled", "sv_tfa_ballistics_enabled")
|
||||
TFA.NumSliderNet(panel, "#tfa.ballisticsettings.mindist", "sv_tfa_ballistics_mindist", -1, 100, 0)
|
||||
TFA.NumSliderNet(panel, "#tfa.ballisticsettings.bullet.life", "sv_tfa_ballistics_bullet_life", 0, 20, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.ballisticsettings.bullet.damping.air", "sv_tfa_ballistics_bullet_damping_air", 0, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.ballisticsettings.bullet.damping.water", "sv_tfa_ballistics_bullet_damping_water", 0, 10, 2)
|
||||
TFA.NumSliderNet(panel, "#tfa.ballisticsettings.bullet.velocity", "sv_tfa_ballistics_bullet_velocity", 0, 2, 3)
|
||||
TFA.NumSliderNet(panel, "#tfa.ballisticsettings.substeps", "sv_tfa_ballistics_substeps", 1, 5, 0)
|
||||
TFA.CheckBoxNet(panel, "#tfa.ballisticsettings.customgravity", "sv_tfa_ballistics_custom_gravity")
|
||||
TFA.CheckBoxNet(panel, "#tfa.ballisticsettings.customgravityvalue", "sv_tfa_ballistics_custom_gravity_value")
|
||||
|
||||
panel:Help("#tfa.settings.client")
|
||||
|
||||
panel:CheckBox("#tfa.ballisticsettings.fx.bullet", "cl_tfa_ballistics_fx_bullet")
|
||||
panel:CheckBox("#tfa.ballisticsettings.fx.hq", "cl_tfa_ballistics_fx_tracers_adv")
|
||||
panel:CheckBox("#tfa.ballisticsettings.fx.mp", "cl_tfa_ballistics_mp")
|
||||
panel:CheckBox("#tfa.ballisticsettings.fx.mptracer", "cl_tfa_ballistics_fx_tracers_mp")
|
||||
|
||||
local tfaOptionTracerStyle = {
|
||||
Options = {},
|
||||
CVars = {"cl_tfa_ballistics_fx_tracers_style"},
|
||||
Label = "#tfa.ballisticsettings.tracer",
|
||||
MenuButton = "1",
|
||||
Folder = "TFASSBallTracerStyle"
|
||||
}
|
||||
|
||||
tfaOptionTracerStyle.Options["#tfa.ballisticsettings.tracer.di"] = {
|
||||
["cl_tfa_ballistics_fx_tracers_style"] = 0
|
||||
}
|
||||
|
||||
tfaOptionTracerStyle.Options["#tfa.ballisticsettings.tracer.sm"] = {
|
||||
["cl_tfa_ballistics_fx_tracers_style"] = 1
|
||||
}
|
||||
|
||||
tfaOptionTracerStyle.Options["#tfa.ballisticsettings.tracer.re"] = {
|
||||
["cl_tfa_ballistics_fx_tracers_style"] = 2
|
||||
}
|
||||
|
||||
panel:AddControl("ComboBox", tfaOptionTracerStyle)
|
||||
end
|
||||
|
||||
local function tfaOptionAbout(panel)
|
||||
panel:Help("TFA Base [Reduxed]")
|
||||
panel:Help(language.GetPhrase("tfa.about.version"):format(TFA_BASE_VERSION))
|
||||
panel:Help(language.GetPhrase("tfa.about.author"):format("TheForgottenArchitect"))
|
||||
panel:Help(language.GetPhrase("tfa.about.maintain"):format("YuRaNnNzZZ", "DBotThePony"))
|
||||
|
||||
panel:Help("")
|
||||
|
||||
panel:Help("#tfa.about.changelog.label")
|
||||
local btnGitLabChangelog = panel:Button("#tfa.about.changelog.btn.gitlab")
|
||||
btnGitLabChangelog.DoClick = function()
|
||||
gui.OpenURL("https://gitlab.com/tfa-devs/tfa-base/-/blob/master/CHANGELOG.md")
|
||||
end
|
||||
local btnSteamChangeNotes = panel:Button("#tfa.about.changelog.btn.steam")
|
||||
btnSteamChangeNotes.DoClick = function()
|
||||
gui.OpenURL("https://steamcommunity.com/sharedfiles/filedetails/changelog/415143062")
|
||||
end
|
||||
|
||||
panel:Help("")
|
||||
|
||||
panel:Help("#tfa.about.help.label")
|
||||
local btnGitLabIssues = panel:Button("#tfa.about.help.btn.gitlab")
|
||||
btnGitLabIssues.DoClick = function()
|
||||
gui.OpenURL("https://gitlab.com/tfa-devs/tfa-base/-/issues")
|
||||
end
|
||||
local btnDiscordHelp = panel:Button("#tfa.about.help.btn.discord")
|
||||
btnDiscordHelp.DoClick = function()
|
||||
gui.OpenURL("https://discord.gg/U38pBcP")
|
||||
end
|
||||
local btnSteamGroupBugReport = panel:Button("#tfa.about.help.btn.steam")
|
||||
btnSteamGroupBugReport.DoClick = function()
|
||||
gui.OpenURL("https://steamcommunity.com/groups/tfa-mods/discussions/2/")
|
||||
end
|
||||
|
||||
panel:Help("")
|
||||
|
||||
panel:Help("#tfa.about.chat.label")
|
||||
local btnChatSteam = panel:Button("#tfa.about.chat.btn.steam")
|
||||
btnChatSteam.DoClick = function()
|
||||
gui.OpenURL("https://steamcommunity.com/groups/tfa-mods")
|
||||
end
|
||||
local btnChatDiscord = panel:Button("#tfa.about.chat.btn.discord")
|
||||
btnChatDiscord.DoClick = function()
|
||||
gui.OpenURL("https://discord.gg/Gxqx67n")
|
||||
end
|
||||
|
||||
panel:Help("")
|
||||
|
||||
panel:Help("#tfa.about.contrib.label")
|
||||
local btnGitLab = panel:Button("#tfa.about.contrib.btn.gitlab")
|
||||
btnGitLab.DoClick = function()
|
||||
gui.OpenURL("https://gitlab.com/tfa-devs/tfa-base")
|
||||
end
|
||||
end
|
||||
|
||||
local function tfaOptionInspect(panel)
|
||||
local presetTable = {
|
||||
Options = {},
|
||||
CVars = {},
|
||||
MenuButton = "1",
|
||||
Folder = "tfa_base_inspect"
|
||||
}
|
||||
|
||||
presetTable.Options["#preset.default"] = {
|
||||
cl_tfa_inspection_bokeh = "0",
|
||||
cl_tfa_inspection_bokeh_radius = "0.1",
|
||||
cl_tfa_inspect_hide = "0",
|
||||
cl_tfa_inspect_hide_hud = "0",
|
||||
cl_tfa_inspect_hide_in_screenshots = "0",
|
||||
cl_tfa_inspect_newbars = "0",
|
||||
cl_tfa_inspect_spreadinmoa = "0"
|
||||
}
|
||||
|
||||
presetTable.CVars = table.GetKeys(presetTable.Options["#preset.default"])
|
||||
panel:AddControl("ComboBox", presetTable)
|
||||
|
||||
panel:CheckBox("#tfa.inspectsettings.inspectdof.enabled", "cl_tfa_inspection_bokeh")
|
||||
panel:NumSlider("#tfa.inspectsettings.inspectdof.radius", "cl_tfa_inspection_bokeh_radius", 0.01, 1, 3)
|
||||
|
||||
panel:CheckBox("#tfa.inspectsettings.hide", "cl_tfa_inspect_hide")
|
||||
if DLib then
|
||||
panel:CheckBox("#tfa.inspectsettings.hidehud", "cl_tfa_inspect_hide_hud")
|
||||
end
|
||||
panel:CheckBox("#tfa.inspectsettings.hideinscreenshots", "cl_tfa_inspect_hide_in_screenshots")
|
||||
panel:CheckBox("#tfa.inspectsettings.newbars", "cl_tfa_inspect_newbars")
|
||||
panel:CheckBox("#tfa.inspectsettings.spreadinmoa", "cl_tfa_inspect_spreadinmoa")
|
||||
end
|
||||
|
||||
local function tfaAddOption()
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "tfaOptionVM", "#tfa.smsettings.viewmodel", "", "", tfaOptionVM)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "tfaOptionSights", "#tfa.smsettings.sights", "", "", tfaOptionSights)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "tfaOptionPerformance", "#tfa.smsettings.perf", "", "", tfaOptionPerformance)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseCrosshair", "#tfa.smsettings.hud", "", "", tfaOptionHUD)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseDeveloper", "#tfa.smsettings.dev", "", "", tfaOptionDeveloper)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseColor", "#tfa.smsettings.color", "", "", tfaOptionColors)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseBallistics", "#tfa.smsettings.ballistics", "", "", tfaOptionBallistics)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseServer", "#tfa.smsettings.server", "", "", tfaOptionServer)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseAbout", "#tfa.smsettings.about", "", "", tfaOptionAbout)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseInspect", "#tfa.smsettings.inspect", "", "", tfaOptionInspect)
|
||||
end
|
||||
|
||||
hook.Add("PopulateToolMenu", "tfaAddOption", tfaAddOption)
|
||||
271
lua/tfa/modules/cl_tfa_vm_blur.lua
Normal file
271
lua/tfa/modules/cl_tfa_vm_blur.lua
Normal file
@@ -0,0 +1,271 @@
|
||||
--[[
|
||||
| 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 supports
|
||||
local cl_tfa_fx_dof, cl_tfa_fx_dof_hd
|
||||
local fmat = CreateMaterial("TFA_DOF_Material4", "Refract", {
|
||||
["$model"] = "1",
|
||||
["$alpha"] = "1",
|
||||
["$alphatest"] = "1",
|
||||
["$normalmap"] = "effects/flat_normal",
|
||||
["$refractamount"] = "0.1",
|
||||
["$vertexalpha"] = "1",
|
||||
["$vertexcolor"] = "1",
|
||||
["$translucent"] = "1",
|
||||
["$forcerefract"] = "0",
|
||||
["$bluramount"] = "1.5",
|
||||
["$nofog"] = "1"
|
||||
})
|
||||
|
||||
local fmat2 = CreateMaterial("TFA_DOF_Material5", "Refract", {
|
||||
["$model"] = "1",
|
||||
["$alpha"] = "1",
|
||||
["$alphatest"] = "1",
|
||||
["$normalmap"] = "effects/flat_normal",
|
||||
["$refractamount"] = "0.1",
|
||||
["$vertexalpha"] = "1",
|
||||
["$vertexcolor"] = "1",
|
||||
["$translucent"] = "1",
|
||||
["$forcerefract"] = "0",
|
||||
["$bluramount"] = "0.9",
|
||||
["$nofog"] = "1"
|
||||
})
|
||||
|
||||
local fmat3 = CreateMaterial("TFA_DOF_Material16", "Refract", {
|
||||
["$model"] = "1",
|
||||
["$alpha"] = "1",
|
||||
["$alphatest"] = "1",
|
||||
["$normalmap"] = "effects/flat_normal",
|
||||
["$refractamount"] = "0.1",
|
||||
["$vertexalpha"] = "1",
|
||||
["$vertexcolor"] = "1",
|
||||
["$translucent"] = "1",
|
||||
["$forcerefract"] = "0",
|
||||
["$bluramount"] = "0.8",
|
||||
["$nofog"] = "1"
|
||||
})
|
||||
|
||||
local white = CreateMaterial("TFA_DOF_White", "UnlitGeneric", {
|
||||
["$alpha"] = "0",
|
||||
["$basetexture"] = "models/debug/debugwhite"
|
||||
})
|
||||
|
||||
TFA.LastRTUpdate = TFA.LastRTUpdate or UnPredictedCurTime()
|
||||
|
||||
hook.Add("PreDrawViewModel", "TFA_DrawViewModel", function(vm, plyv, wep)
|
||||
if not vm or not plyv or not wep then return end
|
||||
if not wep.IsTFAWeapon then return end
|
||||
|
||||
if supports == nil then
|
||||
supports = render.SupportsPixelShaders_1_4() and render.SupportsPixelShaders_2_0() and render.SupportsVertexShaders_2_0()
|
||||
|
||||
if not supports then
|
||||
print("[TFA] Your videocard does not support pixel shaders! DoF of Iron Sights is disabled!")
|
||||
end
|
||||
end
|
||||
|
||||
if not supports then return end
|
||||
|
||||
if not cl_tfa_fx_dof then
|
||||
cl_tfa_fx_dof = GetConVar("cl_tfa_fx_ads_dof")
|
||||
end
|
||||
|
||||
if not cl_tfa_fx_dof or not cl_tfa_fx_dof:GetBool() then return end
|
||||
if not wep.AllowIronSightsDoF then return end
|
||||
local aimingDown = wep:GetIronSightsProgress() > 0.4
|
||||
local scoped = TFA.LastRTUpdate > UnPredictedCurTime() or wep:GetStatL("Scoped")
|
||||
|
||||
if aimingDown and not scoped then
|
||||
if hook.Run("TFA_AllowDoFDraw", wep, plyv, vm) == false then return end
|
||||
wep.__TFA_AimDoFFrame = FrameNumber()
|
||||
render.ClearStencil()
|
||||
render.SetStencilEnable(true)
|
||||
render.SetStencilTestMask(0)
|
||||
render.SetStencilWriteMask(1)
|
||||
render.SetStencilReferenceValue(1)
|
||||
render.SetStencilCompareFunction(STENCIL_ALWAYS)
|
||||
render.OverrideColorWriteEnable(true, true)
|
||||
render.SetStencilZFailOperation(STENCIL_KEEP)
|
||||
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||
render.SetStencilFailOperation(STENCIL_KEEP)
|
||||
end
|
||||
end)
|
||||
|
||||
local transparent = Color(0, 0, 0, 0)
|
||||
local color_white = Color(255, 255, 255)
|
||||
local STOP = false
|
||||
|
||||
local function DrawDOF(muzzledata,fwd2)
|
||||
local w, h = ScrW(), ScrH()
|
||||
render.SetMaterial(fmat)
|
||||
cam.Start2D()
|
||||
surface.SetDrawColor(255, 255, 255)
|
||||
surface.SetMaterial(fmat)
|
||||
surface.DrawTexturedRect(0, 0, w, h)
|
||||
cam.End2D()
|
||||
|
||||
if muzzledata then
|
||||
-- :POG:
|
||||
render.SetMaterial(fmat2)
|
||||
|
||||
for i = 28, 2, -1 do
|
||||
render.UpdateScreenEffectTexture()
|
||||
render.DrawSprite(muzzledata.Pos - fwd2 * i * 3, 200, 200, color_white)
|
||||
end
|
||||
end
|
||||
|
||||
render.SetMaterial(fmat3)
|
||||
cam.Start2D()
|
||||
surface.SetMaterial(fmat3)
|
||||
|
||||
for i = 0, 32 do
|
||||
render.UpdateScreenEffectTexture()
|
||||
surface.DrawTexturedRect(0, h / 1.6 + h / 2 * i / 32, w, h / 2)
|
||||
end
|
||||
|
||||
cam.End2D()
|
||||
end
|
||||
|
||||
hook.Add("PostDrawViewModel", "TFA_DrawViewModel", function(vm, plyv, wep)
|
||||
if not wep.IsTFAWeapon then return end
|
||||
|
||||
if not supports then
|
||||
wep:ViewModelDrawnPost()
|
||||
return
|
||||
end
|
||||
|
||||
if not cl_tfa_fx_dof then
|
||||
cl_tfa_fx_dof = GetConVar("cl_tfa_fx_ads_dof")
|
||||
end
|
||||
|
||||
if not cl_tfa_fx_dof_hd then
|
||||
cl_tfa_fx_dof_hd = GetConVar("cl_tfa_fx_ads_dof_hd")
|
||||
end
|
||||
|
||||
if not cl_tfa_fx_dof or not cl_tfa_fx_dof:GetBool() then
|
||||
wep:ViewModelDrawnPost()
|
||||
return
|
||||
end
|
||||
|
||||
if not wep.AllowIronSightsDoF then
|
||||
wep:ViewModelDrawnPost()
|
||||
return
|
||||
end
|
||||
|
||||
local aimingDown = wep:GetIronSightsProgress() > 0.4
|
||||
local eangles = EyeAngles()
|
||||
local fwd2 = vm:GetAngles():Forward()
|
||||
local scoped = TFA.LastRTUpdate > UnPredictedCurTime()
|
||||
|
||||
if aimingDown and not scoped and wep.__TFA_AimDoFFrame == FrameNumber() then
|
||||
fmat:SetFloat("$alpha", wep:GetIronSightsProgress())
|
||||
local muzzle = hook.Run("TFA_GetDoFMuzzleAttachmentID", wep, plyv, vm) or vm:LookupAttachment("muzzle")
|
||||
local muzzleflash = vm:LookupAttachment("muzzleflash")
|
||||
local muzzledata
|
||||
|
||||
if muzzle and muzzle ~= 0 then
|
||||
muzzledata = vm:GetAttachment(muzzle)
|
||||
elseif wep.MuzzleAttachmentRaw then
|
||||
muzzledata = vm:GetAttachment(wep.MuzzleAttachmentRaw)
|
||||
elseif muzzleflash and muzzleflash ~= 0 then
|
||||
muzzledata = vm:GetAttachment(muzzleflash)
|
||||
end
|
||||
|
||||
local hands = plyv:GetHands()
|
||||
|
||||
if IsValid(hands) and wep.UseHands then
|
||||
render.OverrideColorWriteEnable(true, false)
|
||||
STOP = true
|
||||
local candraw = hook.Run("PreDrawPlayerHands", hands, vm, plyv, wep)
|
||||
STOP = false
|
||||
if candraw ~= true then
|
||||
if wep.ViewModelFlip then
|
||||
render.CullMode(MATERIAL_CULLMODE_CW)
|
||||
end
|
||||
|
||||
hands:DrawModel()
|
||||
|
||||
if wep.ViewModelFlip then
|
||||
render.CullMode(MATERIAL_CULLMODE_CCW)
|
||||
end
|
||||
end
|
||||
|
||||
render.OverrideColorWriteEnable(false, false)
|
||||
end
|
||||
|
||||
if muzzledata then
|
||||
render.SetStencilPassOperation(STENCIL_ZERO)
|
||||
render.SetMaterial(white)
|
||||
render.DrawSprite(muzzledata.Pos - fwd2 * 6 + eangles:Up() * 4, 30, 30, transparent)
|
||||
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||
end
|
||||
|
||||
render.SetStencilTestMask(1)
|
||||
render.SetStencilWriteMask(2)
|
||||
render.SetStencilCompareFunction(STENCIL_EQUAL)
|
||||
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||
render.UpdateScreenEffectTexture()
|
||||
render.PushFilterMin(TEXFILTER.ANISOTROPIC)
|
||||
render.PushFilterMag(TEXFILTER.ANISOTROPIC)
|
||||
if cl_tfa_fx_dof_hd and cl_tfa_fx_dof_hd:GetBool() then
|
||||
DrawDOF(muzzledata,fwd2)
|
||||
else
|
||||
DrawToyTown(3,ScrH() * 2 / 3 )
|
||||
end
|
||||
render.PopFilterMin()
|
||||
render.PopFilterMag()
|
||||
--render.PopRenderTarget()
|
||||
render.SetStencilEnable(false)
|
||||
end
|
||||
|
||||
wep:ViewModelDrawnPost()
|
||||
end)
|
||||
|
||||
hook.Add("PreDrawPlayerHands", "TFA_DrawViewModel", function(hands, vm, plyv, wep)
|
||||
if STOP then return end
|
||||
if not wep.IsTFAWeapon then return end
|
||||
if not supports then return end
|
||||
|
||||
if not cl_tfa_fx_dof then
|
||||
cl_tfa_fx_dof = GetConVar("cl_tfa_fx_ads_dof")
|
||||
end
|
||||
|
||||
if not cl_tfa_fx_dof or not cl_tfa_fx_dof:GetBool() then return end
|
||||
if not wep.AllowIronSightsDoF then return end
|
||||
if TFA.LastRTUpdate > UnPredictedCurTime() then return end
|
||||
if wep:GetIronSightsProgress() > 0.4 then return true end
|
||||
end)
|
||||
|
||||
hook.Add("PostDrawPlayerHands", "TFA_DrawViewModel", function(hands, vm, plyv, wep)
|
||||
if not wep.IsTFAWeapon then return end
|
||||
|
||||
wep:ViewModelDrawnPostFinal()
|
||||
end)
|
||||
56
lua/tfa/modules/sv_tfa_settingsmenu.lua
Normal file
56
lua/tfa/modules/sv_tfa_settingsmenu.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
--[[
|
||||
| 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 IsSinglePlayer = game.SinglePlayer()
|
||||
|
||||
util.AddNetworkString("TFA_SetServerCommand")
|
||||
|
||||
local function QueueConVarChange(convarname, convarvalue)
|
||||
if not convarname or not convarvalue then return end
|
||||
|
||||
timer.Create("tfa_cvarchange_" .. convarname, 0.1, 1, function()
|
||||
if not string.find(convarname, "_tfa") or not GetConVar(convarname) then return end -- affect only TFA convars
|
||||
|
||||
RunConsoleCommand(convarname, convarvalue)
|
||||
end)
|
||||
end
|
||||
|
||||
local function ChangeServerOption(_length, _player)
|
||||
local _cvarname = net.ReadString()
|
||||
local _value = net.ReadString()
|
||||
|
||||
if IsSinglePlayer then return end
|
||||
if not IsValid(_player) or not _player:IsAdmin() then return end
|
||||
|
||||
QueueConVarChange(_cvarname, _value)
|
||||
end
|
||||
|
||||
net.Receive("TFA_SetServerCommand", ChangeServerOption)
|
||||
48
lua/tfa/modules/tfa_ammo.lua
Normal file
48
lua/tfa/modules/tfa_ammo.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
--[[Bow Ammo]]
|
||||
--
|
||||
game.AddAmmoType({
|
||||
name = "tfbow_arrow",
|
||||
dmgtype = DMG_CLUB,
|
||||
tracer = 0,
|
||||
minsplash = 5,
|
||||
maxsplash = 5
|
||||
})
|
||||
|
||||
game.AddAmmoType({
|
||||
name = "tfbow_bolt",
|
||||
dmgtype = DMG_CLUB,
|
||||
tracer = 0,
|
||||
minsplash = 5,
|
||||
maxsplash = 5
|
||||
})
|
||||
420
lua/tfa/modules/tfa_attachments.lua
Normal file
420
lua/tfa/modules/tfa_attachments.lua
Normal file
@@ -0,0 +1,420 @@
|
||||
--[[
|
||||
| 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)
|
||||
|
||||
]]
|
||||
--
|
||||
446
lua/tfa/modules/tfa_ballistics.lua
Normal file
446
lua/tfa/modules/tfa_ballistics.lua
Normal file
@@ -0,0 +1,446 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
-- Degrees to accuracy vector, Valve's formula from SDK 2013
|
||||
TFA.DegreesToAccuracy = math.sin((math.pi / 180) / 2) -- approx. 0.00873
|
||||
|
||||
--default cvar integration
|
||||
local cv_gravity = GetConVar("sv_gravity")
|
||||
|
||||
--[[local function TimeScale(v)
|
||||
return v * game.GetTimeScale() / TFA.Ballistics.SubSteps
|
||||
end]]
|
||||
|
||||
--init code
|
||||
TFA.Ballistics = TFA.Ballistics or {}
|
||||
TFA.Ballistics.Enabled = false
|
||||
TFA.Ballistics.Gravity = Vector(0, 0, -cv_gravity:GetFloat())
|
||||
TFA.Ballistics.Bullets = TFA.Ballistics.Bullets or {}
|
||||
TFA.Ballistics.Bullets.bullet_registry = TFA.Ballistics.Bullets.bullet_registry or {}
|
||||
TFA.Ballistics.BulletLife = 10
|
||||
TFA.Ballistics.UnitScale = TFA.UnitScale or 39.3701 --meters to inches
|
||||
TFA.Ballistics.AirResistance = 1
|
||||
TFA.Ballistics.WaterResistance = 3
|
||||
TFA.Ballistics.WaterEntranceResistance = 6
|
||||
|
||||
TFA.Ballistics.DamageVelocityLUT = {
|
||||
[13] = 350, --shotgun
|
||||
[25] = 425, --mp5k etc.
|
||||
[35] = 900, --ak-12
|
||||
[65] = 830, --SVD
|
||||
[120] = 1100 --sniper cap
|
||||
}
|
||||
|
||||
TFA.Ballistics.VelocityMultiplier = 1
|
||||
TFA.Ballistics.SubSteps = 1
|
||||
TFA.Ballistics.BulletCreationNetString = "TFABallisticsBullet"
|
||||
|
||||
TFA.Ballistics.TracerStyles = {
|
||||
[0] = "",
|
||||
[1] = "tfa_bullet_smoke_tracer",
|
||||
[2] = "tfa_bullet_fire_tracer"
|
||||
}
|
||||
|
||||
setmetatable(TFA.Ballistics.TracerStyles, {
|
||||
["__index"] = function(t, k) return t[math.Round(tonumber(k) or 1)] or t[1] end
|
||||
})
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString(TFA.Ballistics.BulletCreationNetString)
|
||||
end
|
||||
|
||||
--bullet class
|
||||
local function IncludeClass(fn)
|
||||
include("tfa/ballistics/" .. fn .. ".lua")
|
||||
AddCSLuaFile("tfa/ballistics/" .. fn .. ".lua")
|
||||
end
|
||||
|
||||
IncludeClass("bullet")
|
||||
--cvar code
|
||||
local function CreateReplConVar(cvarname, cvarvalue, description, ...)
|
||||
return CreateConVar(cvarname, cvarvalue, CLIENT and {FCVAR_REPLICATED} or {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY}, description, ...)
|
||||
end -- replicated only on clients, archive/notify on server
|
||||
|
||||
local cv_enabled = CreateReplConVar("sv_tfa_ballistics_enabled", "0", "Enable TFA Ballistics?")
|
||||
local cv_bulletlife = CreateReplConVar("sv_tfa_ballistics_bullet_life", 10, "Time to process bullets before removing.")
|
||||
local cv_res_air = CreateReplConVar("sv_tfa_ballistics_bullet_damping_air", 1, "Air resistance, which makes bullets arc faster.")
|
||||
local cv_res_water = CreateReplConVar("sv_tfa_ballistics_bullet_damping_water", 3, "Water resistance, which makes bullets arc faster in water.")
|
||||
local cv_vel = CreateReplConVar("sv_tfa_ballistics_bullet_velocity", 1, "Global velocity multiplier for TFA ballistics bullets.")
|
||||
local cv_substep = CreateReplConVar("sv_tfa_ballistics_substeps", 1, "Substeps for ballistics; more is more precise, at the cost of performance.")
|
||||
local sv_tfa_ballistics_custom_gravity = CreateReplConVar("sv_tfa_ballistics_custom_gravity", 0, "Enable sv_gravity override for ballistics")
|
||||
local sv_tfa_ballistics_custom_gravity_value = CreateReplConVar("sv_tfa_ballistics_custom_gravity_value", 0, "Z velocity down of custom gravity")
|
||||
CreateReplConVar("sv_tfa_ballistics_mindist", -1, "Minimum distance to activate; -1 for always.")
|
||||
|
||||
local function updateCVars()
|
||||
TFA.Ballistics.BulletLife = cv_bulletlife:GetFloat()
|
||||
TFA.Ballistics.AirResistance = cv_res_air:GetFloat()
|
||||
TFA.Ballistics.WaterResistance = cv_res_water:GetFloat()
|
||||
TFA.Ballistics.WaterEntranceResistance = TFA.Ballistics.WaterResistance * 2
|
||||
TFA.Ballistics.VelocityMultiplier = cv_vel:GetFloat()
|
||||
|
||||
if sv_tfa_ballistics_custom_gravity:GetBool() then
|
||||
TFA.Ballistics.Gravity.z = -sv_tfa_ballistics_custom_gravity_value:GetFloat()
|
||||
else
|
||||
TFA.Ballistics.Gravity.z = -cv_gravity:GetFloat()
|
||||
end
|
||||
|
||||
TFA.Ballistics.Enabled = cv_enabled:GetBool()
|
||||
TFA.Ballistics.SubSteps = cv_substep:GetInt()
|
||||
end
|
||||
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_enabled", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_bullet_life", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_bullet_damping_air", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_bullet_damping_water", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_bullet_velocity", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_substeps", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_mindist", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_custom_gravity", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_tfa_ballistics_custom_gravity_value", updateCVars, "TFA")
|
||||
cvars.AddChangeCallback("sv_gravity", updateCVars, "TFA Ballistics")
|
||||
updateCVars()
|
||||
|
||||
--client cvar code
|
||||
local cv_receive, cv_tracers_style, cv_tracers_mp
|
||||
|
||||
if CLIENT then
|
||||
cv_receive = CreateClientConVar("cl_tfa_ballistics_mp", "1", true, false, "Receive bullet data from other players?")
|
||||
CreateClientConVar("cl_tfa_ballistics_fx_bullet", "1", true, false, "Display bullet models for each TFA ballistics bullet?")
|
||||
cv_tracers_style = CreateClientConVar("cl_tfa_ballistics_fx_tracers_style", "1", true, false, "Style of tracers for TFA ballistics? 0=disable,1=smoke")
|
||||
cv_tracers_mp = CreateClientConVar("cl_tfa_ballistics_fx_tracers_mp", "1", true, false, "Enable tracers for other TFA ballistics users?")
|
||||
CreateClientConVar("cl_tfa_ballistics_fx_tracers_adv", "1", true, false, "Enable advanced tracer calculations for other users? This corrects smoke trail to their barrel")
|
||||
end
|
||||
|
||||
--utility func
|
||||
local function Remap(inp, u, v, x, y)
|
||||
return (inp - u) / (v - u) * (y - x) + x
|
||||
end
|
||||
|
||||
--Accessors
|
||||
local CopyTable = table.Copy
|
||||
|
||||
function TFA.Ballistics.Bullets:Add(bulletStruct, originalBulletData)
|
||||
local bullet = TFA.Ballistics:Bullet(bulletStruct)
|
||||
bullet.bul = CopyTable(originalBulletData or bullet.bul)
|
||||
bullet.last_update = CurTime() - TFA.FrameTime()
|
||||
|
||||
table.insert(self.bullet_registry, bullet)
|
||||
|
||||
bullet:_setup()
|
||||
|
||||
if SERVER and game.GetTimeScale() > 0.99 then
|
||||
-- always update bullet since they are being added from predicted hook
|
||||
bullet:Update(CurTime())
|
||||
end
|
||||
end
|
||||
|
||||
function TFA.Ballistics.Bullets:Update(ply)
|
||||
--local delta = TimeScale(SysTime() - (self.lastUpdate or (SysTime() - FrameTime())))
|
||||
local delta = CurTime()
|
||||
|
||||
--self.lastUpdate = SysTime()
|
||||
local toremove
|
||||
local lply = CLIENT and LocalPlayer()
|
||||
|
||||
for i, bullet in ipairs(self.bullet_registry) do
|
||||
if bullet.delete then
|
||||
if not toremove then
|
||||
toremove = {}
|
||||
end
|
||||
|
||||
table.insert(toremove, i)
|
||||
elseif not ply and not bullet.playerOwned or CLIENT and bullet.owner ~= lply or ply == bullet.owner then
|
||||
for _ = 1, TFA.Ballistics.SubSteps do
|
||||
bullet:Update(delta)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if toremove then
|
||||
for i = #toremove, 1, -1 do
|
||||
table.remove(self.bullet_registry, toremove[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TFA.Ballistics:AutoDetectVelocity(damage)
|
||||
local lutMin, lutMax, LUT, DMGs
|
||||
LUT = self.DamageVelocityLUT
|
||||
DMGs = table.GetKeys(LUT)
|
||||
table.sort(DMGs)
|
||||
|
||||
for _, v in ipairs(DMGs) do
|
||||
if v < damage then
|
||||
lutMin = v
|
||||
elseif lutMin then
|
||||
lutMax = v
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not lutMax then
|
||||
lutMax = DMGs[#DMGs]
|
||||
lutMin = DMGs[#DMGs - 1]
|
||||
elseif not lutMin then
|
||||
lutMin = DMGs[1]
|
||||
lutMax = DMGs[2]
|
||||
end
|
||||
|
||||
return Remap(damage, lutMin, lutMax, LUT[lutMin], LUT[lutMax])
|
||||
end
|
||||
|
||||
function TFA.Ballistics:ShouldUse(wep)
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then
|
||||
return false
|
||||
end
|
||||
|
||||
local shouldUse = wep:GetStatL("UseBallistics")
|
||||
|
||||
if shouldUse == nil then
|
||||
if wep:GetStatL("TracerPCF") then
|
||||
return false
|
||||
end
|
||||
|
||||
return self.Enabled
|
||||
else
|
||||
return shouldUse
|
||||
end
|
||||
end
|
||||
|
||||
local sv_tfa_recoil_legacy = GetConVar("sv_tfa_recoil_legacy")
|
||||
|
||||
function TFA.Ballistics:FireBullets(wep, bulletStruct, angIn, bulletOverride)
|
||||
if not IsValid(wep) then return end
|
||||
if not IsValid(wep:GetOwner()) then return end
|
||||
|
||||
local vel
|
||||
|
||||
if bulletStruct.Velocity then
|
||||
vel = bulletStruct.Velocity
|
||||
elseif wep.GetStat and wep:GetStatL("Primary.Velocity") then
|
||||
vel = wep:GetStatL("Primary.Velocity") * TFA.Ballistics.UnitScale
|
||||
elseif wep.Primary and wep.Primary.Velocity then
|
||||
vel = wep.Primary.Velocity * TFA.Ballistics.UnitScale
|
||||
elseif wep.Velocity then
|
||||
vel = wep.Velocity * TFA.Ballistics.UnitScale
|
||||
else
|
||||
local dmg
|
||||
|
||||
if wep.GetStat and wep:GetStatL("Primary.Damage") then
|
||||
dmg = wep:GetStatL("Primary.Damage")
|
||||
else
|
||||
dmg = wep.Primary.Damage or wep.Damage or 30
|
||||
end
|
||||
|
||||
vel = TFA.Ballistics:AutoDetectVelocity(dmg) * TFA.Ballistics.UnitScale
|
||||
end
|
||||
|
||||
vel = vel * (TFA.Ballistics.VelocityMultiplier or 1)
|
||||
|
||||
local oldNum = bulletStruct.Num
|
||||
bulletStruct.Num = 1
|
||||
bulletStruct.IsBallistics = true
|
||||
|
||||
local owner = wep:GetOwner()
|
||||
local isnpc = owner:IsNPC()
|
||||
local ac = bulletStruct.Spread
|
||||
local sharedRandomSeed = "Ballistics" .. CurTime()
|
||||
|
||||
for i = 1, oldNum do
|
||||
local ang
|
||||
|
||||
if angIn then
|
||||
ang = angIn
|
||||
else
|
||||
ang = owner:GetAimVector():Angle()
|
||||
|
||||
if sv_tfa_recoil_legacy:GetBool() and not isnpc then
|
||||
ang:Add(owner:GetViewPunchAngles())
|
||||
else
|
||||
ang.p = ang.p + wep:GetViewPunchP()
|
||||
ang.y = ang.y + wep:GetViewPunchY()
|
||||
end
|
||||
end
|
||||
|
||||
if not angIn then
|
||||
ang:RotateAroundAxis(ang:Up(), util.SharedRandom(sharedRandomSeed, -ac.x * 45, ac.x * 45, 0 + i))
|
||||
ang:RotateAroundAxis(ang:Right(), util.SharedRandom(sharedRandomSeed, -ac.y * 45, ac.y * 45, 1 + i))
|
||||
end
|
||||
|
||||
local struct = {
|
||||
owner = owner, --used for dmginfo SetAttacker
|
||||
inflictor = wep, --used for dmginfo SetInflictor
|
||||
damage = bulletStruct.Damage, --floating point number representing inflicted damage
|
||||
force = bulletStruct.Force,
|
||||
pos = bulletOverride and bulletStruct.Src or owner:GetShootPos(), --b.Src, --vector representing current position
|
||||
velocity = (bulletOverride and bulletStruct.Dir or ang:Forward()) * vel, --b.Dir * vel, --vector representing movement velocity
|
||||
model = wep.BulletModel or bulletStruct.Model, --optional variable representing the given model
|
||||
smokeparticle = bulletStruct.SmokeParticle,
|
||||
customPosition = bulletStruct.CustomPosition or bulletOverride,
|
||||
IgnoreEntity = bulletStruct.IgnoreEntity
|
||||
}
|
||||
|
||||
if CLIENT then
|
||||
if not struct.smokeparticle then
|
||||
struct.smokeparticle = TFA.Ballistics.TracerStyles[cv_tracers_style:GetInt()]
|
||||
end
|
||||
end
|
||||
|
||||
self.Bullets:Add(struct, bulletStruct)
|
||||
|
||||
if SERVER then
|
||||
net.Start(TFA.Ballistics.BulletCreationNetString)
|
||||
|
||||
net.WriteEntity(struct.owner)
|
||||
net.WriteEntity(struct.inflictor)
|
||||
net.WriteFloat(struct.damage)
|
||||
net.WriteFloat(struct.force)
|
||||
net.WriteVector(struct.pos)
|
||||
|
||||
net.WriteDouble(struct.velocity.x)
|
||||
net.WriteDouble(struct.velocity.y)
|
||||
net.WriteDouble(struct.velocity.z)
|
||||
|
||||
net.WriteString(struct.model or '')
|
||||
net.WriteString(struct.smokeparticle or '')
|
||||
net.WriteBool(struct.customPosition == true)
|
||||
net.WriteEntity(struct.IgnoreEntity or NULL)
|
||||
|
||||
net.WriteVector(bulletStruct.Src)
|
||||
net.WriteNormal(bulletStruct.Dir)
|
||||
net.WriteEntity(bulletStruct.Attacker)
|
||||
net.WriteVector(bulletStruct.Spread)
|
||||
net.WriteFloat(vel)
|
||||
|
||||
if game.SinglePlayer() or isnpc then
|
||||
net.SendPVS(struct.pos)
|
||||
else
|
||||
net.SendOmit(owner)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TFA.Ballistics.Bullets:Render()
|
||||
for i = 1, #self.bullet_registry do
|
||||
self.bullet_registry[i]:Render()
|
||||
end
|
||||
end
|
||||
|
||||
local sp = game.SinglePlayer()
|
||||
|
||||
--Netcode and Hooks
|
||||
if CLIENT then
|
||||
net.Receive(TFA.Ballistics.BulletCreationNetString, function()
|
||||
if not sp and not cv_receive:GetBool() then return end
|
||||
|
||||
local owner = net.ReadEntity()
|
||||
local inflictor = net.ReadEntity()
|
||||
local damage = net.ReadFloat()
|
||||
local force = net.ReadFloat()
|
||||
local pos = net.ReadVector()
|
||||
local velocity = Vector(net.ReadDouble(), net.ReadDouble(), net.ReadDouble())
|
||||
local model = net.ReadString()
|
||||
local smokeparticle = net.ReadString()
|
||||
local customPosition = net.ReadBool()
|
||||
local IgnoreEntity = net.ReadEntity()
|
||||
|
||||
|
||||
local Src = net.ReadVector()
|
||||
local Dir = net.ReadNormal()
|
||||
local Attacker = net.ReadEntity()
|
||||
local Spread = net.ReadVector()
|
||||
local Velocity = net.ReadFloat()
|
||||
|
||||
if not IsValid(owner) or not IsValid(inflictor) then return end
|
||||
|
||||
if not cv_tracers_mp:GetBool() and owner ~= LocalPlayer() then
|
||||
smokeparticle = ""
|
||||
elseif smokeparticle == "" then
|
||||
smokeparticle = TFA.Ballistics.TracerStyles[cv_tracers_style:GetInt()]
|
||||
end
|
||||
|
||||
local struct = {
|
||||
owner = owner,
|
||||
inflictor = inflictor,
|
||||
damage = damage,
|
||||
force = force,
|
||||
pos = pos,
|
||||
velocity = velocity,
|
||||
model = model ~= "" and model or nil,
|
||||
smokeparticle = smokeparticle,
|
||||
customPosition = customPosition,
|
||||
IgnoreEntity = IgnoreEntity,
|
||||
}
|
||||
|
||||
local bulletStruct = {
|
||||
Damage = damage,
|
||||
Force = force,
|
||||
Num = 1,
|
||||
Src = Src,
|
||||
Dir = Dir,
|
||||
Attacker = Attacker,
|
||||
Spread = Spread,
|
||||
SmokeParticle = smokeparticle,
|
||||
CustomPosition = customPosition,
|
||||
Model = model ~= "" and model or nil,
|
||||
Velocity = Velocity,
|
||||
IsBallistics = true,
|
||||
}
|
||||
|
||||
TFA.Ballistics.Bullets:Add(struct, bulletStruct)
|
||||
end)
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
hook.Add("FinishMove", "TFABallisticsTick", function(self)
|
||||
if IsFirstTimePredicted() then
|
||||
TFA.Ballistics.Bullets:Update(self)
|
||||
end
|
||||
end)
|
||||
else
|
||||
hook.Add("PlayerPostThink", "TFABallisticsTick", function(self)
|
||||
TFA.Ballistics.Bullets:Update(self)
|
||||
end)
|
||||
end
|
||||
|
||||
hook.Add("Tick", "TFABallisticsTick", function()
|
||||
TFA.Ballistics.Bullets:Update()
|
||||
|
||||
if CLIENT and sp then
|
||||
TFA.Ballistics.Bullets:Update(LocalPlayer())
|
||||
end
|
||||
end)
|
||||
|
||||
--Rendering
|
||||
hook.Add("PostDrawOpaqueRenderables", "TFABallisticsRender", function()
|
||||
TFA.Ballistics.Bullets:Render()
|
||||
end)
|
||||
46
lua/tfa/modules/tfa_bodygroups.lua
Normal file
46
lua/tfa/modules/tfa_bodygroups.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
--[[
|
||||
| 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()
|
||||
|
||||
hook.Add("PlayerSwitchWeapon", "TFA_Bodygroups_PSW", function(ply, oldwep, wep)
|
||||
if not IsValid(wep) or not wep.IsTFAWeapon then return end
|
||||
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(ply) or ply:GetActiveWeapon() ~= wep then return end
|
||||
|
||||
wep:ApplyViewModelModifications()
|
||||
|
||||
if sp then
|
||||
wep:CallOnClient("ApplyViewModelModifications")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
375
lua/tfa/modules/tfa_commands.lua
Normal file
375
lua/tfa/modules/tfa_commands.lua
Normal file
@@ -0,0 +1,375 @@
|
||||
--[[
|
||||
| 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 function CreateReplConVar(cvarname, cvarvalue, description, ...)
|
||||
return CreateConVar(cvarname, cvarvalue, CLIENT and {FCVAR_REPLICATED} or {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY}, description, ...)
|
||||
end -- replicated only on clients, archive/notify on server
|
||||
|
||||
-- Shared Convars
|
||||
|
||||
if GetConVar("sv_tfa_changelog") == nil then
|
||||
CreateReplConVar("sv_tfa_changelog", "1", "Enable changelog?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_soundscale") == nil then
|
||||
CreateReplConVar("sv_tfa_soundscale", "1", "Scale sound pitch in accordance to timescale?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_weapon_strip") == nil then
|
||||
CreateReplConVar("sv_tfa_weapon_strip", "0", "Allow the removal of empty weapons?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_spread_legacy") == nil then
|
||||
CreateReplConVar("sv_tfa_spread_legacy", "0", "Use legacy spread algorithms?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_cmenu") == nil then
|
||||
CreateReplConVar("sv_tfa_cmenu", "1", "Allow custom context menu?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_cmenu_key") == nil then
|
||||
CreateReplConVar("sv_tfa_cmenu_key", "-1", "Override the inspection menu key? Uses the KEY enum available on the gmod wiki. -1 to not.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_range_modifier") == nil then
|
||||
CreateReplConVar("sv_tfa_range_modifier", "0.5", "This controls how much the range affects damage. 0.5 means the maximum loss of damage is 0.5.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_allow_dryfire") == nil then
|
||||
CreateReplConVar("sv_tfa_allow_dryfire", "1", "Allow dryfire?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_penetration_hardlimit") == nil then
|
||||
CreateReplConVar("sv_tfa_penetration_hardlimit", "100", "Max number of objects we can penetrate through.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_bullet_penetration_power_mul") == nil then
|
||||
CreateReplConVar("sv_tfa_bullet_penetration_power_mul", "1", "Power multiplier. 1 or 1.5 for CS 1.6 experience, 0.25 for semi-realistic behavior")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_penetration_hitmarker") == nil then
|
||||
CreateReplConVar("sv_tfa_penetration_hitmarker", "1", "Should penetrating bullet send hitmarker to attacker?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_damage_multiplier") == nil then
|
||||
CreateReplConVar("sv_tfa_damage_multiplier", "1", "Multiplier for TFA base projectile damage.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_damage_multiplier_npc") == nil then
|
||||
CreateReplConVar("sv_tfa_damage_multiplier_npc", "1", "Multiplier for TFA base projectile damage for NPCs.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_damage_mult_min") == nil then
|
||||
CreateConVar("sv_tfa_damage_mult_min", "0.95", {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE}, "This is the lower range of a random damage factor.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_damage_mult_max") == nil then
|
||||
CreateReplConVar("sv_tfa_damage_mult_max", "1.05", "This is the higher range of a random damage factor.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_damage_npc") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_damage_npc", "1", "Damage multiplier against NPCs using TFA Melees.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_damage_ply") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_damage_ply", "0.65", "Damage multiplier against players using TFA Melees.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_blocking_timed") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_blocking_timed", "1", "Enable timed blocking?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_blocking_anglemult") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_blocking_anglemult", "1", "Players can block attacks in an angle around their view. This multiplies that angle.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_blocking_deflection") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_blocking_deflection", "1", "For weapons that can deflect bullets ( e.g. certain katans ), can you deflect bullets? Set to 1 to enable for parries, or 2 for all blocks.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_blocking_timed") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_blocking_timed", "1", "Enable timed blocking?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_blocking_stun_enabled") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_blocking_stun_enabled", "1", "Stun NPCs on block?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_blocking_stun_time") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_blocking_stun_time", "0.65", "How long to stun NPCs on block.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_melee_doordestruction") == nil then
|
||||
CreateReplConVar("sv_tfa_melee_doordestruction", "1", "Allow players to bash open doors?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_door_respawn") == nil then
|
||||
CreateReplConVar("sv_tfa_door_respawn", "-1", "Time for doors to respawn; -1 for never.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_npc_randomize_atts") == nil then
|
||||
CreateReplConVar("sv_tfa_npc_randomize_atts", "1", "Randomize NPC's weapons attachments.")
|
||||
end
|
||||
|
||||
local cv_dfc
|
||||
if GetConVar("sv_tfa_default_clip") == nil then
|
||||
cv_dfc = CreateReplConVar("sv_tfa_default_clip", "-1", "How many clips will a weapon spawn with? Negative reverts to default values.")
|
||||
else
|
||||
cv_dfc = GetConVar("sv_tfa_default_clip")
|
||||
end
|
||||
|
||||
local function TFAUpdateDefaultClip()
|
||||
local dfc = cv_dfc:GetInt()
|
||||
local weplist = weapons.GetList()
|
||||
if not weplist or #weplist <= 0 then return end
|
||||
|
||||
for _, v in pairs(weplist) do
|
||||
local cl = v.ClassName and v.ClassName or v
|
||||
local wep = weapons.GetStored(cl)
|
||||
|
||||
if wep and (wep.IsTFAWeapon or string.find(string.lower(wep.Base and wep.Base or ""), "tfa")) then
|
||||
if not wep.Primary then
|
||||
wep.Primary = {}
|
||||
end
|
||||
|
||||
if not wep.Primary.TrueDefaultClip then
|
||||
wep.Primary.TrueDefaultClip = wep.Primary.DefaultClip
|
||||
end
|
||||
|
||||
if not wep.Primary.TrueDefaultClip then
|
||||
wep.Primary.TrueDefaultClip = 0
|
||||
end
|
||||
|
||||
if dfc < 0 then
|
||||
wep.Primary.DefaultClip = wep.Primary.TrueDefaultClip
|
||||
else
|
||||
if wep.Primary.ClipSize and wep.Primary.ClipSize > 0 then
|
||||
wep.Primary.DefaultClip = wep.Primary.ClipSize * dfc
|
||||
else
|
||||
wep.Primary.DefaultClip = wep.Primary.TrueDefaultClip * 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity", "TFADefaultClipPE", TFAUpdateDefaultClip)
|
||||
|
||||
if TFAUpdateDefaultClip then
|
||||
TFAUpdateDefaultClip()
|
||||
end
|
||||
|
||||
--if GetConVar("sv_tfa_default_clip") == nil then
|
||||
|
||||
cvars.AddChangeCallback("sv_tfa_default_clip", function(convar_name, value_old, value_new)
|
||||
TFAUpdateDefaultClip()
|
||||
end, "TFAUpdateDefaultClip")
|
||||
|
||||
local function sv_tfa_range_modifier()
|
||||
for k, v in ipairs(ents.GetAll()) do
|
||||
if v.IsTFAWeapon and v.Primary_TFA.RangeFalloffLUT_IsConverted then
|
||||
v.Primary_TFA.RangeFalloffLUT = nil
|
||||
v:AutoDetectRange()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cvars.AddChangeCallback("sv_tfa_range_modifier", sv_tfa_range_modifier, "TFA")
|
||||
|
||||
sv_tfa_range_modifier()
|
||||
|
||||
if CLIENT then
|
||||
hook.Add("InitPostEntity", "sv_tfa_range_modifier", sv_tfa_range_modifier)
|
||||
end
|
||||
|
||||
--end
|
||||
if GetConVar("sv_tfa_unique_slots") == nil then
|
||||
CreateReplConVar("sv_tfa_unique_slots", "1", "Give TFA-based Weapons unique slots? 1 for true, 0 for false. RESTART AFTER CHANGING.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_spread_multiplier") == nil then
|
||||
CreateReplConVar("sv_tfa_spread_multiplier", "1", "Increase for more spread, decrease for less.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_force_multiplier") == nil then
|
||||
CreateReplConVar("sv_tfa_force_multiplier", "1", "Arrow force multiplier (not arrow velocity, but how much force they give on impact).")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_dynamicaccuracy") == nil then
|
||||
CreateReplConVar("sv_tfa_dynamicaccuracy", "1", "Dynamic acuracy? (e.g.more accurate on crouch, less accurate on jumping.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_ammo_detonation") == nil then
|
||||
CreateReplConVar("sv_tfa_ammo_detonation", "1", "Ammo Detonation? (e.g. shoot ammo until it explodes) ")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_ammo_detonation_mode") == nil then
|
||||
CreateReplConVar("sv_tfa_ammo_detonation_mode", "2", "Ammo Detonation Mode? (0=Bullets,1=Blast,2=Mix) ")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_ammo_detonation_chain") == nil then
|
||||
CreateReplConVar("sv_tfa_ammo_detonation_chain", "1", "Ammo Detonation Chain? (0=Ammo boxes don't detonate other ammo boxes, 1 you can chain them together) ")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_scope_gun_speed_scale") == nil then
|
||||
CreateReplConVar("sv_tfa_scope_gun_speed_scale", "0", "Scale player sensitivity based on player move speed?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_bullet_penetration") == nil then
|
||||
CreateReplConVar("sv_tfa_bullet_penetration", "1", "Allow bullet penetration?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_bullet_doordestruction") == nil then
|
||||
CreateReplConVar("sv_tfa_bullet_doordestruction", "1", "Allow to shoot down doors?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_bullet_doordestruction_keep") == nil then
|
||||
CreateReplConVar("sv_tfa_bullet_doordestruction_keep", "0", "Don't shoot door off hinges")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_npc_burst") == nil then
|
||||
CreateReplConVar("sv_tfa_npc_burst", "0", "Whenever NPCs should fire in bursts like they do with HL2 weapons.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_bullet_ricochet") == nil then
|
||||
CreateReplConVar("sv_tfa_bullet_ricochet", "0", "Allow bullet ricochet?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_bullet_randomseed") == nil then
|
||||
CreateReplConVar("sv_tfa_bullet_randomseed", "0", "Populate extra seed serverside? This will cause spread to be out of sync with server!")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_debug") == nil then
|
||||
CreateReplConVar("sv_tfa_debug", "0", "Enable debug mode?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_holdtype_dynamic") == nil then
|
||||
CreateReplConVar("sv_tfa_holdtype_dynamic", "1", "Allow dynamic holdtype?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_arrow_lifetime") == nil then
|
||||
CreateReplConVar("sv_tfa_arrow_lifetime", "30", "Arrow lifetime.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_worldmodel_culldistance") == nil then
|
||||
CreateReplConVar("sv_tfa_worldmodel_culldistance", "-1", "-1 to leave unculled. Anything else is feet*16.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_reloads_legacy") == nil then
|
||||
CreateReplConVar("sv_tfa_reloads_legacy", "0", "Enable legacy-style reloading?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_legacy") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_legacy", "0", "Enable legacy-style recoil? This will cause prediction issues in multiplayer. Always disabled for NPCs!")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_mul_p") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_mul_p", "1", "Pitch kick multiplier for recoil")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_mul_y") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_mul_y", "1", "Yaw kick multiplier for recoil")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_mul_p_npc") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_mul_p_npc", "1", "Pitch kick multiplier for recoil for NPCs")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_mul_y_npc") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_mul_y_npc", "1", "Yaw kick multiplier for recoil for NPCs")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_viewpunch_mul") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_viewpunch_mul", "1", "Multiplier for viewpunch recoil (visual viewmodel recoil)")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_recoil_eyeangles_mul") == nil then
|
||||
CreateReplConVar("sv_tfa_recoil_eyeangles_mul", "1", "Multiplier for eye angles recoil (real angle change recoil)")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_fx_penetration_decal") == nil then
|
||||
CreateReplConVar("sv_tfa_fx_penetration_decal", "1", "Enable decals on the other side of a penetrated object?")
|
||||
end
|
||||
|
||||
local cv_ironsights = GetConVar("sv_tfa_ironsights_enabled")
|
||||
|
||||
if cv_ironsights == nil then
|
||||
cv_ironsights = CreateReplConVar("sv_tfa_ironsights_enabled", "1", "Enable ironsights? Disabling this still allows scopes.")
|
||||
end
|
||||
|
||||
local is_stats = {
|
||||
["data.ironsights"] = 0,
|
||||
["Secondary.IronSightsEnabled"] = false,
|
||||
}
|
||||
|
||||
hook.Add("TFA_GetStat", "TFA_IronsightsConVarToggle", function(wep, stat, val)
|
||||
if not IsValid(wep) or is_stats[stat] == nil then return end
|
||||
|
||||
if not cv_ironsights:GetBool() and not wep:GetStatRawL("Scoped") and not wep:GetStatRawL("Scoped_3D") then
|
||||
return is_stats[stat]
|
||||
end
|
||||
end)
|
||||
|
||||
if GetConVar("sv_tfa_sprint_enabled") == nil then
|
||||
CreateReplConVar("sv_tfa_sprint_enabled", "1", "Enable sprinting? Disabling this allows shooting while IN_SPEED.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_attachments_alphabetical") == nil then
|
||||
CreateReplConVar("sv_tfa_attachments_alphabetical", "0", "Override weapon attachment order to be alphabetical.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_jamming") == nil then
|
||||
CreateReplConVar("sv_tfa_jamming", "1", "Enable jamming mechanics?")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_jamming_mult") == nil then
|
||||
CreateReplConVar("sv_tfa_jamming_mult", "1", "Multiply jam chance by this value. You really should modify sv_tfa_jamming_factor_inc rather than this.")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_jamming_factor") == nil then
|
||||
CreateReplConVar("sv_tfa_jamming_factor", "1", "Multiply jam factor by this value")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_jamming_factor_inc") == nil then
|
||||
CreateReplConVar("sv_tfa_jamming_factor_inc", "1", "Multiply jam factor gain by this value")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_nearlyempty") == nil then
|
||||
CreateReplConVar("sv_tfa_nearlyempty", "1", "Enable nearly-empty sounds")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_fixed_crosshair") == nil then
|
||||
CreateReplConVar("sv_tfa_fixed_crosshair", "0", "Fix crosshair position on center of the screen (CS:GO style)")
|
||||
end
|
||||
|
||||
if GetConVar("sv_tfa_weapon_weight") == nil then
|
||||
CreateReplConVar("sv_tfa_weapon_weight", "1", "Disabling this WILL break certain SWEPs and Mechanics. You were warned.")
|
||||
end
|
||||
57
lua/tfa/modules/tfa_darkrp.lua
Normal file
57
lua/tfa/modules/tfa_darkrp.lua
Normal file
@@ -0,0 +1,57 @@
|
||||
--[[
|
||||
| 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 TFA_PocketBlock = {}
|
||||
TFA_PocketBlock["tfa_ammo_357"] = true
|
||||
TFA_PocketBlock["tfa_ammo_ar2"] = true
|
||||
TFA_PocketBlock["tfa_ammo_buckshot"] = true
|
||||
TFA_PocketBlock["tfa_ammo_c4"] = true
|
||||
TFA_PocketBlock["tfa_ammo_frags"] = true
|
||||
TFA_PocketBlock["tfa_ammo_ieds"] = true
|
||||
TFA_PocketBlock["tfa_ammo_nervegas"] = true
|
||||
TFA_PocketBlock["tfa_ammo_nuke"] = true
|
||||
TFA_PocketBlock["tfa_ammo_pistol"] = true
|
||||
TFA_PocketBlock["tfa_ammo_proxmines"] = true
|
||||
TFA_PocketBlock["tfa_ammo_rockets"] = true
|
||||
TFA_PocketBlock["tfa_ammo_smg"] = true
|
||||
TFA_PocketBlock["tfa_ammo_smg1_grenade"] = true
|
||||
TFA_PocketBlock["tfa_ammo_smg1_grenade_large"] = true
|
||||
TFA_PocketBlock["tfa_ammo_sniper_rounds"] = true
|
||||
TFA_PocketBlock["tfa_ammo_stickynades"] = true
|
||||
TFA_PocketBlock["tfa_ammo_winchester"] = true
|
||||
|
||||
local function TFA_PockBlock(ply, wep) --Get it, because cockblock, hehe..... so mature.
|
||||
if not IsValid(wep) then return end
|
||||
local class = wep:GetClass()
|
||||
if TFA_PocketBlock[class] then return false end
|
||||
end
|
||||
|
||||
hook.Add("canPocket", "TFA_PockBlock", TFA_PockBlock)
|
||||
579
lua/tfa/modules/tfa_data.lua
Normal file
579
lua/tfa/modules/tfa_data.lua
Normal file
@@ -0,0 +1,579 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
-- This file is holding seamless translation of older versions of data to newer
|
||||
-- versions of data
|
||||
|
||||
TFA.LatestDataVersion = 1
|
||||
|
||||
TFA.DataVersionMapping = {
|
||||
[0] = {
|
||||
{
|
||||
old_path = "DrawCrosshairIS",
|
||||
new_path = "DrawCrosshairIronSights",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "FiresUnderwater",
|
||||
new_path = "Primary.FiresUnderwater",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "PenetrationMaterials",
|
||||
new_path = "Primary.PenetrationMaterials",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "MaxPenetrationCounter",
|
||||
new_path = "Primary.MaxSurfacePenetrationCount",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "MaxPenetration",
|
||||
new_path = "Primary.MaxSurfacePenetrationCount",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronRecoilMultiplier",
|
||||
new_path = "Primary.IronRecoilMultiplier",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "MoveSpeed",
|
||||
new_path = "RegularMoveSpeedMultiplier",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronSightsMoveSpeed",
|
||||
new_path = "AimingDownSightsSpeedMultiplier",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "Shotgun",
|
||||
new_path = "LoopedReload",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "ShellTime",
|
||||
new_path = "LoopedReloadInsertTime",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "CrouchPos",
|
||||
new_path = "CrouchViewModelPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "CrouchAng",
|
||||
new_path = "CrouchViewModelAngle",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "data.ironsights",
|
||||
new_path = "Secondary.IronSightsEnabled",
|
||||
upgrade = function(value) return value == 1 end,
|
||||
downgrade = function(value) return value and 1 or 0 end,
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "Secondary.IronFOV",
|
||||
new_path = "Secondary.OwnerFOV",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronViewModelFOV",
|
||||
new_path = "Secondary.ViewModelFOV",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "DoProceduralReload",
|
||||
new_path = "IsProceduralReloadBased",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "ProceduralReloadEnabled",
|
||||
new_path = "IsProceduralReloadBased",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "Akimbo",
|
||||
new_path = "IsAkimbo",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "AkimboHUD",
|
||||
new_path = "EnableAkimboHUD",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronInSound",
|
||||
new_path = "Secondary.IronSightsInSound",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronOutSound",
|
||||
new_path = "Secondary.IronSightsOutSound",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "DisableChambering",
|
||||
new_path = "Primary.DisableChambering",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "DisplayFalloff",
|
||||
new_path = "Primary.DisplayFalloff",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "SpreadPattern",
|
||||
new_path = "Primary.SpreadPattern",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "SpreadBiasYaw",
|
||||
new_path = "Primary.SpreadBiasYaw",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "SpreadBiasPitch",
|
||||
new_path = "Primary.SpreadBiasPitch",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "VMPos",
|
||||
new_path = "ViewModelPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "VMAng",
|
||||
new_path = "ViewModelAngle",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "VMPos_Additive",
|
||||
new_path = "AdditiveViewModelPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "RunSightsPos",
|
||||
new_path = "SprintViewModelPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "RunSightsAng",
|
||||
new_path = "SprintViewModelAngle",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronSightsPos",
|
||||
new_path = "IronSightsPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "IronSightsAng",
|
||||
new_path = "IronSightsAngle",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "Bodygroups_V",
|
||||
new_path = "ViewModelBodygroups",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "Bodygroups_W",
|
||||
new_path = "WorldModelBodygroups",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "CenteredPos",
|
||||
new_path = "CenteredViewModelPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "CenteredAng",
|
||||
new_path = "CenteredViewModelAngle",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "Offset",
|
||||
new_path = "WorldModelOffset",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "ProceduralHolsterPos",
|
||||
new_path = "ProceduralHolsterPosition",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "ProceduralHolsterAng",
|
||||
new_path = "ProceduralHolsterAngle",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "VElements",
|
||||
new_path = "ViewModelElements",
|
||||
},
|
||||
|
||||
{
|
||||
old_path = "WElements",
|
||||
new_path = "WorldModelElements",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
local function identity(...) return ... end
|
||||
|
||||
for version = 0, #TFA.DataVersionMapping do
|
||||
for i, data in ipairs(TFA.DataVersionMapping[version]) do
|
||||
if not isfunction(data.upgrade) then data.upgrade = identity end
|
||||
if not isfunction(data.downgrade) then data.downgrade = identity end
|
||||
end
|
||||
end
|
||||
|
||||
TFA.PathParseCache = {}
|
||||
TFA.PathParseCacheTR = {}
|
||||
TFA.StatPathRemapCache = {}
|
||||
TFA.PathParseCacheDirect = {}
|
||||
TFA.PathParseChildren = {}
|
||||
|
||||
local PathParseCache = TFA.PathParseCache
|
||||
local PathParseCacheTR = TFA.PathParseCacheTR
|
||||
local PathParseCacheDirect = TFA.PathParseCacheDirect
|
||||
local StatPathRemapCache = TFA.StatPathRemapCache
|
||||
local PathParseChildren = TFA.PathParseChildren
|
||||
local string_Explode = string.Explode
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local string_sub = string.sub
|
||||
local tonumber = tonumber
|
||||
local table_Copy = table.Copy
|
||||
local table_concat = table.concat
|
||||
local istable = istable
|
||||
local string_format = string.format
|
||||
|
||||
local function doDowngrade(path, migrations)
|
||||
for i, data in ipairs(migrations) do
|
||||
if data.new_path == path then
|
||||
return data.old_path, data.upgrade
|
||||
elseif path:StartWith(data.new_path) and path[#data.new_path + 1] == '.' then
|
||||
return data.old_path .. path:sub(#data.new_path + 1), data.upgrade
|
||||
end
|
||||
end
|
||||
|
||||
return path
|
||||
end
|
||||
|
||||
local function doUpgrade(path, migrations)
|
||||
for i, data in ipairs(migrations) do
|
||||
if data.old_path == path then
|
||||
return data.new_path, data.downgrade
|
||||
elseif path:StartWith(data.old_path) and path[#data.old_path + 1] == '.' then
|
||||
return data.new_path .. path:sub(#data.old_path + 1), data.downgrade
|
||||
end
|
||||
end
|
||||
|
||||
return path
|
||||
end
|
||||
|
||||
function TFA.RemapStatPath(path, path_version, structure_version)
|
||||
local cache_path = path
|
||||
|
||||
if path_version == nil then path_version = 0 end
|
||||
if structure_version == nil then structure_version = 0 end
|
||||
|
||||
-- version do not match
|
||||
if path_version ~= structure_version then
|
||||
cache_path = string_format("%d_%d_%s", path_version, structure_version, path)
|
||||
end
|
||||
|
||||
local get_cache = StatPathRemapCache[cache_path]
|
||||
if get_cache ~= nil then return get_cache end
|
||||
|
||||
if cache_path ~= path then
|
||||
-- downgrade path
|
||||
if path_version > structure_version then
|
||||
for version = path_version, structure_version, -1 do
|
||||
local mapping = TFA.DataVersionMapping[version]
|
||||
|
||||
if istable(mapping) then
|
||||
path = doDowngrade(path, mapping)
|
||||
end
|
||||
end
|
||||
else -- upgrade path
|
||||
for version = path_version, structure_version do
|
||||
local mapping = TFA.DataVersionMapping[version]
|
||||
|
||||
if istable(mapping) then
|
||||
path = doUpgrade(path, mapping)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
StatPathRemapCache[cache_path] = path
|
||||
return StatPathRemapCache[cache_path]
|
||||
end
|
||||
|
||||
function TFA.GetStatPathChildren(path, path_version, structure_version)
|
||||
-- version do not match
|
||||
if path_version ~= structure_version then
|
||||
path = TFA.RemapStatPath(path, path_version, structure_version)
|
||||
end
|
||||
|
||||
if not PathParseChildren[path] then
|
||||
TFA.GetStatPath(path, path_version, structure_version)
|
||||
end
|
||||
|
||||
return PathParseChildren[path].list
|
||||
end
|
||||
|
||||
local function concat_to(tab, to)
|
||||
local str = tab[1]
|
||||
|
||||
for i = 2, to do
|
||||
str = str .. '.' .. tab[i]
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
local function concat_from(tab, from)
|
||||
local str = tab[from]
|
||||
|
||||
for i = from + 1, #tab do
|
||||
str = str .. '.' .. tab[i]
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
function TFA.GetStatPath(path, path_version, structure_version, no_translate)
|
||||
local cache_path = path
|
||||
|
||||
if path_version == nil then path_version = 0 end
|
||||
if structure_version == nil then structure_version = 0 end
|
||||
|
||||
-- version do not match
|
||||
if path_version ~= structure_version then
|
||||
cache_path = string_format("%d_%d_%s", path_version, structure_version, path)
|
||||
end
|
||||
|
||||
local _PathParseCache = no_translate and PathParseCacheTR or PathParseCache
|
||||
local get_cache = _PathParseCache[cache_path]
|
||||
if get_cache ~= nil then return get_cache[1], get_cache[2], get_cache[3] end
|
||||
|
||||
local fn, fnGet
|
||||
|
||||
if cache_path ~= path then
|
||||
-- downgrade
|
||||
if path_version > structure_version then
|
||||
for version = path_version, structure_version, -1 do
|
||||
local mapping = TFA.DataVersionMapping[version]
|
||||
|
||||
if istable(mapping) then
|
||||
path, fnGet = doDowngrade(path, mapping)
|
||||
|
||||
if fnGet and fnGet ~= identity then
|
||||
if not fn then
|
||||
fn = fnGet
|
||||
else
|
||||
local _fn = fn
|
||||
function fn(...) return fnGet(_fn(...)) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else -- upgrade
|
||||
for version = path_version, structure_version do
|
||||
local mapping = TFA.DataVersionMapping[version]
|
||||
|
||||
if istable(mapping) then
|
||||
path, fnGet = doUpgrade(path, mapping)
|
||||
|
||||
if fnGet and fnGet ~= identity then
|
||||
if not fn then
|
||||
fn = fnGet
|
||||
else
|
||||
local _fn = fn
|
||||
function fn(...) return fnGet(_fn(...)) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_cache = string_Explode(".", path, false)
|
||||
|
||||
do
|
||||
local children = PathParseChildren[get_cache[1]]
|
||||
|
||||
if not children then
|
||||
children = {
|
||||
list = {get_cache[1]},
|
||||
children = {}
|
||||
}
|
||||
|
||||
PathParseChildren[get_cache[1]] = children
|
||||
end
|
||||
|
||||
local childrens = {children}
|
||||
|
||||
for i = 2, #get_cache do
|
||||
local obj = get_cache[i]
|
||||
local path2 = concat_to(get_cache, i)
|
||||
|
||||
for i3 = 1, #childrens do
|
||||
local list = childrens[i3].list
|
||||
local hit = false
|
||||
|
||||
for i2 = 1, #list do
|
||||
if list[i2] == path2 then
|
||||
hit = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not hit then
|
||||
table.insert(list, path2)
|
||||
end
|
||||
end
|
||||
|
||||
if not children.children[obj] then
|
||||
children.children[obj] = {
|
||||
list = {path2},
|
||||
children = {}
|
||||
}
|
||||
end
|
||||
|
||||
if not PathParseChildren[path2] then
|
||||
PathParseChildren[path2] = {
|
||||
list = {path2},
|
||||
children = {}
|
||||
}
|
||||
end
|
||||
|
||||
children = children.children[obj]
|
||||
table.insert(childrens, children)
|
||||
table.insert(childrens, PathParseChildren[path2])
|
||||
end
|
||||
end
|
||||
|
||||
if not no_translate then
|
||||
if get_cache[1] == "Primary" then
|
||||
get_cache[1] = "Primary_TFA"
|
||||
elseif get_cache[1] == "Secondary" then
|
||||
get_cache[1] = "Secondary_TFA"
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in ipairs(get_cache) do
|
||||
get_cache[k] = tonumber(v) or v
|
||||
end
|
||||
|
||||
_PathParseCache[cache_path] = {get_cache, path, fn or identity}
|
||||
return get_cache, path, fn or identity
|
||||
end
|
||||
|
||||
function TFA.GetStatPathRaw(path)
|
||||
local get_cache = PathParseCacheDirect[path]
|
||||
if get_cache ~= nil then return get_cache end
|
||||
|
||||
local t_stbl = string_Explode(".", path, false)
|
||||
|
||||
for k, v in ipairs(t_stbl) do
|
||||
t_stbl[k] = tonumber(v) or v
|
||||
end
|
||||
|
||||
PathParseCacheDirect[path] = t_stbl
|
||||
return t_stbl
|
||||
end
|
||||
|
||||
local GetStatPathRaw = TFA.GetStatPathRaw
|
||||
|
||||
do
|
||||
local function get(self, path)
|
||||
local value = self[path[1]]
|
||||
|
||||
for i = 2, #path do
|
||||
if not istable(value) then return end
|
||||
value = value[path[i]]
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
local function set(self, path, val)
|
||||
if #path == 1 then
|
||||
if self[path[1]] == nil then
|
||||
self[path[1]] = val
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local value = self[path[1]]
|
||||
|
||||
if value == nil then
|
||||
self[path[1]] = {}
|
||||
value = self[path[1]]
|
||||
end
|
||||
|
||||
for i = 2, #path - 1 do
|
||||
if not istable(value) then return end
|
||||
if value[path[i]] == nil then value[path[i]] = {} end
|
||||
value = value[path[i]]
|
||||
end
|
||||
|
||||
if istable(value) and value[path[#path]] == nil then
|
||||
value[path[#path]] = val
|
||||
elseif not istable(value) then
|
||||
print('[TFA Base] unable to fill gap for older version in meta structure of ' .. table_concat(path, '.'))
|
||||
end
|
||||
end
|
||||
|
||||
function TFA.FillMissingMetaValues(SWEP)
|
||||
for version = TFA.LatestDataVersion, 0, -1 do
|
||||
local mapping = TFA.DataVersionMapping[version]
|
||||
|
||||
if istable(mapping) then
|
||||
for i, data in ipairs(mapping) do
|
||||
local getVal = get(SWEP, GetStatPathRaw(data.new_path))
|
||||
|
||||
if getVal ~= nil then
|
||||
set(SWEP, GetStatPathRaw(data.old_path), data.downgrade(getVal))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
63
lua/tfa/modules/tfa_effects.lua
Normal file
63
lua/tfa/modules/tfa_effects.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
--[[
|
||||
| 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.Effects = TFA.Effects or {}
|
||||
local Effects = TFA.Effects
|
||||
|
||||
Effects.Overrides = Effects.Overrides or {}
|
||||
local Overrides = Effects.Overrides
|
||||
|
||||
function Effects.AddOverride(target, override)
|
||||
assert(type(target) == "string", "No target effect name or not a string")
|
||||
assert(type(override) == "string", "No override effect name or not a string")
|
||||
|
||||
Overrides[target] = override
|
||||
end
|
||||
|
||||
function Effects.GetOverride(target)
|
||||
if Overrides[target] then
|
||||
return Overrides[target]
|
||||
end
|
||||
|
||||
return target
|
||||
end
|
||||
|
||||
local util_Effect = util.Effect
|
||||
|
||||
function Effects.Create(effectName, effectData, allowOverride, ignorePredictionOrRecipientFilter)
|
||||
effectName = Effects.GetOverride(effectName)
|
||||
|
||||
util_Effect(effectName, effectData, allowOverride, ignorePredictionOrRecipientFilter)
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile("tfa/muzzleflash_base.lua")
|
||||
end
|
||||
92
lua/tfa/modules/tfa_envcheck.lua
Normal file
92
lua/tfa/modules/tfa_envcheck.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
--[[
|
||||
| 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 EmptyFunc = function() end
|
||||
|
||||
local debugInfoTbl = debug.getinfo(EmptyFunc)
|
||||
|
||||
local function checkEnv(plyIn)
|
||||
local printFunc = chat and chat.AddText or print
|
||||
|
||||
if game.SinglePlayer() then
|
||||
if CLIENT then
|
||||
local found = false
|
||||
for _, wepDefTable in ipairs(weapons.GetList()) do
|
||||
if wepDefTable.Spawnable and weapons.IsBasedOn(wepDefTable.ClassName, "tfa_gun_base") then
|
||||
found = true
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
printFunc("[TFA Base] Thank you for installing our weapons base! It appears that you have installed only the base itself, which does not include any weapons by default. Please install some weapons/packs that utilize TFA Base for full experience!")
|
||||
end
|
||||
end
|
||||
|
||||
local shortsrc = debugInfoTbl.short_src
|
||||
|
||||
if shortsrc:StartWith("addons") then -- legacy/unpacked addon
|
||||
local addonRootFolder = shortsrc:GetPathFromFilename():Replace("lua/tfa/modules/", "")
|
||||
|
||||
if not file.Exists(addonRootFolder .. ".git", "GAME") and not file.Exists(addonRootFolder .. "LICENSE", "GAME") then -- assume unpacked version by missing both .git and LICENSE files, which are ignored by gmad.exe
|
||||
printFunc("[TFA Base] You are using unpacked version of TFA Base.\nWe only provide support for Workshop and Git versions.")
|
||||
end
|
||||
end
|
||||
else
|
||||
local activeGamemode = engine.ActiveGamemode()
|
||||
local isRP = activeGamemode:find("rp")
|
||||
or activeGamemode:find("roleplay")
|
||||
or activeGamemode:find("serious")
|
||||
|
||||
if isRP and (SERVER or (IsValid(plyIn) and (plyIn:IsAdmin() or plyIn:IsSuperAdmin()))) then
|
||||
print("[TFA Base] You are running the base on DarkRP or DarkRP-derived gamemode. We can't guarantee that it will work correctly with any possible addons the server might have installed (especially the paid ones), so we don't provide support for RP gamemodes/servers. If you've encountered a conflict error with another addon, it's most likely that addon's fault. DO NOT CONTACT US ABOUT THAT!")
|
||||
|
||||
if TFA_BASE_VERSION <= 4.034 then -- seems to be common problem with SWRP servers
|
||||
printFunc("[TFA Base] You have installed both SV/SV2 and Reduxed versions of the base. Make sure you are using only one version at the same time.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
hook.Add("HUDPaint", "TFA_CheckEnv", function()
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
hook.Remove("HUDPaint", "TFA_CheckEnv")
|
||||
|
||||
checkEnv(ply)
|
||||
end)
|
||||
else
|
||||
hook.Add("InitPostEntity", "TFA_CheckEnv", checkEnv)
|
||||
end
|
||||
426
lua/tfa/modules/tfa_functions.lua
Normal file
426
lua/tfa/modules/tfa_functions.lua
Normal file
@@ -0,0 +1,426 @@
|
||||
--[[
|
||||
| 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 gas_cl_enabled = GetConVar("cl_tfa_fx_gasblur")
|
||||
local oldshell_cl_enabled = GetConVar("cl_tfa_legacy_shells")
|
||||
|
||||
local ScrW, ScrH = ScrW, ScrH
|
||||
|
||||
local BindToKeyTBL = {
|
||||
["ctrl"] = KEY_LCONTROL,
|
||||
["rctrl"] = KEY_LCONTROL,
|
||||
["alt"] = KEY_LALT,
|
||||
["ralt"] = KEY_RALT,
|
||||
["space"] = KEY_SPACE,
|
||||
["caps"] = KEY_CAPSLOCK,
|
||||
["capslock"] = KEY_CAPSLOCK,
|
||||
["tab"] = KEY_TAB,
|
||||
["back"] = KEY_BACKSPACE,
|
||||
["backspace"] = KEY_BACKSPACE,
|
||||
[0] = KEY_0,
|
||||
[1] = KEY_1,
|
||||
[2] = KEY_2,
|
||||
[3] = KEY_3,
|
||||
[4] = KEY_4,
|
||||
[5] = KEY_5,
|
||||
[6] = KEY_6,
|
||||
[7] = KEY_7,
|
||||
[8] = KEY_8,
|
||||
[9] = KEY_9
|
||||
}
|
||||
|
||||
local alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
for i = 1, string.len(alphabet) do
|
||||
local sstr = string.sub( alphabet, i, i )
|
||||
BindToKeyTBL[ sstr ] = string.byte( sstr ) - 86
|
||||
end
|
||||
|
||||
|
||||
local SoundChars = {
|
||||
["*"] = "STREAM",--Streams from the disc and rapidly flushed; good on memory, useful for music or one-off sounds
|
||||
["#"] = "DRYMIX",--Skip DSP, affected by music volume rather than sound volume
|
||||
["@"] = "OMNI",--Play the sound audible everywhere, like a radio voiceover or surface.PlaySound
|
||||
[">"] = "DOPPLER",--Left channel for heading towards the listener, Right channel for heading away
|
||||
["<"] = "DIRECTIONAL",--Left channel = front facing, Right channel = read facing
|
||||
["^"] = "DISTVARIANT",--Left channel = close, Right channel = far
|
||||
["("] = "SPATIALSTEREO_LOOP",--Position a stereo sound in 3D space; broken
|
||||
[")"] = "SPATIALSTEREO",--Same as above but actually useful
|
||||
["}"] = "FASTPITCH",--Low quality pitch shift
|
||||
["$"] = "CRITICAL",--Keep it around in memory
|
||||
["!"] = "SENTENCE",--NPC dialogue
|
||||
["?"] = "USERVOX"--Fake VOIP data; not that useful
|
||||
}
|
||||
local DefaultSoundChar = ")"
|
||||
|
||||
local SoundChannels = {
|
||||
["shoot"] = CHAN_WEAPON,
|
||||
["shootwrap"] = CHAN_STATIC,
|
||||
["misc"] = CHAN_AUTO
|
||||
}
|
||||
|
||||
|
||||
--Scope
|
||||
|
||||
local cv_rt = GetConVar("cl_tfa_3dscope_quality")
|
||||
|
||||
function TFA.RTQuality()
|
||||
if not cv_rt or cv_rt:GetInt() == -1 then
|
||||
return 0
|
||||
elseif cv_rt then
|
||||
return math.Clamp(cv_rt:GetInt(), 0, 3)
|
||||
end
|
||||
end
|
||||
|
||||
--Sensitivity
|
||||
|
||||
local ss, fov_og, resrat, fov_cv
|
||||
|
||||
fov_cv = GetConVar("fov_desired")
|
||||
function TFA.CalculateSensitivtyScale( fov_target, fov_src, screenscale )
|
||||
if not LocalPlayer():IsValid() then return 1 end
|
||||
resrat = ScrW() / ScrH()
|
||||
fov_og = fov_src or TFADUSKFOV or fov_cv:GetFloat()
|
||||
ss = screenscale or 1
|
||||
return math.atan( resrat * math.tan(math.rad( fov_target / 2 ) ) ) / math.atan( resrat * math.tan( math.rad( fov_og / 2) ) ) / ss
|
||||
end
|
||||
|
||||
--Ammo
|
||||
|
||||
local AmmoTypesByName = {}
|
||||
local AmmoTypesAdded = {}
|
||||
|
||||
function TFA.AddAmmo(id, name)
|
||||
if not AmmoTypesAdded[id] then
|
||||
AmmoTypesAdded[id] = true
|
||||
|
||||
game.AddAmmoType({
|
||||
name = id
|
||||
})
|
||||
end
|
||||
|
||||
if name and language then
|
||||
language.Add(id .. "_ammo", name)
|
||||
end
|
||||
|
||||
if name then
|
||||
AmmoTypesByName[name] = AmmoTypesByName[name] or id
|
||||
|
||||
return AmmoTypesByName[name]
|
||||
end
|
||||
|
||||
return id
|
||||
end
|
||||
|
||||
--Particles
|
||||
|
||||
function TFA.ParticleTracer( name,startPos,endPos,doWhiz,ent,att)
|
||||
if type(ent) ~= "number" and IsValid(ent) and ent.EntIndex then
|
||||
ent = ent:EntIndex()
|
||||
end
|
||||
if ent then
|
||||
att = att or -1
|
||||
return util.ParticleTracerEx(name,startPos,endPos,doWhiz,ent,att)
|
||||
else
|
||||
return util.ParticleTracerEx(name,startPos,endPos,doWhiz,0,-1)
|
||||
end
|
||||
end
|
||||
|
||||
--Binds
|
||||
|
||||
function TFA.BindToKey( bind, default )
|
||||
return BindToKeyTBL[ string.lower( bind ) ] or default or KEY_C
|
||||
end
|
||||
|
||||
--Sounds
|
||||
|
||||
function TFA.PatchSound( path, kind )
|
||||
local pathv
|
||||
local c = string.sub(path,1,1)
|
||||
|
||||
if SoundChars[c] then
|
||||
pathv = string.sub( path, 2, string.len(path) )
|
||||
else
|
||||
pathv = path
|
||||
end
|
||||
|
||||
local kindstr = kind
|
||||
if not kindstr then
|
||||
kindstr = DefaultSoundChar
|
||||
end
|
||||
if string.len(kindstr) > 1 then
|
||||
local found = false
|
||||
for k,v in pairs( SoundChars ) do
|
||||
if v == kind then
|
||||
kindstr = k
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
kindstr = DefaultSoundChar
|
||||
end
|
||||
end
|
||||
|
||||
return kindstr .. pathv
|
||||
end
|
||||
|
||||
function TFA.AddSound( name, channel, volume, level, pitch, wave, char )
|
||||
char = char or ""
|
||||
|
||||
local SoundData = {
|
||||
name = name,
|
||||
channel = channel or CHAN_AUTO,
|
||||
volume = volume or 1,
|
||||
level = level or 75,
|
||||
pitch = pitch or 100
|
||||
}
|
||||
|
||||
if char ~= "" then
|
||||
if type(wave) == "string" then
|
||||
wave = TFA.PatchSound(wave, char)
|
||||
elseif type(wave) == "table" then
|
||||
local patchWave = table.Copy(wave)
|
||||
|
||||
for k, v in pairs(patchWave) do
|
||||
patchWave[k] = TFA.PatchSound(v, char)
|
||||
end
|
||||
|
||||
wave = patchWave
|
||||
end
|
||||
end
|
||||
|
||||
SoundData.sound = wave
|
||||
|
||||
sound.Add(SoundData)
|
||||
end
|
||||
|
||||
function TFA.AddFireSound( id, path, wrap, kindv )
|
||||
kindv = kindv or ")"
|
||||
|
||||
TFA.AddSound(id, wrap and SoundChannels.shootwrap or SoundChannels.shoot, 1, 120, {97, 103}, path, kindv)
|
||||
end
|
||||
|
||||
function TFA.AddWeaponSound( id, path, kindv )
|
||||
kindv = kindv or ")"
|
||||
|
||||
TFA.AddSound(id, SoundChannels.misc, 1, 80, {97, 103}, path, kindv)
|
||||
end
|
||||
|
||||
--Frametime
|
||||
|
||||
--CVar Mediators
|
||||
function TFA.GetGasEnabled()
|
||||
local enabled = false
|
||||
|
||||
if gas_cl_enabled then
|
||||
enabled = gas_cl_enabled:GetBool()
|
||||
end
|
||||
|
||||
return enabled
|
||||
end
|
||||
|
||||
function TFA.GetLegacyShellsEnabled()
|
||||
local enabled = false
|
||||
|
||||
if oldshell_cl_enabled then
|
||||
enabled = oldshell_cl_enabled:GetBool()
|
||||
end
|
||||
|
||||
return enabled
|
||||
end
|
||||
|
||||
local ejectionsmoke_cl_enabled = GetConVar("cl_tfa_fx_ejectionsmoke")
|
||||
local muzzlesmoke_cl_enabled = GetConVar("cl_tfa_fx_muzzlesmoke")
|
||||
|
||||
function TFA.GetMZSmokeEnabled()
|
||||
local enabled = false
|
||||
|
||||
if muzzlesmoke_cl_enabled then
|
||||
enabled = muzzlesmoke_cl_enabled:GetBool()
|
||||
end
|
||||
|
||||
return enabled
|
||||
end
|
||||
|
||||
function TFA.GetEJSmokeEnabled()
|
||||
local enabled = false
|
||||
|
||||
if ejectionsmoke_cl_enabled then
|
||||
enabled = ejectionsmoke_cl_enabled:GetBool()
|
||||
end
|
||||
|
||||
return enabled
|
||||
end
|
||||
|
||||
local muzzleflashsmoke_cl_enabled = GetConVar("cl_tfa_fx_muzzleflashsmoke")
|
||||
|
||||
function TFA.GetMZFSmokeEnabled()
|
||||
local enabled = false
|
||||
|
||||
if muzzleflashsmoke_cl_enabled then
|
||||
enabled = muzzleflashsmoke_cl_enabled:GetBool()
|
||||
end
|
||||
|
||||
return enabled
|
||||
end
|
||||
|
||||
local ricofx_cl_enabled = GetConVar("cl_tfa_fx_impact_ricochet_enabled")
|
||||
|
||||
function TFA.GetRicochetEnabled()
|
||||
local enabled = false
|
||||
|
||||
if ricofx_cl_enabled then
|
||||
enabled = ricofx_cl_enabled:GetBool()
|
||||
end
|
||||
|
||||
return enabled
|
||||
end
|
||||
|
||||
--Local function for detecting TFA Base weapons.
|
||||
function TFA.PlayerCarryingTFAWeapon(ply)
|
||||
if not ply then
|
||||
if CLIENT then
|
||||
if LocalPlayer():IsValid() then
|
||||
ply = LocalPlayer()
|
||||
else
|
||||
return false, nil, nil
|
||||
end
|
||||
elseif game.SinglePlayer() then
|
||||
ply = Entity(1)
|
||||
else
|
||||
return false, nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
if not (IsValid(ply) and ply:IsPlayer() and ply:Alive()) then return end
|
||||
local wep = ply:GetActiveWeapon()
|
||||
|
||||
if IsValid(wep) then
|
||||
if (wep.IsTFAWeapon) then return true, ply, wep end
|
||||
|
||||
return false, ply, wep
|
||||
end
|
||||
|
||||
return false, ply, nil
|
||||
end
|
||||
|
||||
local cvar_scale = GetConVar("cl_tfa_hud_scale")
|
||||
local sscache = {}
|
||||
|
||||
function TFA.ScaleH(num)
|
||||
if not sscache[num] then
|
||||
sscache[num] = num * (ScrH() / 1080) * cvar_scale:GetFloat()
|
||||
end
|
||||
|
||||
return sscache[num]
|
||||
end
|
||||
|
||||
local function EmptyCache()
|
||||
sscache = {}
|
||||
end
|
||||
|
||||
cvars.AddChangeCallback("cl_tfa_hud_scale", EmptyCache, "TFA_ClearSScaleCache")
|
||||
hook.Add("OnScreenSizeChanged", "_TFA_DropSScaleCache", EmptyCache)
|
||||
|
||||
local sv_cheats = GetConVar("sv_cheats")
|
||||
local host_timescale = GetConVar("host_timescale")
|
||||
|
||||
function TFA.FrameTime()
|
||||
return engine.TickInterval() * game.GetTimeScale() * (sv_cheats:GetBool() and host_timescale:GetFloat() or 1)
|
||||
end
|
||||
|
||||
local buffer = {}
|
||||
|
||||
function TFA.tbezier(t, values, amount)
|
||||
if DLib then return math.tbezier(t, values) end
|
||||
|
||||
assert(isnumber(t), 't is not a number')
|
||||
assert(t >= 0 and t <= 1, '0 <= t <= 1!')
|
||||
assert(#values >= 2, 'at least two values must be provided')
|
||||
amount = amount or #values
|
||||
local a, b = values[1], values[2]
|
||||
|
||||
-- linear
|
||||
if amount == 2 then
|
||||
return a + (b - a) * t
|
||||
-- square
|
||||
elseif amount == 3 then
|
||||
return (1 - t) * (1 - t) * a + 2 * t * (1 - t) * b + t * t * values[3]
|
||||
-- cube
|
||||
elseif amount == 4 then
|
||||
return (1 - t) * (1 - t) * (1 - t) * a + 3 * t * (1 - t) * (1 - t) * b + 3 * t * t * (1 - t) * values[3] + t * t * t * values[4]
|
||||
end
|
||||
|
||||
for point = 1, amount do
|
||||
local point1 = values[point]
|
||||
local point2 = values[point + 1]
|
||||
if not point2 then break end
|
||||
buffer[point] = point1 + (point2 - point1) * t
|
||||
end
|
||||
|
||||
return TFA.tbezier(t, buffer, amount - 1)
|
||||
end
|
||||
|
||||
function TFA.Quintic(t)
|
||||
return t * t * t * (t * (t * 6 - 15) + 10)
|
||||
end
|
||||
|
||||
function TFA.Cosine(t)
|
||||
return (1 - math.cos(t * math.pi)) / 2
|
||||
end
|
||||
|
||||
function TFA.Sinusine(t)
|
||||
return (1 - math.sin(t * math.pi)) / 2
|
||||
end
|
||||
|
||||
function TFA.Cubic(t)
|
||||
return -2 * t * t * t + 3 * t * t
|
||||
end
|
||||
|
||||
function TFA.UnfoldBaseClass(tableInput, tableOutput)
|
||||
if tableOutput == nil then tableOutput = tableInput end
|
||||
if not istable(tableInput) or not istable(tableOutput) then return tableOutput end
|
||||
|
||||
if tableInput ~= tableOutput then
|
||||
for k, v in pairs(tableInput) do
|
||||
if tableOutput[k] == nil then
|
||||
tableOutput[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if istable(tableInput.BaseClass) then
|
||||
TFA.UnfoldBaseClass(tableInput.BaseClass, tableOutput)
|
||||
end
|
||||
|
||||
return tableOutput
|
||||
end
|
||||
701
lua/tfa/modules/tfa_hooks.lua
Normal file
701
lua/tfa/modules/tfa_hooks.lua
Normal file
@@ -0,0 +1,701 @@
|
||||
--[[
|
||||
| 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.INSPECTION_IMPULSE = 148
|
||||
TFA.BASH_IMPULSE = 149
|
||||
TFA.CYCLE_FIREMODE_IMPULSE = 150
|
||||
TFA.CYCLE_SAFETY_IMPULSE = 151
|
||||
|
||||
TFA.INSPECTION_IMPULSE_STRING = "148"
|
||||
TFA.BASH_IMPULSE_STRING = "149"
|
||||
TFA.CYCLE_FIREMODE_IMPULSE_STRING = "150"
|
||||
TFA.CYCLE_SAFETY_IMPULSE_STRING = "151"
|
||||
|
||||
local sp = game.SinglePlayer()
|
||||
local CurTime = CurTime
|
||||
local RealTime = RealTime
|
||||
|
||||
--[[
|
||||
Hook: PlayerFootstep
|
||||
Function: Weapon Logic
|
||||
Used For: Walk Cycle
|
||||
]]
|
||||
hook.Add("PlayerFootstep", "TFAWalkcycle", function(plyv)
|
||||
if sp and SERVER then
|
||||
BroadcastLua("Entity(" .. plyv:EntIndex() .. ").lastFootstep = " .. CurTime())
|
||||
elseif IsValid(plyv) then
|
||||
plyv.lastFootstep = CurTime()
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: PlayerPostThink
|
||||
Function: Weapon Logic
|
||||
Used For: Main weapon "think" logic
|
||||
]]
|
||||
--
|
||||
hook.Add("PlayerPostThink", "PlayerTickTFA", function(plyv)
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.PlayerThink and wepv.IsTFAWeapon then
|
||||
wepv:PlayerThink(plyv, plyv.last_tfa_think == engine.TickCount())
|
||||
plyv.last_tfa_think = engine.TickCount()
|
||||
end
|
||||
end)
|
||||
|
||||
if SERVER or not sp then
|
||||
hook.Add("FinishMove", "PlayerTickTFA", function(plyv)
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.IsTFAWeapon and wepv.PlayerThink then
|
||||
wepv:PlayerThink(plyv, not IsFirstTimePredicted())
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Remove("PlayerPostThink", "PlayerTickTFA")
|
||||
end
|
||||
|
||||
--[[
|
||||
Hook: Think
|
||||
Function: Weapon Logic for NPC
|
||||
User For: Calling SWEP:Think for NPCs manually
|
||||
]]
|
||||
--
|
||||
if SERVER then
|
||||
hook.Add("Think", "NPCTickTFA", function()
|
||||
hook.Run("TFA_NPCWeaponThink")
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Hook: Tick
|
||||
Function: Inspection mouse support
|
||||
Used For: Enables and disables screen clicker
|
||||
]]
|
||||
--
|
||||
if CLIENT then
|
||||
local tfablurintensity
|
||||
local its_old = 0
|
||||
local ScreenClicker = false
|
||||
local cl_tfa_inspect_hide = GetConVar("cl_tfa_inspect_hide")
|
||||
local cl_drawhud = GetConVar("cl_drawhud")
|
||||
|
||||
hook.Add("Tick", "TFAInspectionScreenClicker", function()
|
||||
tfablurintensity = 0
|
||||
|
||||
if LocalPlayer():IsValid() and LocalPlayer():GetActiveWeapon():IsValid() then
|
||||
local w = LocalPlayer():GetActiveWeapon()
|
||||
|
||||
if w.IsTFAWeapon then
|
||||
tfablurintensity = w:GetCustomizing() and 1 or 0
|
||||
end
|
||||
end
|
||||
|
||||
if tfablurintensity > its_old and not ScreenClicker and not cl_tfa_inspect_hide:GetBool() and cl_drawhud:GetBool() then
|
||||
gui.EnableScreenClicker(true)
|
||||
ScreenClicker = true
|
||||
elseif tfablurintensity < its_old and ScreenClicker then
|
||||
gui.EnableScreenClicker(false)
|
||||
ScreenClicker = false
|
||||
end
|
||||
|
||||
its_old = tfablurintensity
|
||||
end)
|
||||
|
||||
hook.Add("Think", "TFABase_PlayerThinkCL", function()
|
||||
local ply = LocalPlayer()
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
local weapon = ply:GetActiveWeapon()
|
||||
|
||||
if IsValid(weapon) and weapon.IsTFAWeapon then
|
||||
if weapon.PlayerThinkCL then
|
||||
weapon:PlayerThinkCL(ply)
|
||||
end
|
||||
|
||||
if sp then
|
||||
net.Start("tfaSDLP", true)
|
||||
net.WriteBool(ply:ShouldDrawLocalPlayer())
|
||||
net.SendToServer()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Hook: AllowPlayerPickup
|
||||
Function: Prop holding
|
||||
Used For: Records last held object
|
||||
]]
|
||||
--
|
||||
hook.Add("AllowPlayerPickup", "TFAPickupDisable", function(plyv, ent)
|
||||
plyv:SetNW2Entity("LastHeldEntity", ent)
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: PlayerBindPress
|
||||
Function: Intercept Keybinds
|
||||
Used For: Alternate attack, inspection, shotgun interrupts, and more
|
||||
]]
|
||||
--
|
||||
local cv_cm = GetConVar("sv_tfa_cmenu")
|
||||
local cv_cm_key = GetConVar("sv_tfa_cmenu_key")
|
||||
local keyv
|
||||
|
||||
local function GetInspectionKey()
|
||||
if cv_cm_key and cv_cm_key:GetInt() >= 0 then
|
||||
keyv = cv_cm_key:GetInt()
|
||||
else
|
||||
keyv = TFA.BindToKey(input.LookupBinding("+menu_context", true) or "c", KEY_C)
|
||||
end
|
||||
|
||||
return keyv
|
||||
end
|
||||
|
||||
local function TFAContextBlock()
|
||||
local plyv = LocalPlayer()
|
||||
|
||||
if not plyv:IsValid() or GetViewEntity() ~= plyv then return end
|
||||
|
||||
if plyv:InVehicle() and not plyv:GetAllowWeaponsInVehicle() then return end
|
||||
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
if not IsValid(wepv) then return end
|
||||
|
||||
if plyv:GetInfoNum("cl_tfa_keys_customize", 0) > 0 then return end
|
||||
|
||||
if GetInspectionKey() == TFA.BindToKey(input.LookupBinding("+menu_context", true) or "c", KEY_C) and wepv.ToggleInspect and cv_cm:GetBool() and not plyv:KeyDown(IN_USE) then return false end
|
||||
end
|
||||
|
||||
hook.Add("ContextMenuOpen", "TFAContextBlock", TFAContextBlock)
|
||||
|
||||
if CLIENT then
|
||||
local kd_old = false
|
||||
|
||||
local cl_tfa_keys_customize
|
||||
|
||||
local function TFAKPThink()
|
||||
local plyv = LocalPlayer()
|
||||
if not plyv:IsValid() then return end
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
if not IsValid(wepv) then return end
|
||||
|
||||
if not cl_tfa_keys_customize then
|
||||
cl_tfa_keys_customize = GetConVar("cl_tfa_keys_customize")
|
||||
end
|
||||
|
||||
if cl_tfa_keys_customize:GetBool() then return end
|
||||
|
||||
local key = GetInspectionKey()
|
||||
local kd = input.IsKeyDown(key)
|
||||
|
||||
if IsValid(vgui.GetKeyboardFocus()) then
|
||||
kd = false
|
||||
end
|
||||
|
||||
if kd ~= kd_old and kd and cv_cm:GetBool() and not plyv:KeyDown(IN_USE) then
|
||||
RunConsoleCommand("impulse", tostring(TFA.INSPECTION_IMPULSE))
|
||||
end
|
||||
|
||||
kd_old = kd
|
||||
end
|
||||
|
||||
hook.Add("Think", "TFAInspectionMenu", TFAKPThink)
|
||||
end
|
||||
|
||||
local cv_lr = GetConVar("sv_tfa_reloads_legacy")
|
||||
local reload_threshold = 0.3
|
||||
|
||||
local sv_cheats = GetConVar("sv_cheats")
|
||||
local host_timescale = GetConVar("host_timescale")
|
||||
|
||||
local band = bit.band
|
||||
local bxor = bit.bxor
|
||||
local bnot = bit.bnot
|
||||
local GetTimeScale = game.GetTimeScale
|
||||
local IN_ATTACK2 = IN_ATTACK2
|
||||
local IN_RELOAD = IN_RELOAD
|
||||
|
||||
local function FinishMove(ply, cmovedata)
|
||||
if ply:InVehicle() and not ply:GetAllowWeaponsInVehicle() then return end
|
||||
|
||||
local wepv = ply:GetActiveWeapon()
|
||||
if not IsValid(wepv) or not wepv.IsTFAWeapon then return end
|
||||
|
||||
wepv:TFAFinishMove(ply, cmovedata:GetVelocity(), cmovedata)
|
||||
|
||||
local impulse = cmovedata:GetImpulseCommand()
|
||||
|
||||
if impulse == TFA.INSPECTION_IMPULSE then
|
||||
wepv:ToggleInspect()
|
||||
elseif impulse == TFA.CYCLE_FIREMODE_IMPULSE and wepv:GetStatus() == TFA.Enum.STATUS_IDLE and wepv:GetStatL("SelectiveFire") then
|
||||
wepv:CycleFireMode()
|
||||
elseif impulse == TFA.CYCLE_SAFETY_IMPULSE and wepv:GetStatus() == TFA.Enum.STATUS_IDLE then
|
||||
wepv:CycleSafety()
|
||||
end
|
||||
|
||||
local BashImpulse = cmovedata:GetImpulseCommand() == TFA.BASH_IMPULSE
|
||||
ply:TFA_SetZoomKeyDown(BashImpulse) -- this may or may not work
|
||||
|
||||
if wepv.SetBashImpulse then
|
||||
wepv:SetBashImpulse(BashImpulse)
|
||||
end
|
||||
|
||||
if cmovedata:GetImpulseCommand() == 100 and (wepv:GetStatL("FlashlightAttachmentName") ~= nil or wepv:GetStatL("FlashlightAttachment", 0) > 0) then
|
||||
wepv:ToggleFlashlight()
|
||||
end
|
||||
|
||||
local lastButtons = wepv:GetDownButtons()
|
||||
local buttons = cmovedata:GetButtons()
|
||||
local stillPressed = band(lastButtons, buttons)
|
||||
local changed = bxor(lastButtons, buttons)
|
||||
local pressed = band(changed, bnot(lastButtons), buttons)
|
||||
local depressed = band(changed, lastButtons, bnot(buttons))
|
||||
|
||||
wepv:SetDownButtons(buttons)
|
||||
wepv:SetLastPressedButtons(pressed)
|
||||
|
||||
local time = CurTime()
|
||||
|
||||
local cl_tfa_ironsights_toggle = (ply:GetInfoNum("cl_tfa_ironsights_toggle", 0) or 0) >= 1
|
||||
local cl_tfa_ironsights_resight = (ply:GetInfoNum("cl_tfa_ironsights_resight", 0) or 0) >= 1
|
||||
local cl_tfa_ironsights_responsive = (ply:GetInfoNum("cl_tfa_ironsights_responsive", 0) or 0) >= 1
|
||||
local cl_tfa_ironsights_responsive_timer = ply:GetInfoNum("cl_tfa_ironsights_responsive_timer", 0.175) or 0.175
|
||||
|
||||
local scale_dividier = GetTimeScale() * (sv_cheats:GetBool() and host_timescale:GetFloat() or 1)
|
||||
|
||||
if wepv:GetStatL("Secondary.IronSightsEnabled", false) and not wepv:IsSafety() then
|
||||
if band(changed, IN_ATTACK2) == IN_ATTACK2 then
|
||||
local deltaPress = (time - wepv:GetLastIronSightsPressed()) / scale_dividier
|
||||
|
||||
-- pressing for first time
|
||||
if not wepv:GetIronSightsRaw() and band(pressed, IN_ATTACK2) == IN_ATTACK2 then
|
||||
wepv:SetIronSightsRaw(true)
|
||||
wepv:SetLastIronSightsPressed(time)
|
||||
elseif wepv:GetIronSightsRaw() and
|
||||
((cl_tfa_ironsights_toggle or cl_tfa_ironsights_responsive) and band(pressed, IN_ATTACK2) == IN_ATTACK2 or
|
||||
not cl_tfa_ironsights_toggle and not cl_tfa_ironsights_responsive and band(depressed, IN_ATTACK2) == IN_ATTACK2)
|
||||
then
|
||||
-- get out of iron sights
|
||||
wepv:SetIronSightsRaw(false)
|
||||
wepv:SetLastIronSightsPressed(-1)
|
||||
elseif wepv:GetIronSightsRaw() and cl_tfa_ironsights_responsive and band(depressed, IN_ATTACK2) == IN_ATTACK2 and deltaPress > cl_tfa_ironsights_responsive_timer then
|
||||
-- we depressed IN_ATTACK2 with it were being held down
|
||||
wepv:SetIronSightsRaw(false)
|
||||
wepv:SetLastIronSightsPressed(-1)
|
||||
end
|
||||
elseif wepv:GetIronSightsRaw() and not cl_tfa_ironsights_resight and (not TFA.Enum.IronStatus[wepv:GetStatus()] or wepv:GetSprinting()) then
|
||||
wepv:SetIronSightsRaw(false)
|
||||
wepv:SetLastIronSightsPressed(-1)
|
||||
end
|
||||
end
|
||||
|
||||
if
|
||||
band(depressed, IN_RELOAD) == IN_RELOAD and
|
||||
not cv_lr:GetBool()
|
||||
and band(buttons, IN_USE) == 0
|
||||
and time <= (wepv:GetLastReloadPressed() + reload_threshold * scale_dividier)
|
||||
then
|
||||
wepv:SetLastReloadPressed(-1)
|
||||
wepv:Reload(true)
|
||||
elseif band(pressed, IN_RELOAD) == IN_RELOAD then
|
||||
wepv:SetLastReloadPressed(time)
|
||||
elseif band(buttons, IN_RELOAD) ~= 0 and band(buttons, IN_USE) == 0 and time > (wepv:GetLastReloadPressed() + reload_threshold * scale_dividier) then
|
||||
wepv:CheckAmmo()
|
||||
end
|
||||
|
||||
if BashImpulse then
|
||||
if wepv.AltAttack then
|
||||
wepv:AltAttack()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("FinishMove", "TFAFinishMove", FinishMove)
|
||||
|
||||
local function TFABashZoom(plyv, cusercmd)
|
||||
if plyv:InVehicle() and not plyv:GetAllowWeaponsInVehicle() then return end
|
||||
|
||||
if plyv:GetInfoNum("cl_tfa_keys_bash", 0) ~= 0 then
|
||||
if (sp or CLIENT) and plyv.tfa_bash_hack then
|
||||
cusercmd:SetImpulse(TFA.BASH_IMPULSE)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local zoom = cusercmd:KeyDown(IN_ZOOM)
|
||||
|
||||
if zoom then
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.IsTFAWeapon and wepv.AltAttack then
|
||||
cusercmd:RemoveKey(IN_ZOOM)
|
||||
cusercmd:SetImpulse(TFA.BASH_IMPULSE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("StartCommand", "TFABashZoom", TFABashZoom)
|
||||
|
||||
--[[
|
||||
Hook: PlayerSpawn
|
||||
Function: Extinguishes players, zoom cleanup
|
||||
Used For: Fixes incendiary bullets post-respawn
|
||||
]]
|
||||
--
|
||||
hook.Add("PlayerSpawn", "TFAExtinguishQOL", function(plyv)
|
||||
if IsValid(plyv) and plyv:IsOnFire() then
|
||||
plyv:Extinguish()
|
||||
end
|
||||
end)
|
||||
|
||||
local sv_tfa_weapon_weight = GetConVar("sv_tfa_weapon_weight")
|
||||
|
||||
--[[
|
||||
Hook: SetupMove
|
||||
Function: Modify movement speed
|
||||
Used For: Weapon slowdown, ironsights slowdown
|
||||
]]
|
||||
--
|
||||
hook.Add("SetupMove", "tfa_setupmove", function(plyv, movedata, commanddata)
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.IsTFAWeapon then
|
||||
local speedmult = Lerp(wepv:GetIronSightsProgress(), sv_tfa_weapon_weight:GetBool() and wepv:GetStatL("RegularMoveSpeedMultiplier", 1), wepv:GetStatL("AimingDownSightsSpeedMultiplier", 1))
|
||||
movedata:SetMaxClientSpeed(movedata:GetMaxClientSpeed() * speedmult)
|
||||
commanddata:SetForwardMove(commanddata:GetForwardMove() * speedmult)
|
||||
commanddata:SetSideMove(commanddata:GetSideMove() * speedmult)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: HUDShouldDraw
|
||||
Function: Weapon HUD
|
||||
Used For: Hides default HUD
|
||||
]]
|
||||
--
|
||||
local cv_he = GetConVar("cl_tfa_hud_enabled")
|
||||
|
||||
if CLIENT then
|
||||
local TFAHudHide = {
|
||||
CHudAmmo = true,
|
||||
CHudSecondaryAmmo = true
|
||||
}
|
||||
|
||||
hook.Add("HUDShouldDraw", "tfa_hidehud", function(name)
|
||||
if (TFAHudHide[name] and cv_he:GetBool()) then
|
||||
local ictfa = TFA.PlayerCarryingTFAWeapon()
|
||||
if ictfa then return false end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Hook: InitPostEntity
|
||||
Function: Patches or removes other hooks that breaking or changing behavior of our weapons in a negative way
|
||||
Used For: Fixing our stuff
|
||||
]]
|
||||
--
|
||||
|
||||
local function FixInvalidPMHook()
|
||||
if not CLIENT then return end
|
||||
|
||||
local hookTable = hook.GetTable()
|
||||
|
||||
if hookTable["PostDrawViewModel"] and hookTable["PostDrawViewModel"]["Set player hand skin"] then
|
||||
local targetFunc = hookTable["PostDrawViewModel"]["Set player hand skin"]
|
||||
if not targetFunc then return end
|
||||
|
||||
local cv_shouldfix = GetConVar("cl_tfa_fix_pmhands_hook") or CreateClientConVar("cl_tfa_fix_pmhands_hook", "1", true, false, "Fix hands skin hook for CaptainBigButt's (and others) playermodels (Change requires map restart)")
|
||||
|
||||
if not cv_shouldfix:GetBool() then return end
|
||||
|
||||
print("[TFA Base] The playermodels you have installed breaks the automatic rig parenting for Insurgency and CS:GO weapons. The fix is applied but it's more of a band-aid, the solution would be to either fix this properly on author's side or to uninstall the addon.")
|
||||
|
||||
if CLIENT and debug and debug.getinfo then
|
||||
local funcPath = debug.getinfo(targetFunc).short_src
|
||||
|
||||
print("Type whereis " .. funcPath .. " in console to see the conflicting addon.")
|
||||
end
|
||||
|
||||
hook.Remove("PostDrawViewModel", "Set player hand skin")
|
||||
hook.Add("PreDrawPlayerHands", "Set player hand skin BUT FIXED", function(hands, vm, ply, weapon)
|
||||
if hands:SkinCount() == ply:SkinCount() then
|
||||
hands:SetSkin(ply:GetSkin())
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local function PatchSiminovSniperHook()
|
||||
if not CLIENT then return end -- that hook is clientside only
|
||||
|
||||
local hookTable = hook.GetTable()
|
||||
|
||||
if hookTable["CreateMove"] and hookTable["CreateMove"]["SniperCreateMove"] then
|
||||
local SniperCreateMove = hookTable["CreateMove"]["SniperCreateMove"] -- getting the original function
|
||||
if not SniperCreateMove then return end
|
||||
|
||||
local cv_shouldfix = GetConVar("cl_tfa_fix_siminov_scopes") or CreateClientConVar("cl_tfa_fix_siminov_scopes", "1", true, false, "Patch Siminov's sniper overlay hook with weapon base check (Change requires map restart)")
|
||||
|
||||
if not cv_shouldfix:GetBool() then return end
|
||||
|
||||
local PatchedSniperCreateMove = function(cmd) -- wrapping their function with our check
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if IsValid(ply) and IsValid(ply:GetActiveWeapon()) and ply:GetActiveWeapon().IsTFAWeapon then
|
||||
return
|
||||
end
|
||||
|
||||
SniperCreateMove(cmd)
|
||||
end
|
||||
|
||||
hook.Remove("CreateMove", "SniperCreateMove") -- removing original hook
|
||||
hook.Add("CreateMove", "SniperCreateMove_PatchedByTFABase", PatchedSniperCreateMove) -- creating new hook with wrap
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity", "tfa_unfuckeverything", function()
|
||||
FixInvalidPMHook()
|
||||
PatchSiminovSniperHook()
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: PlayerSwitchFlashlight
|
||||
Function: Flashlight toggle
|
||||
Used For: Switching flashlight on weapon and blocking HEV flashlight
|
||||
]]
|
||||
--
|
||||
hook.Add("PlayerSwitchFlashlight", "tfa_toggleflashlight", function(plyv, toEnable)
|
||||
if CLIENT then return end -- this is serverside hook GO AWAY
|
||||
-- fuck you source
|
||||
-- where is fucking prediction??!??!?!?/
|
||||
|
||||
if not IsValid(plyv) or not toEnable then return end -- allow disabling HEV flashlight
|
||||
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.IsTFAWeapon and (wepv:GetStatL("FlashlightAttachmentName") ~= nil or wepv:GetStatL("FlashlightAttachment", 0) > 0) then
|
||||
-- wepv:ToggleFlashlight()
|
||||
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: SetupMove
|
||||
Function: Update players NW2 variable
|
||||
Used For: Walking animation NW2 var
|
||||
]]
|
||||
--
|
||||
hook.Add("SetupMove", "tfa_checkforplayerwalking", function(plyv, mvdatav, cmdv)
|
||||
if not IsValid(plyv) or not mvdatav then return end
|
||||
|
||||
if mvdatav:GetForwardSpeed() ~= 0 or mvdatav:GetSideSpeed() ~= 0 then
|
||||
if not plyv:GetNW2Bool("TFA_IsWalking") then
|
||||
plyv:SetNW2Bool("TFA_IsWalking", true)
|
||||
end
|
||||
elseif plyv:GetNW2Bool("TFA_IsWalking") then
|
||||
plyv:SetNW2Bool("TFA_IsWalking", false)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: PreDrawOpaqueRenderables
|
||||
Function: Calls SWEP:PreDrawOpaqueRenderables()
|
||||
Used For: whatever draw stuff you need lol
|
||||
]]
|
||||
--
|
||||
hook.Add("PreDrawOpaqueRenderables", "tfaweaponspredrawopaque", function()
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
local wepv = v:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.IsTFAWeapon and wepv.PreDrawOpaqueRenderables then
|
||||
wepv:PreDrawOpaqueRenderables()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: PlayerSay
|
||||
Function: Simple chat command
|
||||
Used For: Allowing users to open TFA's Steam group with a chat command
|
||||
]]
|
||||
--
|
||||
if SERVER then
|
||||
hook.Add("PlayerSay", "TFAJoinGroupChat", function(plyv, text, tc)
|
||||
if string.Trim(text) == "!jointfa" then
|
||||
net.Start("TFAJoinGroupPopup")
|
||||
net.Send(plyv)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Hook: PreDrawViewModel
|
||||
Function: Calculating viewmodel offsets
|
||||
Used For: Viewmodel sway, offset and flip
|
||||
]]
|
||||
--
|
||||
if CLIENT then
|
||||
local st_old, host_ts, cheats, vec, ang
|
||||
host_ts = GetConVar("host_timescale")
|
||||
cheats = GetConVar("sv_cheats")
|
||||
vec = Vector()
|
||||
ang = Angle()
|
||||
|
||||
local IsGameUIVisible = gui and gui.IsGameUIVisible
|
||||
|
||||
hook.Add("PreDrawViewModel", "TFACalculateViewmodel", function(vm, plyv, wepv)
|
||||
if not IsValid(wepv) or not wepv.IsTFAWeapon then return end
|
||||
|
||||
wepv:UpdateEngineBob()
|
||||
|
||||
local st = SysTime()
|
||||
st_old = st_old or st
|
||||
|
||||
local delta = st - st_old
|
||||
st_old = st
|
||||
|
||||
if sp and IsGameUIVisible and IsGameUIVisible() then return end
|
||||
|
||||
delta = delta * game.GetTimeScale() * (cheats:GetBool() and host_ts:GetFloat() or 1)
|
||||
|
||||
wepv:Sway(vec, ang, delta)
|
||||
wepv:CalculateViewModelOffset(delta)
|
||||
wepv:CalculateViewModelFlip()
|
||||
|
||||
wepv:UpdateProjectedTextures(true)
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Hook: EntityTakeDamage
|
||||
Function: Applies physics damage to Combine Turrets
|
||||
Used For: Knocking up Combine Turrets with TFA Base weapons
|
||||
]]
|
||||
--
|
||||
hook.Add("EntityTakeDamage", "TFA_TurretPhysics", function(entv, dmg)
|
||||
if entv:GetClass() == "npc_turret_floor" then
|
||||
entv:TakePhysicsDamage(dmg)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: HUDPaint
|
||||
Function: Calls another hook
|
||||
Used For: Hook that notifies when player is fully loaded.
|
||||
]]
|
||||
--
|
||||
hook.Add("HUDPaint", "TFA_TRIGGERCLIENTLOAD", function()
|
||||
if LocalPlayer():IsValid() then
|
||||
hook.Remove("HUDPaint", "TFA_TRIGGERCLIENTLOAD")
|
||||
|
||||
hook.Run("TFA_ClientLoad")
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
Hook: InitPostEntity
|
||||
Function: Wraps SWEP:Think functions
|
||||
Used For: Patching old, broken weapons that override SWEP:Think without calling baseclass
|
||||
]]
|
||||
--
|
||||
local PatchClassBlacklisted = {
|
||||
tfa_gun_base = true,
|
||||
tfa_melee_base = true,
|
||||
tfa_bash_base = true,
|
||||
tfa_bow_base = true,
|
||||
tfa_knife_base = true,
|
||||
tfa_nade_base = true,
|
||||
tfa_sword_advanced_base = true,
|
||||
tfa_cssnade_base = true,
|
||||
tfa_shotty_base = true,
|
||||
tfa_akimbo_base = true,
|
||||
tfa_3dbash_base = true,
|
||||
tfa_3dscoped_base = true,
|
||||
tfa_scoped_base = true,
|
||||
}
|
||||
|
||||
local cv_shouldpatchthink = GetConVar("sv_tfa_backcompat_patchswepthink") or CreateConVar("sv_tfa_backcompat_patchswepthink", "1", CLIENT and {FCVAR_REPLICATED} or {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY}, "Enable patching of old weapons that override SWEP:Think function to work with newer version of the base?\n\tDISABLING THIS IS NOT RECOMMENDED AND MAY LEAD TO NON-FUNCTIONING WEAPONS!")
|
||||
|
||||
hook.Add("InitPostEntity", "TFA_PatchThinkOverride", function()
|
||||
if not cv_shouldpatchthink:GetBool() then return end
|
||||
if not debug or not debug.getinfo then return end
|
||||
|
||||
for _, wepRefTable in ipairs(weapons.GetList()) do
|
||||
local class = wepRefTable.ClassName
|
||||
|
||||
if PatchClassBlacklisted[class] or not weapons.IsBasedOn(class, "tfa_gun_base") then
|
||||
goto THINK1FOUND
|
||||
end
|
||||
|
||||
local wepRealTbl = weapons.GetStored(class)
|
||||
|
||||
if wepRealTbl.Think then
|
||||
local info = debug.getinfo(wepRealTbl.Think, "S")
|
||||
if not info or not info.linedefined or not info.lastlinedefined then goto THINK1FOUND end
|
||||
|
||||
local src = info.short_src
|
||||
|
||||
if src:StartWith("addons/") then
|
||||
src = src:gsub("^addons/[^%0:/]+/", "")
|
||||
end
|
||||
|
||||
local luafile = file.Read(src:sub(5), "LUA")
|
||||
if not luafile or luafile == "" then goto THINK1FOUND end
|
||||
|
||||
local lua = luafile:gsub("\r\n","\n"):gsub("\r","\n"):Split("\n")
|
||||
|
||||
for i = info.linedefined, info.lastlinedefined do
|
||||
local line = lua[i]
|
||||
|
||||
if not line or line:find("BaseClass%s*.%s*Think%s*%(") then
|
||||
goto THINK1FOUND
|
||||
end
|
||||
end
|
||||
|
||||
print(("[TFA Base] Weapon %s (%s) is overriding SWEP:Think() function without calling baseclass!"):format(wepRefTable.ClassName, info.short_src))
|
||||
|
||||
local BaseClass = baseclass.Get(wepRealTbl.Base)
|
||||
|
||||
wepRealTbl.ThinkFuncUnwrapped = wepRealTbl.ThinkFuncUnwrapped or wepRealTbl.Think
|
||||
function wepRealTbl:Think(...)
|
||||
self:ThinkFuncUnwrapped(...)
|
||||
|
||||
return BaseClass.Think(self, ...)
|
||||
end
|
||||
end
|
||||
|
||||
::THINK1FOUND::
|
||||
end
|
||||
end)
|
||||
253
lua/tfa/modules/tfa_keybinds.lua
Normal file
253
lua/tfa/modules/tfa_keybinds.lua
Normal file
@@ -0,0 +1,253 @@
|
||||
--[[
|
||||
| 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._KeyBindTable = TFA._KeyBindTable or {}
|
||||
local KeyBindTable = TFA._KeyBindTable
|
||||
|
||||
local cv_prefix = "cl_tfa_keys_"
|
||||
|
||||
local sp = game.SinglePlayer()
|
||||
|
||||
if sp then -- THANK YOU GARRY FOR HIGH QUALITY PREDICTION IN SINGLEPLAYER
|
||||
if SERVER then
|
||||
util.AddNetworkString("TFA_KB_State")
|
||||
util.AddNetworkString("TFA_KB_Think")
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
net.Receive("TFA_KB_State", function()
|
||||
local ply = LocalPlayer()
|
||||
|
||||
local bind = net.ReadString()
|
||||
local state = net.ReadBool()
|
||||
|
||||
local data = KeyBindTable[bind]
|
||||
|
||||
if data and data.state ~= state then
|
||||
data.state = state
|
||||
|
||||
if state then
|
||||
data.onpress(ply)
|
||||
else
|
||||
data.onrelease(ply)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("TFA_KB_Think", function()
|
||||
local ply = LocalPlayer()
|
||||
|
||||
local bind = net.ReadString()
|
||||
|
||||
local data = KeyBindTable[bind]
|
||||
|
||||
if data and data.think and data.state then
|
||||
data.think(ply)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local function empty()
|
||||
end
|
||||
|
||||
function TFA.RegisterKeyBind(data_in)
|
||||
assert(type(data_in) == "table", "Data must be a table!")
|
||||
assert(data_in.bind and type(data_in.bind) == "string", "Invalid bind name!")
|
||||
-- assert(not TFA._KeyBindTable[data.bind], "Keybind already registered!")
|
||||
|
||||
local data = table.Copy(data_in)
|
||||
|
||||
if not data.onpress then
|
||||
data.onpress = empty
|
||||
elseif type(data.onpress) ~= "function" then
|
||||
error("data.onpress - function expected, got " .. type(data.onpress))
|
||||
end
|
||||
|
||||
if not data.onrelease then
|
||||
data.onrelease = empty
|
||||
elseif type(data.onrelease) ~= "function" then
|
||||
error("data.onrelease - function expected, got " .. type(data.onrelease))
|
||||
end
|
||||
|
||||
data.state = false
|
||||
|
||||
if CLIENT and GetConVar(cv_prefix .. data.bind) == nil then
|
||||
CreateClientConVar(cv_prefix .. data.bind, 0, true, true, data.desc)
|
||||
end
|
||||
|
||||
hook.Add("PlayerButtonDown", "TFA_KB_KeyDown_" .. data.bind, function(ply, button)
|
||||
if not IsFirstTimePredicted() then return end
|
||||
local cv_key = ply:GetInfoNum(cv_prefix .. data.bind, 0)
|
||||
|
||||
if cv_key > 0 and cv_key == button and not data.state then
|
||||
data.state = true
|
||||
data.onpress(ply)
|
||||
|
||||
if sp and SERVER then
|
||||
net.Start("TFA_KB_State", true)
|
||||
net.WriteString(data.bind)
|
||||
net.WriteBool(data.state)
|
||||
net.Send(ply)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerButtonUp", "TFA_KB_KeyUp_" .. data.bind, function(ply, button)
|
||||
if not IsFirstTimePredicted() then return end
|
||||
local cv_key = ply:GetInfoNum(cv_prefix .. data.bind, 0)
|
||||
|
||||
if cv_key > 0 and cv_key == button and data.state then
|
||||
data.state = false
|
||||
data.onrelease(ply)
|
||||
|
||||
if sp and SERVER then
|
||||
net.Start("TFA_KB_State", true)
|
||||
net.WriteString(data.bind)
|
||||
net.WriteBool(data.state)
|
||||
net.Send(ply)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Remove("PlayerPostThink", "TFA_KB_Think_" .. data.bind)
|
||||
|
||||
if data.think and type(data.think) == "function" then
|
||||
hook.Add("PlayerPostThink", "TFA_KB_Think_" .. data.bind, function(ply)
|
||||
if data.state then
|
||||
data.think(ply)
|
||||
|
||||
if sp and SERVER then
|
||||
net.Start("TFA_KB_Think", true)
|
||||
net.WriteString(data.bind)
|
||||
net.Send(ply)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
KeyBindTable[data.bind] = data
|
||||
end
|
||||
|
||||
if CLIENT then -- Populate spawnmenu settings with registered keybinds
|
||||
local function tfaOptionKeys(panel)
|
||||
panel:Help("#tfa.keybinds.help.bind")
|
||||
panel:Help("#tfa.keybinds.help.bound")
|
||||
panel:Help("#tfa.keybinds.help.unbind")
|
||||
panel:Help("")
|
||||
|
||||
for _, data in pairs(KeyBindTable) do
|
||||
local cv = GetConVar(cv_prefix .. data.bind)
|
||||
|
||||
if cv then
|
||||
panel:Help("#tfa.keybind." .. data.bind)
|
||||
|
||||
local binder = vgui.Create("DBinder")
|
||||
|
||||
binder:SetValue(cv:GetInt())
|
||||
|
||||
function binder:OnChange(newcode)
|
||||
cv:SetInt(newcode)
|
||||
end
|
||||
|
||||
panel:AddItem(binder)
|
||||
panel:Help("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("PopulateToolMenu", "TFA_AddKeyBinds", function()
|
||||
spawnmenu.AddToolMenuOption("Utilities", "TFA SWEP Base Settings", "TFASwepBaseKeybinds", "#tfa.smsettings.keybinds", "", "", tfaOptionKeys)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Default keybinds
|
||||
TFA.RegisterKeyBind({
|
||||
bind = "bash",
|
||||
|
||||
onpress = function(plyv)
|
||||
if not plyv:IsValid() then return end
|
||||
|
||||
plyv.tfa_bash_hack = true
|
||||
end,
|
||||
|
||||
onrelease = function(plyv)
|
||||
if not plyv:IsValid() then return end
|
||||
|
||||
plyv.tfa_bash_hack = false
|
||||
end
|
||||
})
|
||||
|
||||
TFA.RegisterKeyBind({
|
||||
bind = "customize",
|
||||
onpress = CLIENT and function(plyv)
|
||||
if not plyv:IsValid() then return end
|
||||
|
||||
RunConsoleCommand("impulse", TFA.INSPECTION_IMPULSE_STRING)
|
||||
end
|
||||
})
|
||||
|
||||
TFA.RegisterKeyBind({
|
||||
bind = "inspect",
|
||||
onpress = function(plyv)
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if (IsValid(wepv) and wepv.GetStat) and (wepv:GetActivityEnabled(ACT_VM_FIDGET) or wepv.InspectionActions) and wepv:GetStatus() == TFA.Enum.STATUS_IDLE then
|
||||
local _, tanim = wepv:ChooseInspectAnim()
|
||||
wepv:ScheduleStatus(TFA.Enum.STATUS_FIDGET, wepv:GetActivityLength(tanim))
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
TFA.RegisterKeyBind({
|
||||
bind = "firemode",
|
||||
onpress = CLIENT and function(plyv)
|
||||
local wepv = plyv:GetActiveWeapon()
|
||||
|
||||
if IsValid(wepv) and wepv.GetStat then
|
||||
if wepv:GetStatL("SelectiveFire") and not wepv:GetOwner():KeyDown(IN_SPEED) then
|
||||
RunConsoleCommand("impulse", TFA.CYCLE_FIREMODE_IMPULSE_STRING)
|
||||
elseif wepv:GetOwner():KeyDown(IN_SPEED) then
|
||||
RunConsoleCommand("impulse", TFA.CYCLE_SAFETY_IMPULSE_STRING)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- EXAMPLE KEYBIND:
|
||||
--[[
|
||||
TFA.RegisterKeyBind({
|
||||
bind = "whatever", -- bind id, cvar is cl_tfa_keys_whatever
|
||||
onpress = function(ply) end, -- function called on key press
|
||||
onrelease = function(ply) end, -- function called on key release
|
||||
think = function(ply) end, -- called from PlayerPostThink when key is held down
|
||||
})
|
||||
]]
|
||||
236
lua/tfa/modules/tfa_keyvalues.lua
Normal file
236
lua/tfa/modules/tfa_keyvalues.lua
Normal file
@@ -0,0 +1,236 @@
|
||||
--[[
|
||||
| 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 CHAR_STRING = {
|
||||
["\""] = true,
|
||||
["'"] = true
|
||||
}
|
||||
|
||||
local CHAR_TABLE_OPEN = {
|
||||
["{"] = true,
|
||||
["["] = true
|
||||
}
|
||||
|
||||
local CHAR_TABLE_CLOSE = {
|
||||
["}"] = true,
|
||||
["]"] = true
|
||||
}
|
||||
|
||||
local CHAR_WHITESPACE = {
|
||||
[" "] = true,
|
||||
["\t"] = true,
|
||||
["\r"] = true,
|
||||
["\n"] = true
|
||||
}
|
||||
|
||||
local CHAR_NEWLINE = {
|
||||
["\r"] = true,
|
||||
["\n"] = true
|
||||
}
|
||||
|
||||
local CHAR_COMMENT = {
|
||||
["/"] = true,
|
||||
["-"] = true
|
||||
}
|
||||
|
||||
local KEY_CASE = true
|
||||
local ORDERED = false
|
||||
|
||||
local buffer = ""
|
||||
local tbl = {}
|
||||
local tbl_focus
|
||||
local tbl_tmp
|
||||
local value, lastvalue
|
||||
local ignore_next_pop
|
||||
local escape
|
||||
local stringtype
|
||||
local is_comment = false
|
||||
local f
|
||||
|
||||
local strsub = string.sub
|
||||
local strlow = string.lower
|
||||
|
||||
local fread = file.Read
|
||||
|
||||
local function strchar( strv, ind )
|
||||
return strsub( strv, ind, ind)
|
||||
end
|
||||
|
||||
local function ResetValues()
|
||||
lastvalue = nil
|
||||
value = nil
|
||||
end
|
||||
|
||||
local function FlushBuffer(write)
|
||||
if buffer ~= "" or stringtype then
|
||||
lastvalue = value
|
||||
if lastvalue and not KEY_CASE then
|
||||
lastvalue = strlow(lastvalue)
|
||||
end
|
||||
value = buffer
|
||||
buffer = ""
|
||||
|
||||
if tbl_focus and (write == nil or write) and lastvalue and value then
|
||||
if ORDERED then
|
||||
tbl_focus[ #tbl_focus + 1 ] = { ["key"] = lastvalue, ["value"] = value }
|
||||
else
|
||||
tbl_focus[lastvalue] = value
|
||||
end
|
||||
ResetValues()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function PushTable()
|
||||
FlushBuffer(true)
|
||||
if value and not KEY_CASE then
|
||||
value = strlow(value)
|
||||
end
|
||||
if value and value ~= "" then
|
||||
if ORDERED then
|
||||
tbl_focus[ #tbl_focus + 1 ] = { ["key"] = value, ["value"] = {} }
|
||||
tbl_focus[ #tbl_focus ].value.__par = tbl_focus
|
||||
tbl_focus = tbl_focus[ #tbl_focus ].value
|
||||
else
|
||||
tbl_focus[value] = istable(tbl_focus[value]) and tbl_focus[value] or {}
|
||||
tbl_focus[value].__par = tbl_focus
|
||||
tbl_focus = tbl_focus[value]
|
||||
end
|
||||
ignore_next_pop = false
|
||||
else
|
||||
ignore_next_pop = true
|
||||
end
|
||||
|
||||
ResetValues()
|
||||
end
|
||||
|
||||
local function PopTable()
|
||||
if not ignore_next_pop then
|
||||
FlushBuffer(true)
|
||||
|
||||
if tbl_focus.__par then
|
||||
tbl_tmp = tbl_focus.__par
|
||||
tbl_focus.__par = nil
|
||||
tbl_focus = tbl_tmp
|
||||
end
|
||||
end
|
||||
|
||||
ignore_next_pop = false
|
||||
ResetValues()
|
||||
end
|
||||
|
||||
function TFA.ParseKeyValues(fn, path, use_escape, keep_key_case, invalid_escape_addslash, ordered )
|
||||
if use_escape == nil then
|
||||
use_escape = true
|
||||
end
|
||||
if keep_key_case == nil then
|
||||
keep_key_case = true
|
||||
end
|
||||
KEY_CASE = keep_key_case
|
||||
if invalid_escape_addslash == nil then
|
||||
invalid_escape_addslash = true
|
||||
end
|
||||
if ordered then
|
||||
ORDERED = true
|
||||
else
|
||||
ORDERED = false
|
||||
end
|
||||
tbl = {}
|
||||
tbl_focus = tbl
|
||||
tbl_tmp = nil
|
||||
value = nil
|
||||
lastvalue = nil
|
||||
escape = false
|
||||
is_comment = false
|
||||
stringtype = nil
|
||||
f = fread(fn, path)
|
||||
if not f then return tbl end
|
||||
for i = 1, #f do
|
||||
local char = strchar(f,i)
|
||||
|
||||
if not char then
|
||||
FlushBuffer()
|
||||
break
|
||||
end
|
||||
|
||||
if is_comment then
|
||||
if CHAR_NEWLINE[char] then
|
||||
is_comment = false
|
||||
end
|
||||
elseif escape then
|
||||
if char == "t" then
|
||||
buffer = buffer .. "\t"
|
||||
elseif char == "n" then
|
||||
buffer = buffer .. "\n"
|
||||
elseif char == "r" then
|
||||
buffer = buffer
|
||||
else
|
||||
if invalid_escape_addslash then
|
||||
buffer = buffer .. "\\"
|
||||
end
|
||||
buffer = buffer .. char
|
||||
end
|
||||
|
||||
escape = false
|
||||
elseif char == "\\" and use_escape then
|
||||
escape = true
|
||||
elseif CHAR_STRING[char] then
|
||||
if not stringtype then
|
||||
FlushBuffer()
|
||||
stringtype = char
|
||||
elseif stringtype == char then
|
||||
FlushBuffer()
|
||||
stringtype = nil
|
||||
elseif stringtype then
|
||||
buffer = buffer .. char
|
||||
end
|
||||
elseif stringtype then
|
||||
buffer = buffer .. char
|
||||
elseif CHAR_COMMENT[char] then
|
||||
if CHAR_COMMENT[ strchar(f,i + 1,i + 1 ) ] then
|
||||
is_comment = true
|
||||
else
|
||||
buffer = buffer .. char
|
||||
end
|
||||
elseif CHAR_WHITESPACE[char] then
|
||||
if buffer ~= "" then
|
||||
FlushBuffer()
|
||||
end
|
||||
elseif CHAR_TABLE_OPEN[char] then
|
||||
PushTable()
|
||||
elseif CHAR_TABLE_CLOSE[char] then
|
||||
PopTable()
|
||||
else
|
||||
buffer = buffer .. char
|
||||
end
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
208
lua/tfa/modules/tfa_matproxies.lua
Normal file
208
lua/tfa/modules/tfa_matproxies.lua
Normal file
@@ -0,0 +1,208 @@
|
||||
--[[
|
||||
| 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 nvec = Vector()
|
||||
|
||||
local function SetPlayerColors(ply)
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
local _SetNWVector = ply.SetNW2Vector or ply.SetNWVector
|
||||
|
||||
nvec.x = ply:GetInfoNum("cl_tfa_laser_color_r", 255)
|
||||
nvec.y = ply:GetInfoNum("cl_tfa_laser_color_g", 0)
|
||||
nvec.z = ply:GetInfoNum("cl_tfa_laser_color_b", 0)
|
||||
_SetNWVector(ply, "TFALaserColor", nvec)
|
||||
|
||||
nvec.x = ply:GetInfoNum("cl_tfa_reticule_color_r", 255)
|
||||
nvec.y = ply:GetInfoNum("cl_tfa_reticule_color_g", 0)
|
||||
nvec.z = ply:GetInfoNum("cl_tfa_reticule_color_b", 0)
|
||||
_SetNWVector(ply, "TFAReticuleColor", nvec)
|
||||
end
|
||||
|
||||
hook.Add("PlayerSpawn", "TFANetworkColors_Spawn", SetPlayerColors)
|
||||
concommand.Add("sv_tfa_apply_player_colors", SetPlayerColors)
|
||||
|
||||
if not matproxy then return end
|
||||
|
||||
matproxy.Add({
|
||||
name = "PlayerWeaponColorStatic",
|
||||
init = function(self, mat, values)
|
||||
self.ResultTo = values.resultvar
|
||||
end,
|
||||
bind = function(self, mat, ent)
|
||||
if (not IsValid(ent)) then return end
|
||||
local owner = ent:GetOwner()
|
||||
if (not IsValid(owner) or not owner:IsPlayer()) then return end
|
||||
local col = owner:GetWeaponColor()
|
||||
if (not isvector(col)) then return end
|
||||
mat:SetVector(self.ResultTo, col * 1)
|
||||
end
|
||||
})
|
||||
|
||||
local cvec = Vector()
|
||||
|
||||
matproxy.Add({
|
||||
name = "TFALaserColor",
|
||||
init = function(self, mat, values)
|
||||
self.ResultTo = values.resultvar
|
||||
end,
|
||||
bind = function(self, mat, ent)
|
||||
local owner
|
||||
|
||||
if (IsValid(ent)) then
|
||||
owner = ent:GetOwner()
|
||||
|
||||
if not IsValid(owner) then
|
||||
owner = ent:GetParent()
|
||||
end
|
||||
|
||||
if IsValid(owner) and owner:IsWeapon() then
|
||||
owner = owner:GetOwner() or owner:GetOwner()
|
||||
end
|
||||
|
||||
if not (IsValid(owner) and owner:IsPlayer()) then
|
||||
owner = GetViewEntity()
|
||||
end
|
||||
else
|
||||
owner = GetViewEntity()
|
||||
end
|
||||
|
||||
if (not IsValid(owner) or not owner:IsPlayer()) then return end
|
||||
local c
|
||||
|
||||
if owner.GetNW2Vector then
|
||||
c = owner:GetNW2Vector("TFALaserColor") or cvec
|
||||
else
|
||||
c = owner:GetNWVector("TFALaserColor") or cvec
|
||||
end
|
||||
|
||||
cvec.x = math.sqrt(c.r / 255) --sqrt for gamma
|
||||
cvec.y = math.sqrt(c.g / 255)
|
||||
cvec.z = math.sqrt(c.b / 255)
|
||||
mat:SetVector(self.ResultTo, cvec)
|
||||
end
|
||||
})
|
||||
|
||||
local cvec_r = Vector()
|
||||
|
||||
matproxy.Add({
|
||||
name = "TFAReticuleColor",
|
||||
init = function(self, mat, values)
|
||||
self.ResultTo = values.resultvar
|
||||
end,
|
||||
bind = function(self, mat, ent)
|
||||
local owner
|
||||
|
||||
if (IsValid(ent)) then
|
||||
owner = ent:GetOwner()
|
||||
|
||||
if not IsValid(owner) then
|
||||
owner = ent:GetParent()
|
||||
end
|
||||
|
||||
if IsValid(owner) and owner:IsWeapon() then
|
||||
owner = owner:GetOwner() or owner:GetOwner()
|
||||
end
|
||||
|
||||
if not (IsValid(owner) and owner:IsPlayer()) then
|
||||
owner = GetViewEntity()
|
||||
end
|
||||
else
|
||||
owner = GetViewEntity()
|
||||
end
|
||||
|
||||
if (not IsValid(owner) or not owner:IsPlayer()) then return end
|
||||
local c
|
||||
|
||||
if owner.GetNW2Vector then
|
||||
c = owner:GetNW2Vector("TFAReticuleColor") or cvec_r
|
||||
else
|
||||
c = owner:GetNWVector("TFAReticuleColor") or cvec_r
|
||||
end
|
||||
|
||||
cvec_r.x = c.r / 255
|
||||
cvec_r.y = c.g / 255
|
||||
cvec_r.z = c.b / 255
|
||||
mat:SetVector(self.ResultTo, cvec_r)
|
||||
end
|
||||
})
|
||||
|
||||
matproxy.Add({
|
||||
name = "TFA_RTScope",
|
||||
init = function(self, mat, values)
|
||||
self.RTMaterial = Material("!tfa_rtmaterial")
|
||||
end,
|
||||
bind = function(self, mat, ent)
|
||||
if not self.RTMaterial then
|
||||
self.RTMaterial = Material("!tfa_rtmaterial")
|
||||
end
|
||||
|
||||
mat:SetTexture("$basetexture", self.RTMaterial:GetTexture("$basetexture"))
|
||||
end
|
||||
})
|
||||
|
||||
local Lerp = Lerp
|
||||
local RealFrameTime = RealFrameTime
|
||||
|
||||
local vector_one = Vector(1, 1, 1)
|
||||
|
||||
matproxy.Add({
|
||||
name = "TFA_CubemapTint",
|
||||
init = function(self, mat, values)
|
||||
self.ResultVar = values.resultvar or "$envmaptint"
|
||||
self.MultVar = values.multiplier
|
||||
end,
|
||||
bind = function(self, mat, ent)
|
||||
local tint = vector_one
|
||||
|
||||
if IsValid(ent) then
|
||||
local mult = self.MultVar and mat:GetVector(self.MultVar) or vector_one
|
||||
|
||||
tint = Lerp(RealFrameTime() * 10, mat:GetVector(self.ResultVar), mult * render.GetLightColor(ent:GetPos()))
|
||||
end
|
||||
|
||||
mat:SetVector(self.ResultVar, tint)
|
||||
end
|
||||
})
|
||||
|
||||
-- VMT Example:
|
||||
--[[
|
||||
$envmapmultiplier "[1 1 1]" // Lighting will be multiplied by this value
|
||||
|
||||
Proxies
|
||||
{
|
||||
TFA_CubemapTint
|
||||
{
|
||||
resultvar $envmaptint // Write final output to $envmaptint
|
||||
multiplier $envmapmultiplier // Use our value for default envmap tint
|
||||
}
|
||||
}
|
||||
]]
|
||||
256
lua/tfa/modules/tfa_melee_autorun.lua
Normal file
256
lua/tfa/modules/tfa_melee_autorun.lua
Normal file
@@ -0,0 +1,256 @@
|
||||
--[[
|
||||
| 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 vector_origin = Vector()
|
||||
|
||||
local timed_blocking_cv = GetConVar("sv_tfa_melee_blocking_timed")
|
||||
local angle_mult_cv = GetConVar("sv_tfa_melee_blocking_anglemult")
|
||||
local deflect_cv = GetConVar("sv_tfa_melee_blocking_deflection")
|
||||
local stun_cv = GetConVar("sv_tfa_melee_blocking_stun_enabled")
|
||||
local stuntime_cv = GetConVar("sv_tfa_melee_blocking_stun_time")
|
||||
|
||||
local bul = {
|
||||
HullSize = 5,
|
||||
Num = 1,
|
||||
Tracer = 1,
|
||||
AmmoType = "",
|
||||
TracerName = "Tracer",
|
||||
Spread = Vector(0.05,0.05,0),
|
||||
Distance = 56756
|
||||
}
|
||||
|
||||
local function CanDeflect()
|
||||
return true
|
||||
end
|
||||
|
||||
local function DeflectBullet( ent, dmginfo, olddmg )
|
||||
if dmginfo:IsDamageType( DMG_BULLET ) and CanDeflect() and ent.FireBullets then
|
||||
bul.Src = ent:GetShootPos()
|
||||
bul.Dir = ent:EyeAngles():Forward()
|
||||
bul.Damage = olddmg
|
||||
bul.Force = olddmg / 10
|
||||
local atk = dmginfo:GetAttacker()
|
||||
if IsValid( atk ) and atk.TFALastTracer then
|
||||
bul.Tracer = atk.TFALastTracer
|
||||
end
|
||||
ent:FireBullets( bul, false )
|
||||
dmginfo:ScaleDamage(0)
|
||||
end
|
||||
end
|
||||
|
||||
local stuntime = 0.65
|
||||
|
||||
local function StunNPC( npc, ply )
|
||||
if stun_cv and not stun_cv:GetBool() then return end
|
||||
if ( not IsValid( npc ) ) or ( not npc:IsNPC() ) then
|
||||
return
|
||||
end
|
||||
if npc.ClearSchedule then
|
||||
npc:ClearSchedule()
|
||||
end
|
||||
if npc.SetEnemy then
|
||||
npc:SetEnemy(nil)
|
||||
end
|
||||
if npc.AddEntityRelationship and IsValid(ply) then
|
||||
local oldrel = npc.GetRelationship and npc:GetRelationship(ply) or D_HT
|
||||
npc:AddEntityRelationship( ply, D_NU, 99)
|
||||
stuntime = stuntime_cv:GetFloat()
|
||||
timer.Simple( stuntime , function()
|
||||
if IsValid(npc) and npc:IsNPC() and IsValid(ply) then
|
||||
npc:AddEntityRelationship( ply, oldrel, 99)
|
||||
end
|
||||
end)
|
||||
end
|
||||
if npc.ClearEnemyMemory then
|
||||
npc:ClearEnemyMemory()
|
||||
end
|
||||
end
|
||||
|
||||
local function BlockDamageNew( ent, dmginfo )
|
||||
if not ent:IsPlayer() then return end
|
||||
if dmginfo:IsDamageType( DMG_DROWNRECOVER ) or dmginfo:IsDamageType(DMG_DIRECT) then return end
|
||||
local wep
|
||||
wep = ent:GetActiveWeapon()
|
||||
|
||||
if (wep.IsTFAWeapon and wep.BlockDamageTypes and wep:GetStatus() == TFA.Enum.STATUS_BLOCKING) then
|
||||
local canblock = false
|
||||
for _,v in ipairs(wep.BlockDamageTypes) do
|
||||
if dmginfo:IsDamageType(v) then canblock = true end
|
||||
end
|
||||
if canblock then
|
||||
local damageinflictor, blockthreshold
|
||||
damageinflictor = dmginfo:GetInflictor()
|
||||
|
||||
if (not IsValid(damageinflictor)) then
|
||||
damageinflictor = dmginfo:GetAttacker()
|
||||
end
|
||||
|
||||
blockthreshold = ( wep.BlockCone or 135 ) / 2
|
||||
if angle_mult_cv then
|
||||
blockthreshold = blockthreshold * angle_mult_cv:GetFloat()
|
||||
end
|
||||
if ( IsValid(damageinflictor) and ( math.abs(math.AngleDifference( ent:EyeAngles().y, ( damageinflictor:GetPos() - ent:GetPos() ):Angle().y )) <= blockthreshold)) then
|
||||
local fac = math.Clamp( ( CurTime() - wep:GetBlockStart() - wep.BlockTimeWindow ) / wep.BlockTimeFade, 0, 1)
|
||||
local dmgscale
|
||||
if ( not timed_blocking_cv ) or timed_blocking_cv:GetBool() then
|
||||
dmgscale = Lerp(fac, wep.BlockDamageMaximum, wep.BlockDamageMinimum)
|
||||
else
|
||||
dmgscale = wep.BlockDamageMaximum
|
||||
end
|
||||
local olddmg = dmginfo:GetDamage()
|
||||
dmgscale = math.min( dmgscale, wep.BlockDamageCap / dmginfo:GetDamage() )
|
||||
--print(fac)
|
||||
dmginfo:ScaleDamage(dmgscale)
|
||||
dmginfo:SetDamagePosition(vector_origin)
|
||||
dmginfo:SetDamageType( bit.bor( dmginfo:GetDamageType(), DMG_DROWNRECOVER ) )
|
||||
wep:EmitSound(wep.BlockSound or "")
|
||||
|
||||
if wep.ChooseBlockAnimation then
|
||||
wep:ChooseBlockAnimation()
|
||||
end
|
||||
|
||||
if deflect_cv and deflect_cv:GetInt() == 2 then
|
||||
DeflectBullet( ent, dmginfo, olddmg )
|
||||
end
|
||||
|
||||
if dmginfo:GetDamage() < 1 then
|
||||
if deflect_cv and deflect_cv:GetInt() == 1 and wep.BlockCanDeflect then
|
||||
DeflectBullet( ent, dmginfo, olddmg )
|
||||
end
|
||||
StunNPC( dmginfo:GetAttacker(), ent )
|
||||
return true
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
hook.Add("EntityFireBullets","TFA_Melee_LogTracer",function(ent,bulv) --Record tracer for blocking
|
||||
ent.TFALastTracer = bulv.TracerName or ""
|
||||
end)
|
||||
|
||||
local npc_dmg_scale_cv = GetConVar("sv_tfa_melee_damage_npc")
|
||||
local ply_dmg_scale_cv = GetConVar("sv_tfa_melee_damage_ply")
|
||||
|
||||
hook.Add("EntityTakeDamage", "TFA_Melee_Scaling", function( ent, dmginfo )
|
||||
local wep = dmginfo:GetInflictor()
|
||||
if not IsValid(wep) then return end
|
||||
if wep:IsPlayer() then wep = wep:GetActiveWeapon() end
|
||||
if not IsValid(wep) or not wep:IsWeapon() then return end
|
||||
if not wep.BlockDamageCap then return end
|
||||
if ent:IsNPC() then
|
||||
dmginfo:ScaleDamage( npc_dmg_scale_cv:GetFloat() )
|
||||
elseif ent:IsPlayer() then
|
||||
dmginfo:ScaleDamage( ply_dmg_scale_cv:GetFloat() )
|
||||
end
|
||||
end) --Cancel
|
||||
hook.Add("EntityTakeDamage", "aaa_TFA_Melee_Block", function( ent, dmginfo )
|
||||
return BlockDamageNew( ent, dmginfo )
|
||||
end) --Cancel
|
||||
hook.Add("ScalePlayerDamage", "aaa_TFA_Melee_Block", function( ent, _, dmginfo ) --Cancel
|
||||
return BlockDamageNew( ent, dmginfo )
|
||||
end)
|
||||
|
||||
game.AddAmmoType({
|
||||
name = "TFMSwordHitGenericSlash",
|
||||
dmgtype = DMG_SLASH,
|
||||
tracer = TRACER_NONE
|
||||
})
|
||||
|
||||
local function TFMPlayerSpawn(ply)
|
||||
ply:SetNW2Vector("TFM_SwordPosition", Vector(1, 1, 1))
|
||||
ply:SetNW2Vector("TFM_SwordNormal", Vector(1, 1, 1))
|
||||
ply:SetNW2Bool("TFM_IsSprinting", false)
|
||||
ply:SetNW2Bool("TFM_IsBlocking", false)
|
||||
ply:SetNW2Bool("TFM_IsSwinging", false)
|
||||
ply:SetNW2Float("TFM_SwingStart", CurTime())
|
||||
end
|
||||
|
||||
hook.Add("PlayerSpawn", "TFM_PlayerSpawn", TFMPlayerSpawn)
|
||||
|
||||
hook.Add("EntityTakeDamage", "TFM_Block", function(ent, dmginfo) --Legacy
|
||||
if ent:IsPlayer() then
|
||||
local wep
|
||||
wep = ent:GetActiveWeapon()
|
||||
|
||||
if (wep.IsTFAWeapon and wep.BlockAngle) and (dmginfo:IsDamageType(DMG_SLASH) or dmginfo:IsDamageType(DMG_CLUB) or (wep.NinjaMode and wep.NinjaMode == true and (dmginfo:IsDamageType(DMG_CRUSH) or dmginfo:IsDamageType(DMG_BULLET)))) and wep:GetIronSights() then
|
||||
local damageinflictor, blockthreshold
|
||||
damageinflictor = dmginfo:GetInflictor()
|
||||
|
||||
if (not IsValid(damageinflictor)) then
|
||||
damageinflictor = dmginfo:GetAttacker()
|
||||
end
|
||||
|
||||
blockthreshold = wep.BlockAngle / 2 or 90
|
||||
|
||||
if (IsValid(damageinflictor) and (math.abs((ent:GetAimVector():Angle() - (damageinflictor:GetPos() - ent:GetPos()):Angle()).y) <= blockthreshold)) or (math.abs((ent:GetAimVector():Angle() - (dmginfo:GetDamagePosition() - ent:GetPos()):Angle()).y) <= blockthreshold) then
|
||||
local fac = math.Clamp((CurTime() - wep:GetBlockStart() - wep.BlockWindow) / wep.BlockFadeTime, 0, 1)
|
||||
local dmgscale
|
||||
if ( not timed_blocking_cv ) or timed_blocking_cv:GetBool() then
|
||||
dmgscale = Lerp(fac, wep.BlockMaximum, wep.BlockMinimum)
|
||||
else
|
||||
dmgscale = wep.BlockMaximum
|
||||
end
|
||||
--print(fac)
|
||||
dmginfo:ScaleDamage(dmgscale)
|
||||
dmginfo:SetDamagePosition(vector_origin)
|
||||
wep:EmitSound(wep.Primary.Sound_Impact_Metal)
|
||||
|
||||
if wep.BlockAnim then
|
||||
wep:BlockAnim()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
--Getting the position and angle of an attachment and sending it back to the server is wayyy too laggy. Must be pre-coded.
|
||||
--[[
|
||||
if SERVER then
|
||||
util.AddNetworkString( "TFM_SAPacket" )
|
||||
net.Receive("TFM_SAPacket", function()
|
||||
local ply;
|
||||
ply = net.ReadEntity()
|
||||
local pos;
|
||||
pos = net.ReadVector()
|
||||
local norm;
|
||||
norm = net.ReadNormal()
|
||||
if IsValid(ply) then
|
||||
if pos and norm then
|
||||
ply:SetNW2Vector("TFM_SwordPosition",pos)
|
||||
ply:SetNW2Vector("TFM_SwordNormal",norm)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
]]
|
||||
--
|
||||
58
lua/tfa/modules/tfa_meta.lua
Normal file
58
lua/tfa/modules/tfa_meta.lua
Normal file
@@ -0,0 +1,58 @@
|
||||
--[[
|
||||
| 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 WEAPON = FindMetaTable("Weapon")
|
||||
|
||||
if WEAPON then
|
||||
function WEAPON:IsTFA() -- please do not use, just check for IsTFAWeapon directly
|
||||
return self.IsTFAWeapon
|
||||
end
|
||||
else
|
||||
print("[TFA Base] Can't find weapon metatable!")
|
||||
end
|
||||
|
||||
local PLAYER = FindMetaTable("Player")
|
||||
|
||||
if PLAYER then
|
||||
function PLAYER:TFA_ZoomKeyDown()
|
||||
if not IsValid(self) then return false end
|
||||
|
||||
return self:GetNW2Bool("TFA_ZoomKeyDown", false)
|
||||
end
|
||||
|
||||
function PLAYER:TFA_SetZoomKeyDown(isdown)
|
||||
if not IsValid(self) then return end
|
||||
|
||||
self:SetNW2Bool("TFA_ZoomKeyDown", isdown)
|
||||
end
|
||||
else
|
||||
print("[TFA Base] Can't find player metatable!")
|
||||
end
|
||||
181
lua/tfa/modules/tfa_netcode.lua
Normal file
181
lua/tfa/modules/tfa_netcode.lua
Normal file
@@ -0,0 +1,181 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
if SERVER then
|
||||
--Pool netstrings
|
||||
util.AddNetworkString("tfaSoundEvent")
|
||||
util.AddNetworkString("tfaSoundEventStop")
|
||||
util.AddNetworkString("tfa_base_muzzle_mp")
|
||||
util.AddNetworkString("tfaShotgunInterrupt")
|
||||
util.AddNetworkString("tfaRequestFidget")
|
||||
util.AddNetworkString("tfaSDLP")
|
||||
util.AddNetworkString("tfaArrowFollow")
|
||||
util.AddNetworkString("tfaTracerSP")
|
||||
util.AddNetworkString("tfaBaseShellSV")
|
||||
--util.AddNetworkString("tfaAltAttack")
|
||||
util.AddNetworkString("TFAJoinGroupPopup")
|
||||
|
||||
util.AddNetworkString("tfaHitmarker")
|
||||
util.AddNetworkString("tfaHitmarker3D")
|
||||
util.AddNetworkString("tfa_friendly_encounter")
|
||||
|
||||
do
|
||||
local old_state = false
|
||||
|
||||
timer.Create("tfa_friendly_encounter", 2, 0, function()
|
||||
local new_state = game.GetGlobalState("friendly_encounter") == GLOBAL_ON
|
||||
|
||||
if old_state ~= new_state then
|
||||
net.Start("tfa_friendly_encounter")
|
||||
net.WriteBool(new_state)
|
||||
net.Broadcast()
|
||||
|
||||
old_state = new_state
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerAuthed", "tfa_friendly_encounter", function()
|
||||
old_state = false
|
||||
end)
|
||||
end
|
||||
|
||||
--Enable CKey Inspection
|
||||
|
||||
net.Receive("tfaRequestFidget",function(length,client)
|
||||
local wep = client:GetActiveWeapon()
|
||||
if IsValid(wep) and wep.CheckAmmo then wep:CheckAmmo() end
|
||||
end)
|
||||
|
||||
--Enable shotgun interruption
|
||||
net.Receive("tfaShotgunInterrupt", function(length, client)
|
||||
if IsValid(client) and client:IsPlayer() and client:Alive() then
|
||||
local ply = client
|
||||
local wep = ply:GetActiveWeapon()
|
||||
|
||||
if IsValid(wep) and wep.ShotgunInterrupt then
|
||||
wep:ShotgunInterrupt()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if game.SinglePlayer() then
|
||||
net.Receive("tfaSDLP",function(length,client)
|
||||
local bool = net.ReadBool()
|
||||
client.TFASDLP = bool
|
||||
end)
|
||||
end
|
||||
|
||||
--Enable alternate attacks
|
||||
--[[
|
||||
net.Receive("tfaAltAttack", function(length, client)
|
||||
if IsValid(client) and client:IsPlayer() and client:Alive() then
|
||||
local ply = client
|
||||
wep = ply:GetActiveWeapon()
|
||||
|
||||
if IsValid(wep) and wep.AltAttack then
|
||||
wep:AltAttack()
|
||||
end
|
||||
end
|
||||
end)
|
||||
]]--
|
||||
else
|
||||
TFA.FriendlyEncounter = false
|
||||
|
||||
net.Receive("tfa_friendly_encounter", function()
|
||||
TFA.FriendlyEncounter = net.ReadBool()
|
||||
end)
|
||||
|
||||
--Arrow can follow entities clientside too
|
||||
net.Receive("tfaArrowFollow",function()
|
||||
local ent = net.ReadEntity()
|
||||
ent.targent = net.ReadEntity()
|
||||
ent.targbone = net.ReadInt( 8 )
|
||||
ent.posoff = net.ReadVector( )
|
||||
ent.angoff = net.ReadAngle( )
|
||||
ent:TargetEnt( false )
|
||||
end)
|
||||
|
||||
--Receive sound events on client
|
||||
net.Receive("tfaSoundEvent", function(length, ply)
|
||||
local wep = net.ReadEntity()
|
||||
local snd = net.ReadString()
|
||||
|
||||
if IsValid(wep) and snd and snd ~= "" then
|
||||
wep:EmitSound(snd)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("tfaSoundEventStop", function(length, ply)
|
||||
local wep = net.ReadEntity()
|
||||
local snd = net.ReadString()
|
||||
|
||||
if IsValid(wep) and snd and snd ~= "" then
|
||||
wep:StopSound(snd)
|
||||
end
|
||||
end)
|
||||
|
||||
--Receive muzzleflashes on client
|
||||
net.Receive("tfa_base_muzzle_mp", function(length, ply)
|
||||
local wep = net.ReadEntity()
|
||||
|
||||
if IsValid(wep) and wep.ShootEffectsCustom then
|
||||
wep:ShootEffectsCustom(true)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("tfaBaseShellSV", function(length, ply)
|
||||
local wep = net.ReadEntity()
|
||||
|
||||
if IsValid(wep) and wep.MakeShellBridge then
|
||||
wep:MakeShellBridge()
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive( "tfaTracerSP", function( length, ply )
|
||||
local part = net.ReadString()
|
||||
local startPos = net.ReadVector()
|
||||
local endPos = net.ReadVector()
|
||||
local woosh = net.ReadBool()
|
||||
local vent = net.ReadEntity()
|
||||
local att = net.ReadInt( 8 )
|
||||
if IsValid( vent ) then
|
||||
local aP = vent:GetAttachment( att or 1 )
|
||||
if aP then
|
||||
startPos = aP.Pos
|
||||
end
|
||||
end
|
||||
TFA.ParticleTracer( part, startPos, endPos, woosh, vent, att )
|
||||
end)
|
||||
|
||||
net.Receive("TFAJoinGroupPopup", function()
|
||||
gui.OpenURL("http://steamcommunity.com/groups/tfa-mods")
|
||||
end)
|
||||
end
|
||||
88
lua/tfa/modules/tfa_npc_weaponmenu.lua
Normal file
88
lua/tfa/modules/tfa_npc_weaponmenu.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
-- AI Options
|
||||
if CLIENT then
|
||||
hook.Add("PopulateMenuBar", "NPCOptions_MenuBar_TFA", function(menubarV)
|
||||
local m = menubarV:AddOrGetMenu("#menubar.npcs")
|
||||
local wpns = m:AddSubMenu("#tfa.menubar.npcs.weapon")
|
||||
wpns:SetDeleteSelf(false)
|
||||
|
||||
wpns:AddCVar("#menubar.npcs.defaultweapon", "gmod_npcweapon", "")
|
||||
wpns:AddCVar("#menubar.npcs.noweapon", "gmod_npcweapon", "none")
|
||||
wpns:AddSpacer()
|
||||
|
||||
local weaponCats = {}
|
||||
|
||||
for _, wep in pairs(weapons.GetList()) do
|
||||
if wep and wep.Spawnable and weapons.IsBasedOn(wep.ClassName, "tfa_gun_base") then
|
||||
local cat = wep.Category or "Other"
|
||||
weaponCats[cat] = weaponCats[cat] or {}
|
||||
|
||||
table.insert(weaponCats[cat], {
|
||||
["class"] = wep.ClassName,
|
||||
["title"] = wep.PrintName or wep.ClassName
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local catKeys = table.GetKeys(weaponCats)
|
||||
table.sort(catKeys, function(a, b) return a < b end)
|
||||
|
||||
for _, k in ipairs(catKeys) do
|
||||
local v = weaponCats[k]
|
||||
local wpnSub = wpns:AddSubMenu(k)
|
||||
wpnSub:SetDeleteSelf(false)
|
||||
table.SortByMember(v, "title", true)
|
||||
|
||||
for _, b in ipairs(v) do
|
||||
wpnSub:AddCVar(b.title, "gmod_npcweapon", b.class)
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
local npcWepList = list.GetForEdit("NPCUsableWeapons")
|
||||
|
||||
hook.Add("PlayerSpawnNPC", "TFACheckNPCWeapon", function(plyv, npcclassv, wepclassv)
|
||||
if type(wepclassv) ~= "string" or wepclassv == "" then return end
|
||||
|
||||
if not npcWepList[wepclassv] then -- do not copy the table
|
||||
local wep = weapons.GetStored(wepclassv)
|
||||
|
||||
if wep and (wep.Spawnable and not wep.AdminOnly) and weapons.IsBasedOn(wep.ClassName, "tfa_gun_base") then
|
||||
npcWepList[wepclassv] = {
|
||||
["class"] = wep.ClassName,
|
||||
["title"] = wep.PrintName or wep.ClassName
|
||||
}
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
236
lua/tfa/modules/tfa_nzombies.lua
Normal file
236
lua/tfa/modules/tfa_nzombies.lua
Normal file
@@ -0,0 +1,236 @@
|
||||
--[[
|
||||
| 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.NZombies = TFA.NZombies or {}
|
||||
|
||||
if TFA.NZombies.Patch == nil then
|
||||
TFA.NZombies.Patch = true --Change this if you need to
|
||||
end
|
||||
|
||||
local cv_melee_scaling, cv_melee_basefactor, cv_melee_berserkscale
|
||||
local nzombies = string.lower(engine.ActiveGamemode() or "") == "nzombies"
|
||||
|
||||
if nZombies or NZombies or NZ then
|
||||
nzombies = true
|
||||
end
|
||||
|
||||
if nzombies then
|
||||
cv_melee_scaling = CreateConVar("sv_tfa_nz_melee_scaling", "1", {FCVAR_SERVER_CAN_EXECUTE, FCVAR_REPLICATED}, "0.5x means if zombies have 4x health, melee does 2x damage")
|
||||
cv_melee_basefactor = CreateConVar("sv_tfa_nz_melee_multiplier", "0.65", {FCVAR_SERVER_CAN_EXECUTE, FCVAR_REPLICATED}, "Base damage scale for TFA Melees.")
|
||||
cv_melee_berserkscale = CreateConVar("sv_tfa_nz_melee_immunity", "0.67", {FCVAR_SERVER_CAN_EXECUTE, FCVAR_REPLICATED}, "Take X% damage from zombies while you're melee.")
|
||||
--cv_melee_juggscale = CreateConVar("sv_tfa_nz_melee_juggernaut", "1.5", {FCVAR_SERVER_CAN_EXECUTE, FCVAR_REPLICATED}, "Do X% damage to zombies while you're jug.")
|
||||
hook.Add("TFA_AnimationRate","NZBase",function(wep,act,rate)
|
||||
if wep:OwnerIsValid() and wep:GetOwner().HasPerk and wep:GetOwner():HasPerk("speed") and wep.SpeedColaActivities[ act ] then
|
||||
rate = rate * wep.SpeedColaFactor
|
||||
end
|
||||
if wep:OwnerIsValid() and wep:GetOwner().HasPerk and wep:GetOwner():HasPerk("dtap") and wep.DTapActivities[ act ] then
|
||||
rate = rate * wep.DTapSpeed
|
||||
end
|
||||
if wep:OwnerIsValid() and wep:GetOwner().HasPerk and wep:GetOwner():HasPerk("dtap2") and wep.DTapActivities[ act ] then
|
||||
rate = rate * wep.DTap2Speed
|
||||
end
|
||||
return rate
|
||||
end)
|
||||
hook.Add("TFA_Deploy","NZBase",function(wep)
|
||||
local pap = wep:GetPaP()
|
||||
wep.OldPaP = pap
|
||||
local spd2 = wep:OwnerIsValid() and wep:GetOwner().HasPerk and wep:GetOwner():HasPerk("speed")
|
||||
if pap and pap ~= wep.OldPaP then
|
||||
if AddPackAPunchName and wep.NZPaPName and not wep.HasAddedNZName then
|
||||
AddPackAPunchName( wep.ClassName, wep.NZPaPName )
|
||||
wep.HasAddedNZName = true
|
||||
end
|
||||
if wep.NZPaPName and wep:GetPaP() then
|
||||
wep.PrintName = wep.NZPaPName
|
||||
wep:SetNW2String("PrintName",wep.NZPaPName)
|
||||
end
|
||||
local pn = wep:GetNW2String("PrintName")
|
||||
if pn and pn ~= "" then
|
||||
wep.PrintName = pn
|
||||
end
|
||||
wep:ClearStatCache()
|
||||
timer.Simple(0.1,function()
|
||||
if IsValid(wep) then
|
||||
wep:ClearStatCache()
|
||||
end
|
||||
end)
|
||||
end
|
||||
if spd2 ~= wep.OldSpCola then
|
||||
wep:ClearStatCache()
|
||||
end
|
||||
wep.OldSpCola = spd2
|
||||
end)
|
||||
hook.Add("TFA_Initialize", "NZBase", function(wep)
|
||||
timer.Simple(0.1, function() -- timers for everything YAY
|
||||
if not IsValid(wep) then return end
|
||||
|
||||
wep.Primary_TFA.Ammo = game.GetAmmoName(wep:GetPrimaryAmmoType())
|
||||
wep:ClearStatCache("Primary.Ammo")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
--[[
|
||||
local function SpreadFix()
|
||||
|
||||
local GAMEMODE = gmod.GetGamemode() or GAMEMODE
|
||||
if not GAMEMODE then return end
|
||||
|
||||
print("[TFA] Patching NZombies")
|
||||
if TFA.NZombies.Patch then return end
|
||||
|
||||
local ghosttraceentities = {
|
||||
["wall_block"] = true,
|
||||
["invis_wall"] = true,
|
||||
["player"] = true
|
||||
}
|
||||
|
||||
function GAMEMODE:EntityFireBullets(ent, data)
|
||||
-- Fire the PaP shooting sound if the weapon is PaP'd
|
||||
--print(wep, wep.pap)
|
||||
if ent:IsPlayer() and IsValid(ent:GetActiveWeapon()) then
|
||||
local wep = ent:GetActiveWeapon()
|
||||
if wep.pap and ( not wep.IsMelee ) and ( not wep.IsKnife ) then
|
||||
wep:EmitSound("nz/effects/pap_shoot_glock20.wav", 105, 100)
|
||||
end
|
||||
end
|
||||
|
||||
if ent:IsPlayer() and ent:HasPerk("dtap2") then
|
||||
data.Num = data.Num * 2
|
||||
end
|
||||
|
||||
-- Perform a trace that filters out entities from the table above
|
||||
local tr = util.TraceLine({
|
||||
start = data.Src,
|
||||
endpos = data.Src + (data.Dir * data.Distance),
|
||||
filter = function(entv)
|
||||
if ghosttraceentities[entv:GetClass()] and not entv:IsPlayer() then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--PrintTable(tr)
|
||||
-- If we hit anything, move the source of the bullets up to that point
|
||||
if IsValid(tr.Entity) and tr.Fraction < 1 then
|
||||
local tr2 = util.TraceLine({
|
||||
start = data.Src,
|
||||
endpos = data.Src + (data.Dir * data.Distance),
|
||||
filter = function(entv)
|
||||
if ghosttraceentities[entv:GetClass()] then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
data.Src = tr2.HitPos - data.Dir * 5
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if ent:IsPlayer() and ent:HasPerk("dtap2") then return true end
|
||||
end
|
||||
end
|
||||
]]
|
||||
--
|
||||
local function MeleeFix()
|
||||
hook.Add("EntityTakeDamage", "TFA_MeleeScaling", function(target, dmg)
|
||||
if not TFA.NZombies.Patch then return end
|
||||
if not nzRound then return end
|
||||
local ent = dmg:GetInflictor()
|
||||
|
||||
if not ent:IsWeapon() and ent:IsPlayer() then
|
||||
ent = ent:GetActiveWeapon()
|
||||
end
|
||||
|
||||
if not IsValid(ent) or not ent:IsWeapon() then return end
|
||||
|
||||
if ent.IsTFAWeapon and (dmg:IsDamageType(DMG_CRUSH) or dmg:IsDamageType(DMG_CLUB) or dmg:IsDamageType(DMG_SLASH)) then
|
||||
local scalefactor = cv_melee_scaling:GetFloat()
|
||||
local basefactor = cv_melee_basefactor:GetFloat()
|
||||
dmg:ScaleDamage(((nzRound:GetZombieHealth() - 75) / 75 * scalefactor + 1) * basefactor)
|
||||
--if IsValid(ent:GetOwner()) and ent:GetOwner():IsPlayer() and ent:GetOwner():HasPerk("jugg") then
|
||||
-- dmg:ScaleDamage(cv_melee_juggscale:GetFloat())
|
||||
--end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("EntityTakeDamage", "TFA_MeleeReceiveLess", function(target, dmg)
|
||||
if not TFA.NZombies.Patch then return end
|
||||
|
||||
if target:IsPlayer() and target.GetActiveWeapon then
|
||||
local wep = target:GetActiveWeapon()
|
||||
|
||||
if IsValid(wep) and wep.IsTFAWeapon and (wep.IsKnife or wep.IsMelee or wep.Primary.Reach) then
|
||||
dmg:ScaleDamage(cv_melee_berserkscale:GetFloat())
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("EntityTakeDamage", "TFA_MeleePaP", function(target, dmg)
|
||||
if not TFA.NZombies.Patch then return end
|
||||
local ent = dmg:GetInflictor()
|
||||
|
||||
if IsValid(ent) then
|
||||
local wep
|
||||
|
||||
if ent:IsPlayer() then
|
||||
wep = ent:GetActiveWeapon()
|
||||
elseif ent:IsWeapon() then
|
||||
wep = ent
|
||||
end
|
||||
|
||||
if IsValid(wep) and wep.IsTFAWeapon and (wep.Primary.Attacks or wep.IsMelee or wep.Primary.Reach) and wep:GetPaP() then
|
||||
dmg:ScaleDamage(2)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function NZPatch()
|
||||
if not TFA.NZombies.Patch then return end
|
||||
nzombies = string.lower(engine.ActiveGamemode() or "") == "nzombies"
|
||||
|
||||
if nZombies or NZombies or NZ or NZombies then
|
||||
nzombies = true
|
||||
end
|
||||
|
||||
if nzombies then
|
||||
--SpreadFix()
|
||||
MeleeFix()
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity", "TFA_NZPatch", NZPatch)
|
||||
NZPatch()
|
||||
79
lua/tfa/modules/tfa_particles.lua
Normal file
79
lua/tfa/modules/tfa_particles.lua
Normal file
@@ -0,0 +1,79 @@
|
||||
--[[
|
||||
| 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.Particles = TFA.Particles or {}
|
||||
TFA.Particles.FlareParts = {}
|
||||
TFA.Particles.VMAttachments = {}
|
||||
|
||||
TFA.Particles.PCFParticles = TFA.Particles.PCFParticles or {}
|
||||
|
||||
TFA.Particles.PCFParticles["tfa_muzzle_rifle"] = "tfa_muzzleflashes"
|
||||
TFA.Particles.PCFParticles["tfa_muzzle_sniper"] = "tfa_muzzleflashes"
|
||||
TFA.Particles.PCFParticles["tfa_muzzle_energy"] = "tfa_muzzleflashes"
|
||||
TFA.Particles.PCFParticles["tfa_muzzle_energy"] = "tfa_muzzleflashes"
|
||||
TFA.Particles.PCFParticles["tfa_muzzle_gauss"] = "tfa_muzzleflashes"
|
||||
|
||||
-- TFA.Particles.PCFParticles["weapon_muzzle_smoke_long"] = "csgo_fx"
|
||||
-- TFA.Particles.PCFParticles["weapon_muzzle_smoke"] = "csgo_fx"
|
||||
|
||||
TFA.Particles.PCFParticles["tfa_ins2_weapon_muzzle_smoke"] = "tfa_ins2_muzzlesmoke"
|
||||
TFA.Particles.PCFParticles["tfa_ins2_weapon_shell_smoke"] = "tfa_ins2_shellsmoke"
|
||||
TFA.Particles.PCFParticles["tfa_bullet_smoke_tracer"] = "tfa_ballistics"
|
||||
TFA.Particles.PCFParticles["tfa_bullet_fire_tracer"] = "tfa_ballistics"
|
||||
TFA.Particles.PCFParticles["tfa_ins2_shell_eject"] = "tfa_ins2_ejectionsmoke"
|
||||
|
||||
--legacy
|
||||
TFA.Particles.PCFParticles["smoke_trail_tfa"] = "tfa_smoke"
|
||||
TFA.Particles.PCFParticles["smoke_trail_controlled"] = "tfa_smoke"
|
||||
|
||||
TFA.Particles.SmokeLightingMin = Vector(0.15, 0.15, 0.15)
|
||||
TFA.Particles.SmokeLightingMax = Vector(0.75, 0.75, 0.75)
|
||||
TFA.Particles.SmokeLightingClamp = 1
|
||||
|
||||
local addedparts = {}
|
||||
local cachedparts = {}
|
||||
|
||||
function TFA.Particles.Initialize()
|
||||
for k, v in pairs(TFA.Particles.PCFParticles) do
|
||||
if not addedparts[v] then
|
||||
game.AddParticles("particles/" .. v .. ".pcf")
|
||||
addedparts[v] = true
|
||||
end
|
||||
|
||||
if not cachedparts[k] and not string.find(k, "DUMMY") then
|
||||
PrecacheParticleSystem(k)
|
||||
cachedparts[k] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity", "TFA.Particles.Initialize", TFA.Particles.Initialize)
|
||||
TFA.Particles.Initialize()
|
||||
327
lua/tfa/modules/tfa_small_entities.lua
Normal file
327
lua/tfa/modules/tfa_small_entities.lua
Normal file
@@ -0,0 +1,327 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
-- This file contain aliases/slight modifications which do not deserve their own Lua file
|
||||
|
||||
weapons.Register({
|
||||
Base = "tfa_nade_base",
|
||||
AllowUnderhanded = true,
|
||||
}, "tfa_cssnade_base")
|
||||
|
||||
weapons.Register({
|
||||
Base = "tfa_gun_base",
|
||||
Shotgun = true,
|
||||
}, "tfa_shotty_base")
|
||||
|
||||
weapons.Register({
|
||||
Base = "tfa_gun_base",
|
||||
}, "tfa_akimbo_base")
|
||||
|
||||
if SERVER then
|
||||
AddCSLuaFile("tfa/3dscoped_base.lua")
|
||||
end
|
||||
|
||||
local SWEP_ = include("tfa/3dscoped_base.lua")
|
||||
local SWEP = table.Copy(SWEP_)
|
||||
SWEP.Secondary = {}
|
||||
|
||||
SWEP.Secondary.ScopeZoom = 1
|
||||
SWEP.Secondary.UseACOG = false
|
||||
SWEP.Secondary.UseMilDot = false
|
||||
SWEP.Secondary.UseSVD = false
|
||||
SWEP.Secondary.UseParabolic = false
|
||||
SWEP.Secondary.UseElcan = false
|
||||
SWEP.Secondary.UseGreenDuplex = false
|
||||
SWEP.RTScopeFOV = 6
|
||||
SWEP.RTScopeAttachment = 3 --Anchor the scope shadow to this
|
||||
SWEP.Scoped = false
|
||||
SWEP.BoltAction = false
|
||||
SWEP.ScopeLegacyOrientation = false --used to align with eyeangles instead of vm angles
|
||||
SWEP.ScopeAngleTransforms = {}
|
||||
--{"P",1} --Pitch, 1
|
||||
--{"Y",1} --Yaw, 1
|
||||
--{"R",1} --Roll, 1
|
||||
SWEP.ScopeOverlayTransforms = {0, 0}
|
||||
SWEP.ScopeOverlayTransformMultiplier = 0.8
|
||||
SWEP.RTMaterialOverride = 1
|
||||
SWEP.IronSightsSensitivity = 1
|
||||
SWEP.ScopeShadow = nil
|
||||
SWEP.ScopeReticule = nil
|
||||
SWEP.ScopeDirt = nil
|
||||
SWEP.ScopeReticule_CrossCol = false
|
||||
SWEP.ScopeReticule_Scale = {1, 1}
|
||||
--[[End of Tweakable Parameters]]--
|
||||
SWEP.Scoped_3D = true
|
||||
SWEP.BoltAction_3D = false
|
||||
|
||||
SWEP.Base = "tfa_bash_base"
|
||||
|
||||
weapons.Register(SWEP, "tfa_3dbash_base")
|
||||
|
||||
SWEP = table.Copy(SWEP_)
|
||||
SWEP.Secondary = {}
|
||||
|
||||
SWEP.Secondary.ScopeZoom = 0
|
||||
SWEP.Secondary.UseACOG = false
|
||||
SWEP.Secondary.UseMilDot = false
|
||||
SWEP.Secondary.UseSVD = false
|
||||
SWEP.Secondary.UseParabolic = false
|
||||
SWEP.Secondary.UseElcan = false
|
||||
SWEP.Secondary.UseGreenDuplex = false
|
||||
SWEP.RTScopeFOV = 6
|
||||
SWEP.RTScopeAttachment = 3
|
||||
SWEP.Scoped = false
|
||||
SWEP.BoltAction = false
|
||||
SWEP.ScopeLegacyOrientation = false --used to align with eyeangles instead of vm angles
|
||||
SWEP.ScopeAngleTransforms = {}
|
||||
--{"P",1} --Pitch, 1
|
||||
--{"Y",1} --Yaw, 1
|
||||
--{"R",1} --Roll, 1
|
||||
SWEP.ScopeOverlayTransforms = {0, 0}
|
||||
SWEP.ScopeOverlayTransformMultiplier = 0.8
|
||||
SWEP.RTMaterialOverride = 1
|
||||
SWEP.IronSightsSensitivity = 1
|
||||
SWEP.ScopeShadow = nil
|
||||
SWEP.ScopeReticule = nil
|
||||
SWEP.ScopeDirt = nil
|
||||
SWEP.ScopeReticule_CrossCol = false
|
||||
SWEP.ScopeReticule_Scale = {1, 1}
|
||||
--[[End of Tweakable Parameters]]--
|
||||
SWEP.Scoped_3D = true
|
||||
SWEP.BoltAction_3D = false
|
||||
|
||||
SWEP.Base = "tfa_gun_base"
|
||||
|
||||
weapons.Register(SWEP, "tfa_3dscoped_base")
|
||||
|
||||
weapons.Register({
|
||||
Base = "tfa_gun_base",
|
||||
|
||||
Secondary = {
|
||||
ScopeZoom = 0,
|
||||
UseACOG = false,
|
||||
UseMilDot = false,
|
||||
UseSVD = false,
|
||||
UseParabolic = false,
|
||||
UseElcan = false,
|
||||
UseGreenDuplex = false,
|
||||
},
|
||||
|
||||
Scoped = true,
|
||||
BoltAction = false,
|
||||
}, "tfa_scoped_base")
|
||||
|
||||
local ammo = {
|
||||
["357"] = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "357",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/357ammo.mdl",
|
||||
AmmoCount = 25,
|
||||
AmmoType = "357",
|
||||
DrawText = true,
|
||||
TextColor = Color(225, 225, 225, 255),
|
||||
TextPosition = Vector(5, 0, 7.5),
|
||||
TextAngles = Vector(42, 90, 0),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 50,
|
||||
},
|
||||
|
||||
ar2 = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "Assault Ammo",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/BoxMRounds.mdl",
|
||||
AmmoCount = 100,
|
||||
AmmoType = "ar2",
|
||||
DrawText = true,
|
||||
TextColor = Color(5, 5, 5, 255),
|
||||
TextPosition = Vector(2, 1.5, 13.4),
|
||||
TextAngles = Vector(90, 90, 90),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 35,
|
||||
Text = "Assault Ammo",
|
||||
},
|
||||
|
||||
buckshot = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "Buckshot",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/BoxBuckshot.mdl",
|
||||
AmmoCount = 20,
|
||||
AmmoType = "buckshot",
|
||||
DrawText = true,
|
||||
TextColor = Color(225, 225, 225, 255),
|
||||
TextPosition = Vector(2, 3.54, 3),
|
||||
TextAngles = Vector(0, 90, 90),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 40,
|
||||
Text = "Buckshot",
|
||||
},
|
||||
|
||||
pistol = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "Pistol Rounds",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/BoxSRounds.mdl",
|
||||
AmmoCount = 100,
|
||||
AmmoType = "pistol",
|
||||
DrawText = true,
|
||||
TextColor = Color(255, 255, 255, 255),
|
||||
TextPosition = Vector(2, 1.5, 11.6),
|
||||
TextAngles = Vector(90, 90, 90),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 40,
|
||||
Text = "Pistol Rounds",
|
||||
},
|
||||
|
||||
smg = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "SMG Rounds",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/BoxSRounds.mdl",
|
||||
AmmoCount = 100,
|
||||
AmmoType = "smg1",
|
||||
DrawText = true,
|
||||
TextColor = Color(255, 255, 255, 255),
|
||||
TextPosition = Vector(2, 1.5, 11.6),
|
||||
TextAngles = Vector(90, 90, 90),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 20,
|
||||
Text = "SMG Rounds",
|
||||
},
|
||||
|
||||
smg1_grenade = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "SMG Grenade",
|
||||
Category = "TFA Ammunition",
|
||||
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
|
||||
MyModel = "models/items/tfa/ar2_grenade.mdl",
|
||||
|
||||
AmmoType = "SMG1_Grenade",
|
||||
AmmoCount = 1,
|
||||
|
||||
DamageThreshold = 15,
|
||||
},
|
||||
|
||||
smg1_grenade_large = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "SMG Grenades",
|
||||
Category = "TFA Ammunition",
|
||||
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
|
||||
MyModel = "models/items/tfa/boxar2grenades.mdl",
|
||||
|
||||
AmmoType = "SMG1_Grenade",
|
||||
AmmoCount = 5,
|
||||
|
||||
DamageThreshold = 55,
|
||||
},
|
||||
|
||||
sniper_rounds = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "Sniper Ammo",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/sniper_round_box.mdl",
|
||||
AmmoCount = 30,
|
||||
AmmoType = "SniperPenetratedRound",
|
||||
DrawText = true,
|
||||
TextColor = Color(185, 25, 25, 255),
|
||||
TextPosition = Vector(1, -1.45, 2.1),
|
||||
TextAngles = Vector(90, 0, 0),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 80,
|
||||
Text = "Sniper Rounds",
|
||||
TextScale = 0.5,
|
||||
},
|
||||
|
||||
winchester = {
|
||||
Type = "anim",
|
||||
Base = "tfa_ammo_base",
|
||||
PrintName = "Winchester Ammo",
|
||||
Category = "TFA Ammunition",
|
||||
Spawnable = true,
|
||||
AdminSpawnable = true,
|
||||
Class = "",
|
||||
MyModel = "models/Items/sniper_round_box.mdl",
|
||||
AmmoCount = 50,
|
||||
AmmoType = "AirboatGun",
|
||||
DrawText = true,
|
||||
TextColor = Color(185, 25, 25, 255),
|
||||
TextPosition = Vector(1, -1.45, 1.5),
|
||||
TextAngles = Vector(90, 0, 0),
|
||||
ShouldDrawShadow = true,
|
||||
ImpactSound = "Default.ImpactSoft",
|
||||
Damage = 30,
|
||||
Text = ".308",
|
||||
}
|
||||
}
|
||||
|
||||
for ammoclass, ENT in pairs(ammo) do
|
||||
scripted_ents.Register(ENT, "tfa_ammo_" .. ammoclass)
|
||||
end
|
||||
81
lua/tfa/modules/tfa_snd_timescale.lua
Normal file
81
lua/tfa/modules/tfa_snd_timescale.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
--[[
|
||||
| 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 sv_cheats_cv = GetConVar("sv_cheats")
|
||||
local host_timescale_cv = GetConVar("host_timescale")
|
||||
local ts
|
||||
|
||||
local en_cvar = GetConVar("sv_tfa_soundscale")
|
||||
|
||||
hook.Add("EntityEmitSound", "zzz_TFA_EntityEmitSound", function(soundData)
|
||||
local ent = soundData.Entity
|
||||
local modified
|
||||
local weapon
|
||||
|
||||
if ent:IsWeapon() then
|
||||
weapon = ent
|
||||
elseif ent:IsNPC() or ent:IsPlayer() then
|
||||
weapon = ent:GetActiveWeapon()
|
||||
end
|
||||
|
||||
if IsValid(weapon) and weapon.IsTFA and weapon.IsTFAWeapon then
|
||||
if weapon.GonnaAdjuctPitch then
|
||||
soundData.Pitch = soundData.Pitch * weapon.RequiredPitch
|
||||
weapon.GonnaAdjuctPitch = false
|
||||
modified = true
|
||||
end
|
||||
|
||||
if weapon.GonnaAdjustVol then
|
||||
soundData.Volume = soundData.Volume * weapon.RequiredVolume
|
||||
weapon.GonnaAdjustVol = false
|
||||
modified = true
|
||||
end
|
||||
end
|
||||
|
||||
if not en_cvar then return modified end
|
||||
if not en_cvar:GetBool() then return modified end
|
||||
ts = game.GetTimeScale()
|
||||
|
||||
if sv_cheats_cv:GetBool() then
|
||||
ts = ts * host_timescale_cv:GetFloat()
|
||||
end
|
||||
|
||||
if engine.GetDemoPlaybackTimeScale then
|
||||
ts = ts * engine.GetDemoPlaybackTimeScale()
|
||||
end
|
||||
|
||||
if ts ~= 1 then
|
||||
soundData.Pitch = math.Clamp(soundData.Pitch * ts, 0, 255)
|
||||
return true
|
||||
end
|
||||
|
||||
return modified
|
||||
end)
|
||||
160
lua/tfa/modules/tfa_soundscripts.lua
Normal file
160
lua/tfa/modules/tfa_soundscripts.lua
Normal file
@@ -0,0 +1,160 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
sound.Add({
|
||||
name = "Weapon_Bow.1",
|
||||
channel = CHAN_STATIC,
|
||||
volume = 1.0,
|
||||
sound = {"weapons/tfbow/fire1.wav", "weapons/tfbow/fire2.wav", "weapons/tfbow/fire3.wav"}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "Weapon_Bow.boltpull",
|
||||
channel = CHAN_USER_BASE + 11,
|
||||
volume = 1.0,
|
||||
sound = {"weapons/tfbow/pull1.wav", "weapons/tfbow/pull2.wav", "weapons/tfbow/pull3.wav"}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.NearlyEmpty",
|
||||
channel = CHAN_USER_BASE + 15,
|
||||
volume = 1,
|
||||
pitch = 100,
|
||||
level = 65,
|
||||
sound = "weapons/tfa/lowammo.wav"
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.Bash",
|
||||
channel = CHAN_USER_BASE + 14,
|
||||
volume = 1.0,
|
||||
sound = {"weapons/tfa/bash1.wav", "weapons/tfa/bash2.wav"},
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.BashWall",
|
||||
channel = CHAN_USER_BASE + 14,
|
||||
volume = 1.0,
|
||||
sound = "weapons/melee/rifle_swing_hit_world.wav",
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.BashFlesh",
|
||||
channel = CHAN_USER_BASE + 14,
|
||||
volume = 1.0,
|
||||
sound = {"weapons/melee/rifle_swing_hit_infected7.wav", "weapons/melee/rifle_swing_hit_infected8.wav", "weapons/melee/rifle_swing_hit_infected9.wav", "weapons/melee/rifle_swing_hit_infected10.wav", "weapons/melee/rifle_swing_hit_infected11.wav", "weapons/melee/rifle_swing_hit_infected12.wav"},
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.IronIn",
|
||||
channel = CHAN_USER_BASE + 13,
|
||||
volume = 1.0,
|
||||
sound = {"weapons/tfa/ironin.wav"},
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.IronOut",
|
||||
channel = CHAN_USER_BASE + 13,
|
||||
volume = 1.0,
|
||||
sound = {"weapons/tfa/ironout.wav"},
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "Weapon_Pistol.Empty2",
|
||||
channel = CHAN_USER_BASE + 11,
|
||||
volume = 1.0,
|
||||
level = 80,
|
||||
sound = {"weapons/pistol/pistol_empty.wav"},
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "Weapon_AR2.Empty2",
|
||||
channel = CHAN_USER_BASE + 11,
|
||||
volume = 1.0,
|
||||
level = 80,
|
||||
sound = {"weapons/ar2/ar2_empty.wav"},
|
||||
pitch = {97, 103}
|
||||
})
|
||||
|
||||
sound.Add({
|
||||
name = "TFA.LowAmmo",
|
||||
channel = CHAN_USER_BASE + 15,
|
||||
volume = 1.0,
|
||||
level = 75,
|
||||
pitch = 100,
|
||||
sound = ")weapons/tfa/lowammo_indicator_automatic.wav"
|
||||
})
|
||||
sound.Add({
|
||||
name = "TFA.LowAmmo_Dry",
|
||||
channel = CHAN_USER_BASE + 15,
|
||||
volume = 1.0,
|
||||
level = 75,
|
||||
pitch = 100,
|
||||
sound = ")weapons/tfa/lowammo_dry_automatic.wav"
|
||||
})
|
||||
|
||||
local ammos = {
|
||||
["Handgun"] = "handgun",
|
||||
["Shotgun"] = "shotgun",
|
||||
["AutoShotgun"] = "shotgun_auto",
|
||||
["MachineGun"] = "mg",
|
||||
["AssaultRifle"] = "ar",
|
||||
["DMR"] = "dmr",
|
||||
["Revolver"] = "revolver",
|
||||
["Sniper"] = "sr",
|
||||
["SMG"] = "smg",
|
||||
["SciFi"] = "scifi",
|
||||
["GL"] = "gl",
|
||||
}
|
||||
for k,v in pairs(ammos) do
|
||||
sound.Add({
|
||||
name = "TFA.LowAmmo." .. k, -- "TFA.LowAmmo.Handgun"
|
||||
channel = CHAN_USER_BASE + 15,
|
||||
volume = 1.0,
|
||||
level = 75,
|
||||
pitch = 100,
|
||||
sound = ")weapons/tfa/lowammo_indicator_" .. v .. ".wav"
|
||||
})
|
||||
sound.Add({
|
||||
name = "TFA.LowAmmo." .. k .. "_Dry", -- "TFA.LowAmmo.Handgun_Dry"
|
||||
channel = CHAN_USER_BASE + 15,
|
||||
volume = 1.0,
|
||||
level = 75,
|
||||
pitch = 100,
|
||||
sound = ")weapons/tfa/lowammo_dry_" .. v .. ".wav"
|
||||
})
|
||||
end
|
||||
176
lua/tfa/modules/tfa_tttpatch.lua
Normal file
176
lua/tfa/modules/tfa_tttpatch.lua
Normal file
@@ -0,0 +1,176 @@
|
||||
--[[
|
||||
| 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.
|
||||
|
||||
if engine.ActiveGamemode() ~= "terrortown" then return end
|
||||
|
||||
-- luacheck: globals WEAPON_NONE WEAPON_MELEE WEAPON_PISTOL WEAPON_HEAVY WEAPON_NADE WEAPON_CARRY WEAPON_EQUIP1 WEAPON_EQUIP2 WEAPON_ROLE WEAPON_EQUIP WEAPON_UNARMED ROLE_INNOCENT ROLE_TRAITOR ROLE_DETECTIVE ROLE_NONE
|
||||
WEAPON_NONE = WEAPON_NONE or 0
|
||||
WEAPON_MELEE = WEAPON_MELEE or 1
|
||||
WEAPON_PISTOL = WEAPON_PISTOL or 2
|
||||
WEAPON_HEAVY = WEAPON_HEAVY or 3
|
||||
WEAPON_NADE = WEAPON_NADE or 4
|
||||
WEAPON_CARRY = WEAPON_CARRY or 5
|
||||
WEAPON_EQUIP1 = WEAPON_EQUIP1 or 6
|
||||
WEAPON_EQUIP2 = WEAPON_EQUIP2 or 7
|
||||
WEAPON_ROLE = WEAPON_ROLE or 8
|
||||
WEAPON_EQUIP = WEAPON_EQUIP or WEAPON_EQUIP1
|
||||
WEAPON_UNARMED = WEAPON_UNARMED or -1
|
||||
ROLE_INNOCENT = ROLE_INNOCENT or 0
|
||||
ROLE_TRAITOR = ROLE_TRAITOR or 1
|
||||
ROLE_DETECTIVE = ROLE_DETECTIVE or 2
|
||||
ROLE_NONE = ROLE_NONE or ROLE_INNOCENT
|
||||
|
||||
local KindTable = {
|
||||
[0] = WEAPON_MELEE,
|
||||
[1] = WEAPON_PISTOL,
|
||||
[2] = WEAPON_HEAVY,
|
||||
[3] = WEAPON_HEAVY,
|
||||
[4] = WEAPON_HEAVY,
|
||||
[5] = WEAPON_EQUIP1,
|
||||
[6] = WEAPON_EQUIP2
|
||||
}
|
||||
|
||||
local TypeStrings = {
|
||||
[WEAPON_NONE] = "Invalid",
|
||||
[WEAPON_MELEE] = "Melee",
|
||||
[WEAPON_PISTOL] = "Pistol",
|
||||
[WEAPON_HEAVY] = "Heavy",
|
||||
[WEAPON_NADE] = "Grenade",
|
||||
[WEAPON_CARRY] = "Carry",
|
||||
[WEAPON_EQUIP1] = "Equipment",
|
||||
[WEAPON_EQUIP2] = "Equipment",
|
||||
[WEAPON_ROLE] = "Role"
|
||||
}
|
||||
|
||||
local function PatchWep(wep)
|
||||
if not weapons.IsBasedOn(wep, "tfa_gun_base") then return end
|
||||
if wep:find("base") then return end
|
||||
|
||||
local tbl = weapons.GetStored(wep)
|
||||
if not tbl then return end
|
||||
|
||||
tbl.AllowSprintAttack = true -- no sprinting ever, running convar is a dumb idea
|
||||
|
||||
if (not tbl.Kind) or (not isnumber(tbl.Kind)) then
|
||||
tbl.Kind = KindTable[tbl.Slot or 2] or WEAPON_HEAVY
|
||||
|
||||
if (tbl.ProjectileVelocity and tbl.ProjectileVelocity < 1000 and tbl.ProjectileVelocity > 0) or string.find(tbl.Base or "", "nade") then
|
||||
tbl.Kind = WEAPON_NADE
|
||||
end
|
||||
|
||||
if tbl.IsMelee then
|
||||
tbl.Kind = WEAPON_MELEE
|
||||
end
|
||||
|
||||
if not tbl.Spawnable then
|
||||
tbl.Kind = WEAPON_NONE
|
||||
end
|
||||
end
|
||||
|
||||
--if not tbl.Icon then
|
||||
-- tbl.Icon = nil--"vgui/entities/" .. wep
|
||||
--end
|
||||
tbl.model = tbl.model or tbl.WorldModel
|
||||
|
||||
if not tbl.CanBuy then
|
||||
--if tbl.Spawnable then
|
||||
-- tbl.CanBuy = { ROLE_TRAITOR, ROLE_DETECTIVE }
|
||||
--else
|
||||
tbl.CanBuy = {}
|
||||
--end
|
||||
end
|
||||
|
||||
for _, v in pairs(tbl.CanBuy) do
|
||||
if v ~= ROLE_TRAITOR and v ~= ROLE_DETECTIVE then
|
||||
table.RemoveByValue(tbl.CanBuy, v)
|
||||
end
|
||||
end
|
||||
|
||||
if (not tbl.Icon) or (string.len(tbl.Icon) <= 0) then
|
||||
tbl.Icon = nil
|
||||
if file.Exists("materials/entities/" .. wep .. ".png", "GAME") then
|
||||
tbl.Icon = "entities/" .. wep .. ".png"
|
||||
elseif file.Exists("materials/vgui/entities/" .. wep .. ".vmt", "GAME") then
|
||||
tbl.Icon = "vgui/entities/" .. wep
|
||||
end
|
||||
end
|
||||
|
||||
if tbl.LimitedStock == nil then
|
||||
tbl.LimitedStock = false
|
||||
end
|
||||
|
||||
if not tbl.EquipMenuData then
|
||||
tbl.EquipMenuData = {
|
||||
["type"] = TypeStrings[tbl.Kind],
|
||||
["desc"] = tbl.PrintName or wep
|
||||
}
|
||||
end
|
||||
|
||||
if tbl.IsSilent == nil then
|
||||
tbl.IsSilent = false
|
||||
end
|
||||
|
||||
if tbl.NoSights == nil then
|
||||
if tbl.data then
|
||||
tbl.NoSights = tbl.Secondary.IronSightsEnabled == false or tbl.data and tbl.data.ironsights ~= 0 or false
|
||||
end
|
||||
|
||||
if tbl.NoSights == nil then
|
||||
tbl.NoSights = false
|
||||
end
|
||||
end
|
||||
|
||||
if tbl.AutoSpawnable == nil then
|
||||
tbl.AutoSpawnable = tbl.Spawnable
|
||||
end
|
||||
end
|
||||
|
||||
local function Patch()
|
||||
for _, v in pairs(weapons.GetList()) do
|
||||
local wep = v.ClassName
|
||||
|
||||
if wep then
|
||||
PatchWep(wep)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
hook.Add("Initialize", "TFAPatchTTT", Patch)
|
||||
end
|
||||
if CLIENT then
|
||||
hook.Add("HUDPaint", "TFAPatchTTT", function()
|
||||
if LocalPlayer():IsValid() then
|
||||
Patch()
|
||||
hook.Remove("HUDPaint","TFAPatchTTT")
|
||||
end
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user