This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 8064ba84d8
commit 9c918c46e5
7081 changed files with 2173485 additions and 14 deletions

View 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")

View 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" )

View 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" )

View 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)

View 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

View 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

View 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")

View 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)

View 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

View 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

View 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)

View 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

View 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)

View 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

View 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)

View 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

View 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)

View 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)

View 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)

View 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)

View 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
})

View 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)
]]
--

View 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)

View 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)

View 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

View 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)

View 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

View 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

View 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

View 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

View 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)

View 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
})
]]

View 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

View 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
}
}
]]

View 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
]]
--

View 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

View 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

View 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

View 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()

View 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()

View 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

View 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)

View 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

View 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