This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 0e770b2b49
commit ba1fc01b16
7084 changed files with 2173495 additions and 14 deletions

View File

@@ -0,0 +1,366 @@
--[[
| 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 SWEP = {}
local BaseClass = baseclass.Get("tfa_gun_base")
local scopecvar = GetConVar("cl_tfa_3dscope")
local scopeshadowcvar = GetConVar("cl_tfa_3dscope_overlay")
local sp = game.SinglePlayer()
function SWEP:Do3DScope()
if scopecvar then
return scopecvar:GetBool()
else
if self:OwnerIsValid() and self:GetOwner().GetInfoNum then
return self:GetOwner():GetInfoNum("cl_tfa_3dscope", 1) == 1
else
return true
end
end
end
function SWEP:Do3DScopeOverlay()
if scopeshadowcvar then
return scopeshadowcvar:GetBool()
else
return false
end
end
function SWEP:UpdateScopeType(force)
if not self.HasInitialized then return end
local target = self.Secondary_TFA or self.Secondary
if self.Scoped_3D and force then
self.Scoped = true
self.Scoped_3D = false
if target.ScopeZoom_Backup then
target.ScopeZoom = target.ScopeZoom_Backup
else
target.ScopeZoom = 90 / self:GetStatRawL("Secondary.OwnerFOV") -- M9K/Older TFA Base compatibility
end
if self.BoltAction_3D then
self.BoltAction = true
self.BoltAction_3D = nil
self:ClearStatCache("BoltAction")
end
self:SetStatRawL("Secondary.OwnerFOV", 90 / self:GetStatRawL("Secondary.ScopeZoom"))
self.IronSightsSensitivity = 1
end
if self:Do3DScope() then
self.Scoped = false
self.Scoped_3D = true
if not target.ScopeZoom_Backup then
target.ScopeZoom_Backup = target.ScopeZoom
end
if self.BoltAction then
self.BoltAction_3D = true
self.BoltAction = self.BoltAction_Forced or false
self.Primary.DisableChambering = true
self.FireModeName = "tfa.firemode.bolt"
end
if target.ScopeZoom and target.ScopeZoom > 0 then
if CLIENT then
self.RTScopeFOV = 90 / target.ScopeZoom * (target.ScopeScreenScale or 0.392592592592592)
end
-- target.IronFOV_Backup = self:GetStatRawL("Secondary.OwnerFOV", 70)
-- self:SetStatRawL("Secondary.OwnerFOV", 70)
-- self:ClearStatCacheL("Secondary.OwnerFOV")
if CLIENT then
self.IronSightsSensitivity = self:Get3DSensitivity()
end
target.ScopeZoom = false
end
else
self.Scoped = true
self.Scoped_3D = false
if target.ScopeZoom_Backup then
target.ScopeZoom = target.ScopeZoom_Backup
else
target.ScopeZoom = 4
end
if self.BoltAction_3D then
self.BoltAction = true
self.BoltAction_3D = nil
self:ClearStatCache("BoltAction")
end
self:SetStatRawL("Secondary.OwnerFOV", 90 / target.ScopeZoom)
self.IronSightsSensitivity = 1
self:ClearStatCacheL("Secondary.OwnerFOV")
end
end
function SWEP:Initialize(...)
local unsetA = self.Primary_TFA == nil
local unsetB = self.Secondary_TFA == nil
self.Primary_TFA = self.Primary_TFA or self.Primary
self.Secondary_TFA = self.Secondary_TFA or self.Secondary
self:UpdateScopeType()
if unsetA then
self.Primary_TFA = nil
end
if unsetB then
self.Secondary_TFA = nil
end
BaseClass.Initialize(self, ...)
timer.Simple(0, function()
if IsValid(self) and self:OwnerIsValid() then
self:UpdateScopeType()
end
end)
end
function SWEP:Deploy(...)
if SERVER and self:OwnerIsValid() and sp then
self:CallOnClient("UpdateScopeType", "")
end
self:UpdateScopeType()
timer.Simple(0, function()
if IsValid(self) and self:OwnerIsValid() then
self:UpdateScopeType()
end
end)
return BaseClass.Deploy(self,...)
end
local flipcv = GetConVar("cl_tfa_viewmodel_flip")
local cd = {}
local crosscol = Color(255, 255, 255, 255)
SWEP.RTOpaque = true
local cv_cc_r = GetConVar("cl_tfa_hud_crosshair_color_r")
local cv_cc_g = GetConVar("cl_tfa_hud_crosshair_color_g")
local cv_cc_b = GetConVar("cl_tfa_hud_crosshair_color_b")
local cv_cc_a = GetConVar("cl_tfa_hud_crosshair_color_a")
SWEP.defaultscrvec = Vector()
function SWEP:RTCode(rt, scrw, scrh)
local legacy = self.ScopeLegacyOrientation
local rttw = ScrW()
local rtth = ScrH()
if not self:VMIV() then return end
if not self.myshadowmask then
self.myshadowmask = surface.GetTextureID(self.ScopeShadow or "vgui/scope_shadowmask_test")
end
if not self.myreticule then
self.myreticule = Material(self.ScopeReticule or "scope/gdcw_scopesightonly")
end
if not self.mydirt then
self.mydirt = Material(self.ScopeDirt or "vgui/scope_dirt")
end
local vm = self.OwnerViewModel
if not self.LastOwnerPos then
self.LastOwnerPos = self:GetOwner():GetShootPos()
end
local owoff = self:GetOwner():GetShootPos() - self.LastOwnerPos
self.LastOwnerPos = self:GetOwner():GetShootPos()
local scrpos
if self.RTScopeAttachment and self.RTScopeAttachment > 0 then
vm:SetupBones()
local att = vm:GetAttachment( self.RTScopeAttachment or 1 )
if not att then return end
local pos = att.Pos - owoff
cam.Start3D()
cam.End3D()
scrpos = pos:ToScreen()
else
self.defaultscrvec.x = scrw / 2
self.defaultscrvec.y = scrh / 2
scrpos = self.defaultscrvec
end
scrpos.x = scrpos.x - scrw / 2 + self.ScopeOverlayTransforms[1]
scrpos.y = scrpos.y - scrh / 2 + self.ScopeOverlayTransforms[2]
scrpos.x = scrpos.x / scrw * 1920
scrpos.y = scrpos.y / scrw * 1920
scrpos.x = math.Clamp(scrpos.x, -1024, 1024)
scrpos.y = math.Clamp(scrpos.y, -1024, 1024)
--scrpos.x = scrpos.x * ( 2 - self:GetIronSightsProgress()*1 )
--scrpos.y = scrpos.y * ( 2 - self:GetIronSightsProgress()*1 )
scrpos.x = scrpos.x * self.ScopeOverlayTransformMultiplier
scrpos.y = scrpos.y * self.ScopeOverlayTransformMultiplier
if not self.scrpos then
self.scrpos = scrpos
end
self.scrpos.x = math.Approach(self.scrpos.x, scrpos.x, (scrpos.x - self.scrpos.x) * FrameTime() * 10)
self.scrpos.y = math.Approach(self.scrpos.y, scrpos.y, (scrpos.y - self.scrpos.y) * FrameTime() * 10)
scrpos = self.scrpos
render.OverrideAlphaWriteEnable(true, true)
surface.SetDrawColor(color_white)
surface.DrawRect(-512, -512, 1024, 1024)
render.OverrideAlphaWriteEnable(true, true)
local ang = legacy and self:GetOwner():EyeAngles() or vm:GetAngles()
if self.RTScopeAttachment and self.RTScopeAttachment > 0 then
vm:SetupBones()
local AngPos = vm:GetAttachment( self.RTScopeAttachment )
if AngPos then
ang = AngPos.Ang
if flipcv:GetBool() then
ang.y = -ang.y
end
for _, v in pairs(self.ScopeAngleTransforms) do
if v[1] == "P" then
ang:RotateAroundAxis(ang:Right(), v[2])
elseif v[1] == "Y" then
ang:RotateAroundAxis(ang:Up(), v[2])
elseif v[1] == "R" then
ang:RotateAroundAxis(ang:Forward(), v[2])
end
end
end
else
local isang = self:GetStatL("IronSightsAngle") * self:GetIronSightsProgress()
ang:RotateAroundAxis(ang:Forward(), -isang.z)
ang:RotateAroundAxis(ang:Right(), -isang.x)
ang:RotateAroundAxis(ang:Up(), -isang.y)
ang:RotateAroundAxis(ang:Forward(), isang.z)
end
cd.angles = ang
cd.origin = self:GetOwner():GetShootPos()
if not self.RTScopeOffset then
self.RTScopeOffset = {0, 0}
end
if not self.RTScopeScale then
self.RTScopeScale = {1, 1}
end
local rtow, rtoh = self.RTScopeOffset[1], self.RTScopeOffset[2]
local rtw, rth = rttw * self.RTScopeScale[1], rtth * self.RTScopeScale[2]
cd.x = 0
cd.y = 0
cd.w = rtw
cd.h = rth
cd.fov = self.RTScopeFOV
cd.drawviewmodel = false
cd.drawhud = false
render.Clear(0, 0, 0, 255, true, true)
render.SetScissorRect(0 + rtow, 0 + rtoh, rtw + rtow, rth + rtoh, true)
if self:GetIronSightsProgress() > 0.01 and self.Scoped_3D then
render.RenderView(cd)
end
render.SetScissorRect(0, 0, rtw, rth, false)
render.OverrideAlphaWriteEnable(false, true)
cam.Start2D()
draw.NoTexture()
surface.SetTexture(self.myshadowmask)
surface.SetDrawColor(color_white)
if self:Do3DScopeOverlay() then
surface.DrawTexturedRect(scrpos.x + rtow - rtw / 2, scrpos.y + rtoh - rth / 2, rtw * 2, rth * 2)
end
if self.ScopeReticule_CrossCol then
crosscol.r = cv_cc_r:GetFloat()
crosscol.g = cv_cc_g:GetFloat()
crosscol.b = cv_cc_b:GetFloat()
crosscol.a = cv_cc_a:GetFloat()
surface.SetDrawColor(crosscol)
end
surface.SetMaterial(self.myreticule)
local tmpborderw = rtw * (1 - self.ScopeReticule_Scale[1]) / 2
local tmpborderh = rth * (1 - self.ScopeReticule_Scale[2]) / 2
surface.DrawTexturedRect(rtow + tmpborderw, rtoh + tmpborderh, rtw - tmpborderw * 2, rth - tmpborderh * 2)
surface.SetDrawColor(color_black)
draw.NoTexture()
if self:Do3DScopeOverlay() then
surface.DrawRect(scrpos.x - 2048 + rtow, -1024 + rtoh, 2048, 2048)
surface.DrawRect(scrpos.x + rtw + rtow, -1024 + rtoh, 2048, 2048)
surface.DrawRect(-1024 + rtow, scrpos.y - 2048 + rtoh, 2048, 2048)
surface.DrawRect(-1024 + rtow, scrpos.y + rth + rtoh, 2048, 2048)
end
surface.SetDrawColor(ColorAlpha(color_black, 255 - 255 * (math.Clamp(self:GetIronSightsProgress() - 0.75, 0, 0.25) * 4)))
surface.DrawRect(-1024 + rtow, -1024 + rtoh, 2048, 2048)
surface.SetMaterial(self.mydirt)
surface.SetDrawColor(ColorAlpha(color_white, 128))
surface.DrawTexturedRect(0, 0, rtw, rth)
surface.SetDrawColor(ColorAlpha(color_white, 64))
surface.DrawTexturedRectUV(rtow, rtoh, rtw, rth, 2, 0, 0, 2)
cam.End2D()
end
return SWEP

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.
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "G.I.B Ammunition"
ATTACHMENT.ShortName = "GIB" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Always gibs enemies", TFA.Attachments.Colors["+"], "10% more damage", TFA.Attachments.Colors["-"], "20% more recoil", TFA.Attachments.Colors["-"], "10% more spread" }
ATTACHMENT.Icon = "entities/tfa_ammo_gib.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["Primary"] = {
["DamageType"] = function(wep,stat) return bit.bor( stat or DMG_BULLET, DMG_ALWAYSGIB ) end,
["Damage"] = function( wep, stat ) return stat * 1.1 end,
["Spread"] = function( wep, stat ) return stat * 1.1 end,
["IronAccuracy"] = function( wep, stat ) return stat * 1.1 end,
["KickUp"] = function( wep, stat ) return stat * 1.2 end,
["KickDown"] = function( wep, stat ) return stat * 1.2 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,55 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Magnum Ammunition"
ATTACHMENT.ShortName = "MAG" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "10% more damage", TFA.Attachments.Colors["-"], "15% more recoil", TFA.Attachments.Colors["-"], "10% more spread" }
ATTACHMENT.Icon = "entities/tfa_ammo_magnum.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["Primary"] = {
["Damage"] = function( wep, stat ) return stat * 1.1 end,
["Spread"] = function( wep, stat ) return stat * 1.1 end,
["IronAccuracy"] = function( wep, stat ) return stat * 1.1 end,
["KickUp"] = function( wep, stat ) return stat * 1.15 end,
["KickDown"] = function( wep, stat ) return stat * 1.15 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,54 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Match Ammunition"
ATTACHMENT.ShortName = "Match" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "20% lower spread kick", "10% lower recoil", TFA.Attachments.Colors["-"], "20% lower spread recovery" }
ATTACHMENT.Icon = "entities/tfa_ammo_match.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["Primary"] = {
["SpreadIncrement"] = function( wep, stat ) return stat * 0.9 end,
["SpreadRecovery"] = function( wep, stat ) return stat * 0.8 end,
["KickUp"] = function( wep, stat ) return stat * 0.9 end,
["KickDown"] = function( wep, stat ) return stat * 0.9 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,37 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Dragon's Breath Shells"
ATTACHMENT.ShortName = "Fire" -- Abbreviation, 5 chars or less please
ATTACHMENT.Icon = "entities/dragon_breach_shell.png" -- Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.Description = {
TFA.Attachments.Colors["+"], "Ignites enemies or objects",
TFA.Attachments.Colors["+"], "Stun enemies with fire",
TFA.Attachments.Colors["+"], "+8 Pellets",
TFA.Attachments.Colors["-"], "+100% Spread", "-50% Damage" }
ATTACHMENT.WeaponTable = {
["Primary"] = {
["DamageType"] = function(wep,stat) return bit.bor( stat or 0, DMG_BURN ) end,
["NumShots"] = function( wep, stat ) return stat + 8 end,
["Spread"] = function(wep,stat) return stat * 2 end,
["IronAccuracy"] = function( wep, stat ) return stat * 1.5 end,
["Damage"] = function(wep,stat) return stat * 0.5 end,
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,38 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Flechette Shells" -- Fully attachment name
ATTACHMENT.ShortName = "Flechette" -- Abbreviation, 5 chars or less please
ATTACHMENT.Icon = "entities/flechetterounds.png" -- Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.Description = {
TFA.AttachmentColors["="], "Flechette Darts",
TFA.AttachmentColors["+"], "Improves the accuracy",
TFA.AttachmentColors["+"], "Improves the penetration",
TFA.AttachmentColors["+"], "+8 Pellets",
TFA.AttachmentColors["-"], "-50% Damage"}
ATTACHMENT.WeaponTable = {
["Primary"] = {
["IronAccuracy"] = function( wep, stat ) return math.max( stat * 0.75 ) end,
["Spread"] = function( wep, stat ) return math.max( stat * 0.75 ) end,
["PenetrationMultiplier"] = function( wep, stat ) return stat * 2 end,
["NumShots"] = function( wep, stat ) return stat + 8 end,
["Damage"] = function(wep,stat) return stat * 0.50 end,
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Extended Magazine"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "Increases magazine capacity to 60 rounds."
}
ATTACHMENT.Icon = "entities/ins2_att_mag_ext_carbine_30rd.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "MAG+"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["mag"] = {
["active"] = false,
},
["mag_ext"] = {
["active"] = true,
}
},
["WElements"] = {
["mag"] = {
["active"] = false,
},
["mag_ext"] = {
["active"] = true,
}
},
["Primary"] = {
["ClipSize"] = function(wep, val)
return wep.Primary.ClipSize_Drum or 60
end,
},
}
function ATTACHMENT:Attach(wep)
wep:Unload()
end
function ATTACHMENT:Detach(wep)
wep:Unload()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,69 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "RIS Extended Handguard"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "Activates Laser Sight and GL", "5% lower recoil", TFA.AttachmentColors["-"], "25% lower base accuracy", "Somewhat slower movespeed" }
ATTACHMENT.Icon = "entities/ar15_att_ris_e.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "RISE"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["basebarrel"] = {
["active"] = false
},
["risextbarrel"] = {
["active"] = true
}
},
["Bodygroups_W"] = {
[2] = 4
},
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(1.1, 1.1, 1.1), pos = Vector(0, -13, -0.1), angle = Angle(0, 180, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(0.7, 0.7, 0.7), pos = Vector(14, -1.4, 0.75), angle = Angle(0, 180, 0) },
},
["Primary"] = {
["KickUp"] = function(wep,stat) return stat * 0.9 end,
["KickDown"] = function(wep,stat) return stat * 0.9 end,
["KickHorizontal"] = function(wep,stat) return stat * 0.9 end,
["Spread"] = function(wep,stat) return stat * 1.5 end,
},
["MoveSpeed"] = function(wep,stat) return stat * 0.95 end,
["IronSightsMoveSpeed"] = function(wep,stat) return stat * 0.95 end,
}
function ATTACHMENT:Detach(wep)
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep.ViewModelKitOld = nil
end
if wep.WorldModelKitOld then
wep.WorldModel = wep.WorldModelKitOld
wep:SetModel(wep.WorldModel)
wep.ViewModelKitOld = nil
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,67 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "M16 Handguard"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "60% less vertical recoil", "20% less horizontal recoil", TFA.AttachmentColors["-"], "10% lower base accuracy", "Somewhat slower movespeed" }
ATTACHMENT.Icon = "entities/ar15_att_m16_b.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "M16B"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["basebarrel"] = {
["active"] = false
},
["m16barrel"] = {
["active"] = true
}
},
["Bodygroups_W"] = {
[2] = 3
},
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(1.1, 1.1, 1.1), pos = Vector(0, -13, -0.1), angle = Angle(0, 180, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(0.7, 0.7, 0.7), pos = Vector(14, -1.4, 0.75), angle = Angle(0, 180, 0) },
},
["Primary"] = {
["Spread"] = function(wep,stat) return stat * 1.2 end,
["IronAccuracy"] = function(wep,stat) return stat * 0.9 end,
},
["MoveSpeed"] = function(wep,stat) return stat * 0.95 end,
["IronSightsMoveSpeed"] = function(wep,stat) return stat * 0.95 end,
}
function ATTACHMENT:Detach(wep)
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep.ViewModelKitOld = nil
end
if wep.WorldModelKitOld then
wep.WorldModel = wep.WorldModelKitOld
wep:SetModel(wep.WorldModel)
wep.ViewModelKitOld = nil
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,62 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "M16 Stock"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "70% less vertical recoil", "30% less horizontal recoil", TFA.AttachmentColors["-"], "Somewhat slower movespeed" }
ATTACHMENT.Icon = "entities/ar15_att_m16_s.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "M16S"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["basestock"] = {
["active"] = false
},
["m16stock"] = {
["active"] = true
}
},
["Bodygroups_W"] = {
[1] = 1
},
["Primary"] = {
["KickUp"] = function(wep,stat) return stat * 0.3 end,
["KickDown"] = function(wep,stat) return stat * 0.3 end,
["KickHorizontal"] = function(wep,stat) return stat * 0.7 end
},
["MoveSpeed"] = function(wep,stat) return stat * 0.95 end,
["IronSightsMoveSpeed"] = function(wep,stat) return stat * 0.95 end,
}
function ATTACHMENT:Attach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
function ATTACHMENT:Detach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,62 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Magpul Handguard"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "60% less vertical recoil", "20% less horizontal recoil", "10% more ironsight accuracy", TFA.AttachmentColors["-"], "20% lower base accuracy" }
ATTACHMENT.Icon = "entities/ar15_att_moe_b.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "MOEB"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["basebarrel"] = {
["active"] = false
},
["magpulbarrel"] = {
["active"] = true
}
},
["Bodygroups_W"] = {
[2] = 2
},
["Primary"] = {
["KickUp"] = function(wep,stat) return stat * 0.3 end,
["KickDown"] = function(wep,stat) return stat * 0.3 end,
["KickHorizontal"] = function(wep,stat) return stat * 0.7 end,
["Spread"] = function(wep,stat) return stat * 1.1 end,
["IronAccuracy"] = function(wep,stat) return stat * 1.1 end
},
}
function ATTACHMENT:Attach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
function ATTACHMENT:Detach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,60 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Magpul Stock"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "30% less vertical recoil", "10% less horizontal recoil" }
ATTACHMENT.Icon = "entities/ar15_att_moe_s.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "MOE"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["basestock"] = {
["active"] = false
},
["magpulstock"] = {
["active"] = true
}
},
["Bodygroups_W"] = {
[1] = 2
},
["Primary"] = {
["KickUp"] = function(wep,stat) return stat * 0.7 end,
["KickDown"] = function(wep,stat) return stat * 0.7 end,
["KickHorizontal"] = function(wep,stat) return stat * 0.9 end
},
}
function ATTACHMENT:Attach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
function ATTACHMENT:Detach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "RIS Handguard"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "Activates Laser Sight and GL", TFA.AttachmentColors["-"], "5% lower base accuracy" }
ATTACHMENT.Icon = "entities/ar15_att_ris.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "RIS"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["basebarrel"] = {
["active"] = false
},
["risbarrel"] = {
["active"] = true
}
},
["Bodygroups_W"] = {
[2] = 1
},
["Primary"] = {
["Spread"] = function(wep,stat) return stat * 0.8 end,
},
}
function ATTACHMENT:Attach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
function ATTACHMENT:Detach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,45 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Folded Sights"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "Easier to aim", TFA.AttachmentColors["-"], "5% higher zoom time" }
ATTACHMENT.Icon = "entities/ins2_att_fsi.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "FSI"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["sights_folded"] = {
["active"] = false
},
["sight_fsi"] = {
["active"] = true
}
},
["WElements"] = {
["sights_folded"] = {
["active"] = false
},
["sight_fsi"] = {
["active"] = true
}
},
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng end,
["IronSightTime"] = function( wep, val ) return val * 1.05 end
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,101 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Foregrip"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "30% lower H-recoil", TFA.Attachments.Colors["+"], "10% lower V-recoil", TFA.Attachments.Colors["-"], "10% higher spread recovery" }
ATTACHMENT.Icon = "entities/tfa_si_eotech.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "FGRIP"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
local defaultbl = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
local function LerpBoneMods( t, b1, b2 )
local tbl = table.Copy(b1)
for k,v in pairs(b2) do
if not tbl[k] then
tbl[k] = table.Copy(defaultbl)
end
tbl[k].scale = LerpVector( t, tbl[k].scale, v.scale )
tbl[k].pos = LerpVector( t, tbl[k].pos, v.pos )
tbl[k].angle = LerpAngle( t, tbl[k].angle, v.angle )
end
return tbl
end
ATTACHMENT.WeaponTable = {
["ViewModelElements"] = {
["foregrip"] = {
["active"] = true
}
},
["WorldModelElements"] = {
["foregrip"] = {
["active"] = true
}
},
["Primary"] = {
["SpreadRecovery"] = function(wep,stat) return stat * 1.1 end,
["KickUp"] = function(wep,stat) return stat * 0.9 end,
["KickDown"] = function(wep,stat) return stat * 0.9 end,
["KickHorizontal"] = function(wep,stat) return stat * 0.7 end,
},
["ViewModelBoneMods"] = function(wep,tbl)
if wep.GripBoneMods then
wep.GripFactor = wep.GripFactor or 0
local CanGrip = true
if wep.GripBadActivities and wep.GripBadActivities[ wep:GetLastActivity() ] and wep:VMIV() then
local cyc = wep.OwnerViewModel:GetCycle()
if cyc > wep.GripBadActivities[ wep:GetLastActivity() ][1] and cyc < wep.GripBadActivities[ wep:GetLastActivity() ][2] then
CanGrip = false
end
end
wep.GripFactor = math.Approach( wep.GripFactor, CanGrip and 1 or 0, ( ( CanGrip and 1 or 0 ) - wep.GripFactor ) * TFA.FrameTime() * ( wep.GripLerpSpeed or 20 ) )
return LerpBoneMods( wep.GripFactor, tbl, wep.GripBoneMods )
end
end
}
function ATTACHMENT:Attach(wep)
wep.GripFactor = 0
end
function ATTACHMENT:Detach(wep)
wep.GripFactor = 0
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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.
if not ATTACHMENT then
ATTACHMENT = {}
end
-- ATTACHMENT.TFADataVersion = 1 -- Uncomment this in your attachment file
-- If it is undefined, if fallback to 0 and WeaponTable gets migrated like SWEPs do
ATTACHMENT.Name = "Base Attachment"
ATTACHMENT.ShortName = nil --Abbreviation, 5 chars or less please
ATTACHMENT.Description = {} --TFA.Attachments.Colors["+"], "Does something good", TFA.Attachments.Colors["-"], "Does something bad" }
ATTACHMENT.Icon = nil --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.WeaponTable = {} --put replacements for your SWEP talbe in here e.g. ["Primary"] = {}
ATTACHMENT.DInv2_GridSizeX = nil -- DInventory/2 Specific. Determines attachment's width in grid.
ATTACHMENT.DInv2_GridSizeY = nil -- DInventory/2 Specific. Determines attachment's height in grid.
ATTACHMENT.DInv2_Volume = nil -- DInventory/2 Specific. Determines attachment's volume in liters.
ATTACHMENT.DInv2_Mass = nil -- DInventory/2 Specific. Determines attachment's mass in kilograms.
ATTACHMENT.DInv2_StackSize = nil -- DInventory/2 Specific. Determines attachment's maximal stack size.
ATTACHMENT.TFADataVersion = nil -- TFA.LatestDataVersion, specifies version of TFA Weapon Data this attachment utilize in `WeaponTable`
-- 0 is original, M9K-like data, and is the fallback if `TFADataVersion` is undefined
function ATTACHMENT:CanAttach(wep)
return true --can be overridden per-attachment
end
function ATTACHMENT:Attach(wep)
end
function ATTACHMENT:Detach(wep)
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,68 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Suppressor"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Less firing noise", TFA.Attachments.Colors["-"], "10% less spread", TFA.Attachments.Colors["-"], "5% less damage", TFA.Attachments.Colors["-"], "10% less vertical recoil" }
ATTACHMENT.Icon = "entities/tfa_br_supp.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SUPP"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["ViewModelElements"] = {
["suppressor"] = {
["active"] = true
}
},
["WorldModelElements"] = {
["suppressor"] = {
["active"] = true
}
},
["Primary"] = {
["Damage"] = function(wep,stat) return stat * 0.95 end,
["KickUp"] = function(wep,stat) return stat * 0.9 end,
["KickDown"] = function(wep,stat) return stat * 0.9 end,
["Spread"] = function(wep,stat) return stat * 0.9 end,
["IronAccuracy"] = function(wep,stat) return stat * 0.9 end,
["Sound"] = function(wep,stat) return wep.Primary.SilencedSound or stat end
},
["MuzzleFlashEffect"] = "tfa_muzzleflash_silenced",
["MuzzleAttachmentMod"] = function(wep,stat) return wep.MuzzleAttachmentSilenced or stat end
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,35 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Unfolded Bayonet"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = {
TFA.AttachmentColors["="], "Use with suitzoom bind (+zoom)",
TFA.AttachmentColors["+"], "+75% melee damage",
}
ATTACHMENT.Icon = "entities/tfafas2sksunfld.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "UNFLD"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[1] = 2},
["Bodygroups_W"] = {[2] = 3},
["Secondary"] = {
["BashDamage"] = function( wep, stat ) return stat * 1.75 end,
},
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,28 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Folded Bayonet"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = {}
ATTACHMENT.Icon = "entities/tfafas2sksfld.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "FOLD"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[1] = 1},
["Bodygroups_W"] = {[2] = 1},
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,32 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Magnum Shells"
ATTACHMENT.ShortName = "MGNM" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Increases critical damage", "+60% damage", TFA.Attachments.Colors["-"], "Decreases hit chance at range", "-5 pellets" }
ATTACHMENT.Icon = "entities/tfa_ammo_fragshell.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.WeaponTable = {
["Primary"] = {
["StaticRecoilFactor"] = function( wep, stat ) return stat * 1.15 end,
["PenetrationMultiplier"] = function( wep, stat ) return wep.Primary.NumShots * stat * 1 end,
["Damage"] = function(wep,stat) return stat * 1.60 end,
["NumShots"] = function(wep,stat) return stat / 2 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,37 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Pyro Shells"
ATTACHMENT.ShortName = "PYRO" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Ignites flammable objects", "Fun with VFire", "+7 pellets", "-35% overall recoil", TFA.Attachments.Colors["-"], "+200% spread", "-55% total damage" }
ATTACHMENT.Icon = "entities/tfa_ammo_incenshell.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.WeaponTable = {
["Primary"] = {
["KickUp"] = function( wep, stat ) return stat * .65 end,
["KickDown"] = function( wep, stat ) return stat * .65 end,
["KickHorizontal"] = function( wep, stat ) return stat * .65 end,
["StaticRecoilFactor"] = function( wep, stat ) return stat * .8 end,
["DamageType"] = function(wep,stat) return bit.bor( stat or 0, DMG_BURN ) end,
["Spread"] = function(wep,stat) return stat * 2 end,
["IronAccuracy"] = function( wep, stat ) return stat * 3 end,
["Damage"] = function(wep,stat) return stat / 2.55 end,
["NumShots"] = function(wep,stat) return stat * 1.7 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,43 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Slug Shells"
ATTACHMENT.ShortName = "SLUG" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Increases accuracy", "Standard with the KS23's rifled barrel", TFA.Attachments.Colors["-"], "-20% total damage", "-9 pellets" }
ATTACHMENT.Icon = "entities/tfa_ammo_slug.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.WeaponTable = {
["Primary"] = {
["Damage"] = function( wep, stat ) return wep.Primary.NumShots * stat * 0.8 end,
["PenetrationMultiplier"] = function( wep, stat ) return wep.Primary.NumShots * stat * 3 end,
["NumShots"] = function( wep, stat ) return 1, true end,
["Spread"] = function( wep, stat ) return stat - 0.025 end,
["IronAccuracy"] = function( wep, stat ) return stat - 0.04 end,
["Range"] = function( wep, stat ) return stat + 100 * 39.370 end
},
["MuzzleFlashEffect"] = "tfa_muzzleflash_generic",
}
function ATTACHMENT:Attach(wep)
wep.Type = "Pump-action carbine, 23×75mmR"
end
function ATTACHMENT:Detach(wep)
wep.Type = "Pump-action shotgun, 23×75mmR"
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,41 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Adjustable Stock"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "-10% overall recoil", "-30% aim recoil",
}
ATTACHMENT.Icon = "entities/tfafas2adjstk.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "ADJ."
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[2] = 1},
["Bodygroups_W"] = {[2] = 2},
["Primary"] = {
["KickUp"] = function( wep, stat ) return stat * 0.9 end,
["KickDown"] = function( wep, stat ) return stat * 0.9 end,
["KickHorizontal"] = function( wep, stat ) return stat * 0.9 end,
["IronRecoilMultiplier"] = function( wep, stat ) return stat * 0.7 end,
["StaticRecoilFactor"] = function( wep, stat ) return stat * 0.9 end,
},
["BlowbackVector"] = Vector(0,-3,-.02),
--["IronSightsSensitivity"] = function( wep, stat ) return stat * 0.975 end,
--["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 0.85 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,50 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "CQB Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+10% movement speed",
TFA.AttachmentColors["-"], "+20% recoil", "-20% accuracy"
}
ATTACHMENT.Icon = "entities/tfafas2g3barcqb.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "CQB"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.8, .8, .8), pos = Vector(-14.75, .85, .41), angle = Angle(-90, 90, 0) },
["A_Underbarrel"] = { scale = Vector(.6, .6, .6), pos = Vector(-12.5, .85, 3.41), angle = Angle(-90, 90, 0) },
["A_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(9, 0, 0), angle = Angle(0, 0, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(6.5, 0, 0), angle = Angle(0, 0, 0) },
["Left Polex Phalange1"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(-12, 1, 25) },
},
["Bodygroups_V"] = {[1] = 1},
["Bodygroups_W"] = {[1] = 1},
["IronSightsPos"] = Vector(-2.658, -5, -.022),
["IronSightsAng"] = Vector(0.515, 0.002, 0),
["Primary"] = {
["IronAccuracy"] = function( wep, stat ) return stat * 1.15 end,
["Spread"] = function( wep, stat ) return stat * 1.2 end,
["KickUp"] = function( wep, stat ) return stat * 1.2 end,
["Sound"] = function(wep,stat) return "FAS2TFA_G3.2" or stat end,
["SilencedSound"] = function(wep,stat) return "FAS2TFA_G3.4" or stat end,
},
["MoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsSensitivity"] = function( wep, stat ) return stat * 0.9 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,44 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Full Stock"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+20% accuracy", "-20% overall recoil", "-70% aim recoil",
TFA.AttachmentColors["-"], "-10% aim speed",
}
ATTACHMENT.Icon = "entities/tfafas2g3fulstk.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "FULL"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[2] = 2},
["Bodygroups_W"] = {[2] = 1},
["Primary"] = {
["IronAccuracy"] = function( wep, stat ) return stat * 0.5 end,
["KickUp"] = function( wep, stat ) return stat * 0.8 end,
["KickDown"] = function( wep, stat ) return stat * 0.8 end,
["KickHorizontal"] = function( wep, stat ) return stat * 0.8 end,
["IronRecoilMultiplier"] = function( wep, stat ) return stat * 0.3 end,
["StaticRecoilFactor"] = function( wep, stat ) return stat * 0.9 end,
},
["BlowbackVector"] = Vector(0,-2.25,.005),
["IronSightTime"] = function( wep, stat ) return stat * 0.9 end,
["MoveSpeed"] = function( wep, stat ) return stat * 0.975 end,
["IronSightsSensitivity"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 0.9 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,42 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Extended Tube, 6rnd"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "Increases internal magazine capacity", TFA.Attachments.Colors["-"],"Attaching & detaching empties magazine",
}
ATTACHMENT.Icon = "entities/ks23tube.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "+MAG"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[2] = 1},
["Bodygroups_W"] = {[2] = 1},
["Primary"] = {
["ClipSize"] = function(wep, val)
return wep.Primary.ClipSize_ExtRifle or 6
end,
},
}
function ATTACHMENT:Attach(wep)
wep:Unload()
end
function ATTACHMENT:Detach(wep)
wep:Unload()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,37 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Colorable Stock"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "Corresponds with your gmod physgun color",
}
ATTACHMENT.Icon = "entities/ks23plrstock.png"
ATTACHMENT.ShortName = "RGB"
ATTACHMENT.WeaponTable = {
["Skin"] = 1,
}
function ATTACHMENT:Attach(wep)
wep:SetSkin(1)
end
function ATTACHMENT:Detach(wep)
wep:SetSkin(0)
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,52 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "KS23M Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+10% movement speed",
TFA.AttachmentColors["-"], "+35% recoil", "+170% spread",
}
ATTACHMENT.Icon = "entities/ks23short.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SBS"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.85, .85, .85), pos = Vector(13.75, 13.55, 4.27), angle = Angle(180, -90, 90) },
["A_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(-9, 0, 0), angle = Angle(0, 0, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(-5, 0, 0), angle = Angle(0, 0, 0) }, },
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(.9, .9, .9), pos = Vector(0, 8.25, 0), angle = Angle(0, 0, 0) },
},
["VElements"] = {
["short"] = {
["active"] = true
},
},
["IronSightsPos"] = Vector(-2.7285, -7.035, 1.847),
["IronSightsAng"] = Vector(1.05, 0.015, 0),
["Bodygroups_V"] = {[1] = 1},
["Bodygroups_W"] = {[1] = 1},
["Primary"] = {
["KickUp"] = function( wep, stat ) return stat * 1.15 end,
["Spread"] = function(wep,stat) return stat * 1.7 end,
["IronAccuracy"] = function( wep, stat ) return stat * 1.7 end,
},
["MoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsSensitivity"] = function( wep, stat ) return stat * 0.9 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,65 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Suppressor"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "Less firing noise", TFA.AttachmentColors["+"], "+10% vertical recoil", "-10% spread", TFA.AttachmentColors["-"], "-30% damage" }
ATTACHMENT.Icon = "entities/ins2_att_br_supp.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SUPP"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["suppressor"] = {
["active"] = true
},
["standard_barrel"] = {
["active"] = false
}
},
["WElements"] = {
["suppressor"] = {
["active"] = true
},
["standard_barrel"] = {
["active"] = false
}
},
["IronSightsPos"] = Vector(-2.7285, -7.035, 1.8975),
["IronSightsAng"] = Vector(-.2, 0.015, 0),
["Primary"] = {
["Damage"] = function(wep,stat) return stat * 0.7 end,
["KickUp"] = function(wep,stat) return stat * 0.9 end,
["KickDown"] = function(wep,stat) return stat * 0.9 end,
["Spread"] = function(wep,stat) return stat * 0.9 end,
["IronAccuracy"] = function(wep,stat) return stat * 0.9 end,
["Sound"] = function(wep,stat) return wep.Primary.SilencedSound or stat end,
},
["MuzzleFlashEffect"] = "tfa_muzzleflash_silenced",
["MuzzleAttachmentMod"] = function(wep,stat) return wep.MuzzleAttachmentSilenced or stat end,
["Silenced"] = true,
}
function ATTACHMENT:Attach(wep)
wep.Silenced = true
wep:SetSilenced(wep.Silenced)
end
function ATTACHMENT:Detach(wep)
wep.Silenced = false
wep:SetSilenced(wep.Silenced)
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,35 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Retractable Stock"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+5% aiming speed", "-15% spread"
}
ATTACHMENT.Icon = "entities/tfafas2adjstk.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "RETR"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[5] = 1},
["Bodygroups_W"] = {[2] = 1},
["Primary"] = {
["Spread"] = function(wep,stat) return stat * .85 end,
},
["BlowbackVector"] = Vector(0,-1.5,-.075),
["IronSightTime"] = function( wep, stat ) return stat * 1.05 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,140 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "MP5K Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "Increases RPM to 975", "+5% movement speed",
TFA.AttachmentColors["-"], "+20% recoil",
}
ATTACHMENT.Icon = "entities/tfafas2mp5k.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "PDW"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.75, 1, .75), pos = Vector(10.25, .82, 0), angle = Angle(180, -90, 0) },
["A_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(-3.75, 0, 0), angle = Angle(0, 0, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(-2, 0, 0), angle = Angle(0, 0, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(-4, 0, -.29), angle = Angle(0, 0, 0) },
},
["Bodygroups_V"] = {[1] = 1, [3] = 1, [4] = 2},
["Bodygroups_W"] = {[1] = 1},
["Animations"] = {
["draw"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_deploy"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["holster"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_holster"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["idle"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_idle"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["idle_empty"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_idle"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["shoot1"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_shoot"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["reload"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_reload"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["reload_empty"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "mp5k_"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "mp5k_reload_empty"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
},
["Primary"] = {
["KickUp"] = function( wep, stat ) return stat * 1.20 end,
["Sound"] = function(wep,stat) return "FAS2TFA_MP5.2" or stat end,
["SilencedSound"] = function(wep,stat) return "FAS2TFA_MP5.4" or stat end,
["RPM"] = function( wep, stat ) return stat + 125 end,
},
["MoveSpeed"] = function( wep, stat ) return stat * 1.05 end,
["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 1.05 end,
["IronSightsSensitivity"] = function( wep, stat ) return stat * 0.95 end,
}
function ATTACHMENT:Attach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
function ATTACHMENT:Detach( wep )
if TFA.Enum.ReadyStatus[wep:GetStatus()] then
wep:ChooseIdleAnim()
if game.SinglePlayer() then
wep:CallOnClient("ChooseIdleAnim","")
end
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,37 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "PDW Stock"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+10% aiming speed", "-5% spread",
TFA.AttachmentColors["-"], "+10% horizontal recoil",
}
ATTACHMENT.Icon = "entities/tfafas2pdwstk.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "PDW"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[5] = 2},
["Bodygroups_W"] = {[2] = 2},
["Primary"] = {
["KickHorizontal"] = function( wep, stat ) return stat * 1.1 end,
["Spread"] = function( wep, stat ) return stat * .95 end,
},
["BlowbackVector"] = Vector(0,-1.5,-.075),
["IronSightTime"] = function( wep, stat ) return stat * 1.10 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,50 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "MP5SD Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["-"], "Decreases RPM to 800",
TFA.AttachmentColors["+"], "-15% recoil",
}
ATTACHMENT.Icon = "entities/tfafas2mp5sd.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SD"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.75, 1, .75), pos = Vector(10.25, .82, 0), angle = Angle(180, -90, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(-1.5, 0, 0), angle = Angle(0, 0, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(.75, .75, .75), pos = Vector(-3, 0, -.29), angle = Angle(0, 0, 0) },
},
["Bodygroups_V"] = {[1] = 2, [3] = 1, [4] = 3},
["Bodygroups_W"] = {[1] = 2},
["Primary"] = {
["KickUp"] = function( wep, stat ) return stat * .85 end,
["SilencedSound"] = function(wep,stat) return "FAS2TFA_MP5.3" or stat end,
["RPM"] = function( wep, stat ) return stat - 50 end,
},
}
function ATTACHMENT:Attach(wep)
end
function ATTACHMENT:Detach(wep)
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Suppressor"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["+"], "Less firing noise", TFA.AttachmentColors["+"], "-5% overall recoil", "-10% spread", TFA.AttachmentColors["-"], "-7% damage" }
ATTACHMENT.Icon = "entities/ins2_att_br_supp.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SUPP"
ATTACHMENT.WeaponTable = {
["VElements"] = {
["suppressor"] = {
["active"] = true
},
["standard_barrel"] = {
["active"] = false
}
},
["WElements"] = {
["suppressor"] = {
["active"] = true
},
["standard_barrel"] = {
["active"] = false
}
},
["Primary"] = {
["Damage"] = function(wep,stat) return stat * 0.93 end,
["KickUp"] = function(wep,stat) return stat * 0.95 end,
["KickDown"] = function(wep,stat) return stat * 0.95 end,
["KickHorizontal"] = function(wep,stat) return stat * 0.95 end,
["Spread"] = function(wep,stat) return stat * 0.9 end,
["IronAccuracy"] = function(wep,stat) return stat * 0.9 end,
["Sound"] = function(wep,stat) return wep.Primary.SilencedSound or stat end,
},
["MuzzleFlashEffect"] = "tfa_muzzleflash_silenced",
["MuzzleAttachmentMod"] = function(wep,stat) return wep.MuzzleAttachmentSilenced or stat end,
["Silenced"] = true,
}
function ATTACHMENT:Attach(wep)
wep.Silenced = true
wep:SetSilenced(wep.Silenced)
end
function ATTACHMENT:Detach(wep)
wep.Silenced = false
wep:SetSilenced(wep.Silenced)
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "553 Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+5% movement speed",
TFA.AttachmentColors["-"], "+15% overall recoil",
}
ATTACHMENT.Icon = "entities/sgshort.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "CQB"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.86, 1, .86), pos = Vector(1.672, -7.25, 2.825), angle = Angle(180, 0, 180) },
["A_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(-11, 0, 0), angle = Angle(0, 0, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(-9, 0, 0), angle = Angle(0, 0, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(.9, .9, .9), pos = Vector(-13, .05, -.1), angle = Angle(0, 0, 0) },
},
["VElements"] = { ["cqb"] = { ["active"] = true},
},
["IronSightsPos"] = Vector(-2.3012, -2.5, .956),
["IronSightsAng"] = Vector(-.15, 0.008, 0),
["Bodygroups_V"] = {[3] = 1, [4] = 2, [8] = 1, [7] = 1},
["Bodygroups_W"] = {[1] = 1, [3] = 2, [4] = 1},
["Primary"] = {
["KickUp"] = function( wep, stat ) return stat * 1.15 end,
["KickDown"] = function( wep, stat ) return stat * 1.15 end,
["KickHorizontal"] = function( wep, stat ) return stat * 1.15 end,
["StaticRecoilFactor"] = function( wep, stat ) return stat * 1.05 end,
["Sound"] = function(wep,stat) return "FAS2TFA_SG550.3" or stat end,
["SilencedSound"] = function(wep,stat) return "FAS2TFA_SG550.4" or stat end,
},
["MoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 1.4 end,
["IronSightsSensitivity"] = function( wep, stat ) return stat * 0.6 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,55 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "550-1 Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "-15% vertical recoil", "+35% aiming accuracy",
}
ATTACHMENT.Icon = "entities/ins2_att_br_heavy.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "HBAR"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.88, 1, .88), pos = Vector(1.672, -24.5, 2.825), angle = Angle(180, 0, 180) },
["A_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(5, 0, 0), angle = Angle(0, 0, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(10, 0, 0), angle = Angle(0, 0, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(.9, .9, .9), pos = Vector(5, .05, -.1), angle = Angle(0, 0, 0) },
},
["Bodygroups_V"] = {[4] = 1},
["Bodygroups_W"] = {[3] = 1},
["Primary"] = {
["IronAccuracy"] = function( wep, stat ) return stat * 1.35 end,
["IronRecoilMultiplier"] = function( wep, stat ) return stat * 1.35 end,
["KickUp"] = function( wep, stat ) return stat * 0.9 end,
["KickDown"] = function( wep, stat ) return stat * 0.9 end,
},
["MoveSpeed"] = function( wep, stat ) return stat * 0.95 end,
["MuzzleFlashEffect"] = "tfa_muzzleflash_generic",
}
function ATTACHMENT:Attach(wep)
wep.Type = "Select-fire sniper rifle, 5.56×45mm"
end
function ATTACHMENT:Detach(wep)
wep.Type = "Assault rifle, 5.56×45mm"
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,35 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Precision Stock"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "-10% horizontal recoil",
TFA.AttachmentColors["-"], "+25% aiming speed",
}
ATTACHMENT.Icon = "entities/sgstk2.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "+STK"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[1] = 1},
["Bodygroups_W"] = {[2] = 1},
["Primary"] = {
["KickHorizontal"] = function(wep,stat) return stat * 0.88 end,
},
["IronSightTime"] = function( wep, stat ) return stat * 1.25 end,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,45 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "SG550/1 Scope"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "10x zoom", TFA.AttachmentColors["-"], "40% higher zoom time", TFA.AttachmentColors["-"], "10% slower aimed walking" }
ATTACHMENT.Icon = "entities/ins2_si_mx4.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SG"
ATTACHMENT.Base = "ins2_scope_base"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[5] = 1, [7] = 1},
["BlowbackVector"] = Vector(0,-1,0),
["VElements"] = {
["rail_sights"] = {
["active"] = false,},
["pso1_lens"] = {
["active"] = true,
},
},
["WElements"] = {
["scope_mx4"] = {
["active"] = true
}
},
["Secondary"] = {
["ScopeZoom"] = function(wep, val) return 10 end
},
["INS2_SightSuffix"] = "SG"
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Detachable 20rnd"
ATTACHMENT.Description = {}
ATTACHMENT.Icon = "entities/tfafas2sks20rnd.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "20DM"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[2] = 2},
["Bodygroups_W"] = {[1] = 1},
["Animations"] = {
["reload"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "_stanag"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "Reload_30_nmc"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["reload_empty"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "_stanag"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "Reload_30_empty_nmc"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
},
["Primary"] = {
["ClipSize"] = function(wep, val)
return wep.Primary.ClipSize_ExtRifle or 20
end,
},
}
function ATTACHMENT:Attach(wep)
wep:Unload()
end
function ATTACHMENT:Detach(wep)
wep:Unload()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,62 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Detachable 30rnd"
ATTACHMENT.Description = {}
ATTACHMENT.Icon = "entities/tfafas2sks30rnd.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "30DM"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[2] = 3},
["Bodygroups_W"] = {[1] = 2},
["Animations"] = {
["reload"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "_stanag"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "Reload_30_nmc"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["reload_empty"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "_stanag"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "Reload_30_empty_nmc"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
},
["Primary"] = {
["ClipSize"] = function(wep, val)
return wep.Primary.ClipSize_ExtRifle or 30
end,
},
}
function ATTACHMENT:Attach(wep)
wep:Unload()
end
function ATTACHMENT:Detach(wep)
wep:Unload()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Detachable 40rnd"
ATTACHMENT.Description = {}
ATTACHMENT.Icon = "entities/tfafas2sks40rnd.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "40RPK"
ATTACHMENT.WeaponTable = {
["CanJam"] = true,
["Bodygroups_V"] = {[2] = 4},
["Bodygroups_W"] = {[1] = 3},
["Animations"] = {
["reload"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "_stanag"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "Reload_30_nmc"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
["reload_empty"] = function(wep, _val)
local val = table.Copy(_val)
if val.type == TFA.Enum.ANIMATION_SEQ then
val.value = val.value .. "_stanag"
else
val.type = TFA.Enum.ANIMATION_SEQ --Sequence or act
val.value = "Reload_30_empty_nmc"
end
return (wep:CheckVMSequence(val.value) and val or _val), true, true
end,
},
["Primary"] = {
["ClipSize"] = function(wep, val)
return wep.Primary.ClipSize_ExtRifle or 40
end,
},
}
function ATTACHMENT:Attach(wep)
wep:Unload()
end
function ATTACHMENT:Detach(wep)
wep:Unload()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,35 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Full-auto conversion"
ATTACHMENT.Description = {}
ATTACHMENT.Icon = nil --"entities/ins2_att_mag_ext_rifle_30rd.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "AUTO"
ATTACHMENT.WeaponTable = {
}
function ATTACHMENT:Attach(wep)
wep.Primary.Automatic = true
wep.Type = "Automatic rifle, 7.62×39mm"
end
function ATTACHMENT:Detach(wep)
wep.Primary.Automatic = false
wep.Type = "Semi-automatic rifle, 7.62×39mm"
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,50 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "SBR Barrel"
ATTACHMENT.Description = {
TFA.AttachmentColors["+"], "+10% movement speed",
TFA.AttachmentColors["-"], "+20% recoil", "-30% accuracy", "-5% damage"
}
ATTACHMENT.Icon = "entities/tfafas2svdsbr.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "SBR"
ATTACHMENT.WeaponTable = {
["ViewModelBoneMods"] = {
["A_Suppressor"] = { scale = Vector(.8, .8, .8), pos = Vector(9, .5, 0), angle = Angle(0, -90, 0) },
["A_Muzzle"] = { scale = Vector(1, 1, 1), pos = Vector(-13.8, 0, 0), angle = Angle(0, 0, 0) },
["A_MuzzleSupp"] = { scale = Vector(1, 1, 1), pos = Vector(-10.5, 0, 0), angle = Angle(0, 0, 0) },
},
["WorldModelBoneMods"] = {
["ATTACH_Muzzle"] = { scale = Vector(.9, .9, .9), pos = Vector(-14, .2, 0), angle = Angle(0, 0, 0) },
},
["Bodygroups_V"] = {[2] = 1},
["Bodygroups_W"] = {[1] = 1},
["Primary"] = {
["IronAccuracy"] = function( wep, stat ) return stat * 1.3 end,
["Damage"] = function( wep, stat ) return stat * .95 end,
["Spread"] = function( wep, stat ) return stat * 1.3 end,
["KickUp"] = function( wep, stat ) return stat * 1.2 end,
["Sound"] = function(wep,stat) return "FAS2TFA_SVD.3" or stat end,
["SilencedSound"] = function(wep,stat) return "FAS2TFA_SVD.4" or stat end,
},
["MoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsMoveSpeed"] = function( wep, stat ) return stat * 1.1 end,
["IronSightsSensitivity"] = function( wep, stat ) return stat * 0.9 end,
["MuzzleFlashEffect"] = "tfa_muzzleflash_generic",
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,45 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "PSO-1 Scope"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "4x zoom", TFA.AttachmentColors["-"], "30% higher zoom time", TFA.AttachmentColors["-"], "15% slower aimed walking" }
ATTACHMENT.Icon = "entities/ins2_si_mx4.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "PSO-1"
ATTACHMENT.Base = "ins2_scope_base"
ATTACHMENT.WeaponTable = {
["Bodygroups_V"] = {[1] = 1},
["BlowbackVector"] = Vector(0,-1,0),
["VElements"] = {
["rail_sights"] = {
["active"] = false,},
["pso1_lens"] = {
["active"] = true,
},
},
["WElements"] = {
["scope_mx4"] = {
["active"] = true
}
},
["Secondary"] = {
["ScopeZoom"] = function(wep, val) return 4 end
},
["INS2_SightSuffix"] = "PSO"
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,68 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Ironsight-less"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["-"], "Removes the ironsight on the AR2.", TFA.AttachmentColors["+"], "Appreciate all the intricate mechanisms of the AR2." }
ATTACHMENT.Icon = "entities/hl2r_ar2_legacy_is.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "LEGACY"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_LEG or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_LEG or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
}
function ATTACHMENT:Attach(wep)
local mag = wep:Clip1()
wep.DrawCrosshairIS = true
wep.ViewModelKitOld = wep.ViewModelKitOld or wep.ViewModel
wep.ViewModel = wep:GetStat("ViewModel_LEG") or wep.ViewModel
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
if mag == 0 then
wep:SendViewModelAnim(ACT_VM_IDLE_EMPTY)
elseif mag == 1 then
wep:SendViewModelSeq("idle_midempty")
else
wep:SendViewModelAnim(ACT_VM_IDLE)
end
end)
end
end
function ATTACHMENT:Detach(wep)
local mag = wep:Clip1()
wep.DrawCrosshairIS = false
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
if mag == 0 then
wep:SendViewModelAnim(ACT_VM_IDLE_EMPTY)
elseif mag == 1 then
wep:SendViewModelSeq("idle_midempty")
else
wep:SendViewModelAnim(ACT_VM_IDLE)
end
end)
end
wep.ViewModelKitOld = nil
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,43 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "No-scope"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["-"], "Don't aim with the scope." }
ATTACHMENT.Icon = "entities/hl2r_ar2_legacy_is.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "LEGACY"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_LEG or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_LEG or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
--["RTMaterialOverride"] = 0;
}
function ATTACHMENT:Attach(wep)
wep.DrawCrosshairIS = true
wep:ClearStatCache()
--wep.RTMaterialOverride = 0;
wep:ClearStatCache()
end
function ATTACHMENT:Detach(wep)
wep.DrawCrosshairIS = false
wep:ClearStatCache()
--wep.RTMaterialOverride = 2;
wep:ClearStatCache()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,36 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Ironsight-less"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "Changes the aim to look like MMOD", TFA.AttachmentColors["-"], "Doesn't use the sights." }
ATTACHMENT.Icon = "entities/hl2r_ar2_legacy_is.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "LEGACY"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_LEG or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_LEG or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
}
function ATTACHMENT:Attach(wep)
wep.DrawCrosshairIS = true
end
function ATTACHMENT:Detach(wep)
wep.DrawCrosshairIS = false
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,36 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Ironsight-less"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "Changes the aim to look like MMOD", TFA.AttachmentColors["-"], "Doesn't use the sights." }
ATTACHMENT.Icon = "entities/hl2r_ar2_legacy_is.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "LEGACY"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_LEG or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_LEG or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
}
function ATTACHMENT:Attach(wep)
wep.DrawCrosshairIS = true
end
function ATTACHMENT:Detach(wep)
wep.DrawCrosshairIS = false
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "HOLO Off"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["-"], "Shuts down the Holo sight", TFA.AttachmentColors["+"], "Train your aim!"}
ATTACHMENT.Icon = "entities/hl2r_ar2_legacy_is.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "LEGACY"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_LEG or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_LEG or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
}
ATTACHMENT.MaterialTable = {
}
function ATTACHMENT:Attach(wep)
local mag = wep:Clip1()
wep.ViewModelKitOld = wep.ViewModelKitOld or wep.ViewModel
wep.ViewModel = wep:GetStat("ViewModel_LEG") or wep.ViewModel
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
end
function ATTACHMENT:Detach(wep)
local mag = wep:Clip1()
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep.ViewModelKitOld = nil
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,61 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "MMod Reticle"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "Uses the MMod SMG Reticle.", TFA.AttachmentColors["+"], "This one can be colored." }
ATTACHMENT.Icon = "entities/hl2r_si_smg_ret.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "RET"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_MM or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_MM or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
}
function ATTACHMENT:Attach(wep)
wep.ViewModelKitOld = wep.ViewModelKitOld or wep.ViewModel
wep.WorldModelKitOld = wep.WorldModelKitOld or wep.WorldModel
wep.ViewModel = wep:GetStat("ViewModel_RET") or wep.ViewModel
wep.WorldModel = wep:GetStat("WorldModel_RET") or wep.WorldModel
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep:SetModel(wep.WorldModel)
end
function ATTACHMENT:Detach(wep)
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep.ViewModelKitOld = nil
end
if wep.WorldModelKitOld then
wep.WorldModel = wep.WorldModelKitOld
wep:SetModel(wep.WorldModel)
wep.ViewModelKitOld = nil
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Alternative Look"
ATTACHMENT.Description = {}
ATTACHMENT.Icon = "entities/tfa_ins2_pm_alt.png"
ATTACHMENT.ShortName = "ALT"
ATTACHMENT.WeaponTable = {
["MaterialTable_V"] = {
[1] = "models/weapons/tfa_ins2/pm/alt/pm",
},
["VElements"] = {
["mag"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/alt/pm",
}
},
["mag_ext"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/alt/pm",
}
}
},
["MaterialTable_W"] = {
[1] = "models/weapons/tfa_ins2/pm/alt/pm",
},
["WElements"] = {
["mag"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/alt/pm",
}
},
["mag_ext"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/alt/pm",
}
}
},
["WepSelectIcon_Override"] = "vgui/hud/tfa_ins2_pm_alt"
}
local function resetMatCache(att, wep)
wep:ClearMaterialCache()
end
ATTACHMENT.Attach = resetMatCache
ATTACHMENT.Detach = resetMatCache
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Honorary"
ATTACHMENT.Description = {
"«For succesful execution of highly dangerous state orders,",
"as well as valor and courage shown in the line of duty.»"
}
ATTACHMENT.Icon = "entities/tfa_ins2_pm_honorary.png"
ATTACHMENT.ShortName = "HONOR"
ATTACHMENT.WeaponTable = {
["MaterialTable_V"] = {
[1] = "models/weapons/tfa_ins2/pm/honorary/pm",
},
["VElements"] = {
["mag"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/honorary/pm",
}
},
["mag_ext"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/honorary/pm",
}
}
},
["MaterialTable_W"] = {
[1] = "models/weapons/tfa_ins2/pm/honorary/pm",
},
["WElements"] = {
["mag"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/honorary/pm",
}
},
["mag_ext"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/honorary/pm",
}
}
},
["WepSelectIcon_Override"] = "vgui/hud/tfa_ins2_pm_honorary"
}
local function resetMatCache(att, wep)
wep:ClearMaterialCache()
end
ATTACHMENT.Attach = resetMatCache
ATTACHMENT.Detach = resetMatCache
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Classic Soviet Vintage"
ATTACHMENT.Description = {}
ATTACHMENT.Icon = "entities/tfa_ins2_pm_soviet.png"
ATTACHMENT.ShortName = "OLD"
ATTACHMENT.WeaponTable = {
["MaterialTable_V"] = {
[1] = "models/weapons/tfa_ins2/pm/soviet/pm",
},
["VElements"] = {
["mag"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/soviet/pm",
}
},
["mag_ext"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/soviet/pm",
}
}
},
["MaterialTable_W"] = {
[1] = "models/weapons/tfa_ins2/pm/soviet/pm",
},
["WElements"] = {
["mag"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/soviet/pm",
}
},
["mag_ext"] = {
["materials"] = {
[1] = "models/weapons/tfa_ins2/pm/soviet/pm",
}
}
},
["WepSelectIcon_Override"] = "vgui/hud/tfa_ins2_pm_soviet"
}
local function resetMatCache(att, wep)
wep:ClearMaterialCache()
end
ATTACHMENT.Attach = resetMatCache
ATTACHMENT.Detach = resetMatCache
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "HD AR2"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "Overhauled textures."}
ATTACHMENT.Icon = "entities/mmod_ar2_greg.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "HD"
ATTACHMENT.WeaponTable = {
}
ATTACHMENT.MaterialTable = {
}
function ATTACHMENT:Attach(wep)
local mag = wep:Clip1()
wep.ViewModelKitOld = wep.ViewModelKitOld or wep.ViewModel
wep.WorldModelKitOld = wep.WorldModelKitOld or wep.WorldModel
wep.ViewModel = wep:GetStat("ViewModel_HD") or wep.ViewModel
wep.WorldModel = wep:GetStat("WorldModel_HD") or wep.WorldModel
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
if mag == 0 then
wep:SendViewModelAnim(ACT_VM_IDLE_EMPTY)
elseif mag == 1 then
wep:SendViewModelSeq("idle_midempty")
else
wep:SendViewModelAnim(ACT_VM_IDLE)
end
end)
end
wep:SetModel(wep.WorldModel)
wep.MaterialTable = wep.MaterialTable or {}
wep.MaterialTable[2] = self.MaterialTable[2]
end
function ATTACHMENT:Detach(wep)
local mag = wep:Clip1()
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
if mag == 0 then
wep:SendViewModelAnim(ACT_VM_IDLE_EMPTY)
elseif mag == 1 then
wep:SendViewModelSeq("idle_midempty")
else
wep:SendViewModelAnim(ACT_VM_IDLE)
end
end)
end
wep.ViewModelKitOld = nil
end
if wep.WorldModelKitOld then
wep.WorldModel = wep.WorldModelKitOld
wep:SetModel(wep.WorldModel)
wep.ViewModelKitOld = nil
end
wep.MaterialTable = wep.MaterialTable or {}
wep.MaterialTable[2] = nil
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,36 @@
--[[
| 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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Legacy Irons"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "Ironsights inspired by MMod." }
ATTACHMENT.Icon = "entities/mmod_si_legacy.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "LEGACY"
ATTACHMENT.WeaponTable = {
["IronSightsPos"] = function( wep, val ) return wep.IronSightsPos_LEG or val end,
["IronSightsAng"] = function( wep, val ) return wep.IronSightsAng_LEG or val end,
["IronSightTime"] = function( wep, val ) return val * 1 end,
}
function ATTACHMENT:Attach(wep)
wep.DrawCrosshairIS = true
end
function ATTACHMENT:Detach(wep)
wep.DrawCrosshairIS = false
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
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/
--]]
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Legacy Reticle"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.AttachmentColors["="], "Uses old SMG reticle.", TFA.AttachmentColors["-"], "Cannot be colored." }
ATTACHMENT.Icon = "entities/mmod_si_smg_ret.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "RET"
ATTACHMENT.WeaponTable = {
}
function ATTACHMENT:Attach(wep)
wep.ViewModelKitOld = wep.ViewModelKitOld or wep.ViewModel
wep.WorldModelKitOld = wep.WorldModelKitOld or wep.WorldModel
wep.ViewModel = wep:GetStat("ViewModel_RET") or wep.ViewModel
wep.WorldModel = wep:GetStat("WorldModel_RET") or wep.WorldModel
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep:SetModel(wep.WorldModel)
end
function ATTACHMENT:Detach(wep)
if wep.ViewModelKitOld then
wep.ViewModel = wep.ViewModelKitOld
if IsValid(wep.OwnerViewModel) then
wep.OwnerViewModel:SetModel(wep.ViewModel)
timer.Simple(0, function()
wep:SendViewModelAnim(ACT_VM_IDLE)
end)
end
wep.ViewModelKitOld = nil
end
if wep.WorldModelKitOld then
wep.WorldModel = wep.WorldModelKitOld
wep:SetModel(wep.WorldModel)
wep.ViewModelKitOld = nil
end
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,53 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Frag Ammunition"
ATTACHMENT.ShortName = "Frag" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Explosive Damage", "2x damage", TFA.Attachments.Colors["-"], "0.5x pellets" }
ATTACHMENT.Icon = "entities/tfa_ammo_fragshell.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["Primary"] = {
["DamageType"] = function(wep,stat) return bit.bor( stat or 0, DMG_BLAST ) end,
["Damage"] = function(wep,stat) return stat * 2 end,
["NumShots"] = function(wep,stat) return stat / 2 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,55 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Slug Ammunition"
ATTACHMENT.ShortName = "Slug" --Abbreviation, 5 chars or less please
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["+"], "Much lower spread", TFA.Attachments.Colors["+"], "100m higher range", TFA.Attachments.Colors["-"], "30% less damage", "One pellet" }
ATTACHMENT.Icon = "entities/tfa_ammo_slug.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["Primary"] = {
["Damage"] = function( wep, stat ) return wep.Primary_TFA.NumShots * stat * 0.7 end,
["NumShots"] = function( wep, stat ) return 1, true end,
["Spread"] = function( wep, stat ) return math.max( stat - 0.015, stat * 0.5 ) end,
["IronAccuracy"] = function( wep, stat ) return math.max( stat - 0.03, stat * 0.25 ) end,
["Range"] = function( wep, stat ) return stat + 100 * 39.370 end
}
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

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.
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Base = "si_rt_base"
ATTACHMENT.Name = "ACOG"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["="], "4x zoom", TFA.Attachments.Colors["-"], "20% higher zoom time", TFA.Attachments.Colors["-"], "10% slower aimed walking" }
ATTACHMENT.Icon = "entities/tfa_si_acog.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "ACOG"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
local fov = 90 / 4 / 2 -- Default FOV / Scope Zoom / screenscale
ATTACHMENT.WeaponTable = {
["ViewModelElements"] = {
["acog"] = {
["active"] = true
},
["rtcircle_acog"] = {
["active"] = true
}
},
["WorldModelElements"] = {
["acog"] = {
["active"] = true
}
},
["IronSightsPosition"] = function( wep, val ) return wep.IronSightsPos_ACOG or val, true end,
["IronSightsAngle"] = function( wep, val ) return wep.IronSightsAng_ACOG or val, true end,
["IronSightsSensitivity"] = function(wep,val) return TFA.CalculateSensitivtyScale( fov, wep:GetStatL("Secondary.OwnerFOV"), wep.ACOGScreenScale ) end ,
["Secondary"] = {
["OwnerFOV"] = function( wep, val ) return val * 0.7 end
},
["IronSightTime"] = function( wep, val ) return val * 1.20 end,
["IronSightMoveSpeed"] = function(stat) return stat * 0.9 end,
["RTOpaque"] = true,
["RTMaterialOverride"] = -1,
["RTScopeFOV"] = 90 / 4 / 2, -- Default FOV / Scope Zoom / screenscale
["RTReticleMaterial"] = Material("scope/gdcw_acog"),
["RTReticleScale"] = 1,
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,70 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "Aimpoint"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["="], "10% higher zoom", TFA.Attachments.Colors["-"], "10% higher zoom time" }
ATTACHMENT.Icon = "entities/tfa_si_aimpoint.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "AIM"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["ViewModelElements"] = {
["aimpoint"] = {
["active"] = true
},
["aimpoint_spr"] = {
["active"] = true
}
},
["WorldModelElements"] = {
["aimpoint"] = {
["active"] = true
},
["aimpoint_spr"] = {
["active"] = true
}
},
["IronSightsPosition"] = function( wep, val ) return wep.IronSightsPos_AimPoint or val, true end,
["IronSightsAngle"] = function( wep, val ) return wep.IronSightsAng_AimPoint or val, true end,
["Secondary"] = {
["OwnerFOV"] = function( wep, val ) return val * 0.9 end
},
["IronSightTime"] = function( wep, val ) return val * 1.10 end
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

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.
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "EOTech"
--ATTACHMENT.ID = "base" -- normally this is just your filename
ATTACHMENT.Description = { TFA.Attachments.Colors["="], "10% higher zoom", TFA.Attachments.Colors["-"], "10% higher zoom time" }
ATTACHMENT.Icon = "entities/tfa_si_eotech.png" --Revers to label, please give it an icon though! This should be the path to a png, like "entities/tfa_ammo_match.png"
ATTACHMENT.ShortName = "EOTEK"
ATTACHMENT.TFADataVersion = TFA.LatestDataVersion
ATTACHMENT.WeaponTable = {
["ViewModelElements"] = {
["eotech"] = {
["active"] = true
}
},
["WorldModelElements"] = {
["eotech"] = {
["active"] = true
}
},
["IronSightsPosition"] = function( wep, val ) return wep.IronSightsPos_EOTech or val, true end,
["IronSightsAngle"] = function( wep, val ) return wep.IronSightsAng_EOTech or val, true end,
["Secondary"] = {
["OwnerFOV"] = function( wep, val ) return val * 0.9 end
},
["IronSightTime"] = function( wep, val ) return val * 1.10 end
}
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,140 @@
--[[
| 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 not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.Name = "RT Scope Base"
ATTACHMENT.Description = {}
ATTACHMENT.WeaponTable = {
["RTDrawEnabled"] = true,
-- ["RTScopeFOV"] = 90 / 1 / 2, -- Default FOV / Scope Zoom / screenscale
-- ["RTScopeAttachment"] = -1,
-- ["RTReticleMaterial"] = Material("scope/gdcw_acog"),
-- ["RTReticleColor"] = color_white,
-- ["RTReticleScale"] = 1,
-- ["RTShadowMaterial"] = Material("vgui/scope_shadowmask_test"),
-- ["RTShadowColor"] = color_white,
-- ["RTShadowScale"] = 2,
}
local cd = {}
local fallbackReticle = Material("scope/gdcw_scopesightonly")
local fallbackShadow = Material("vgui/scope_shadowmask_test")
local flipcv = GetConVar("cl_tfa_viewmodel_flip")
function ATTACHMENT:RTCode(wep, rt, scrw, scrh)
if not wep.OwnerIsValid or not wep:VMIV() then return end
local rtw, rth = rt:Width(), rt:Height()
-- clearing view
render.OverrideAlphaWriteEnable(true, true)
surface.SetDrawColor(color_white)
surface.DrawRect(-rtw, -rth, rtw * 2, rth * 2)
local vm = wep.OwnerViewModel
local ang = vm:GetAngles()
local isang = wep:GetStatL("IronSightsAngle") * wep:GetIronSightsProgress()
ang:RotateAroundAxis(ang:Forward(), -isang.z)
ang:RotateAroundAxis(ang:Right(), -isang.x)
ang:RotateAroundAxis(ang:Up(), -isang.y)
ang:RotateAroundAxis(ang:Forward(), isang.z)
local scopeAtt = wep:GetStatL("RTScopeAttachment", -1)
if scopeAtt > 0 then
local AngPos = vm:GetAttachment(scopeAtt)
if AngPos then
ang = AngPos.Ang
if flipcv:GetBool() then
ang.y = -ang.y
end
end
end
cd.angles = ang
cd.origin = wep:GetOwner():GetShootPos()
cd.x = 0
cd.y = 0
cd.w = rtw
cd.h = rth
cd.fov = wep:GetStatL("RTScopeFOV", 90 / wep:GetStatL("ScopeZoom", 1) / 2)
cd.drawviewmodel = false
cd.drawhud = false
-- main RT render view
render.Clear(0, 0, 0, 255, true, true)
render.SetScissorRect(0, 0, rtw, rth, true)
if wep:GetIronSightsProgress() > 0.005 then
render.RenderView(cd)
end
render.SetScissorRect(0, 0, rtw, rth, false)
render.OverrideAlphaWriteEnable(false, true)
cam.Start2D()
-- ADS transition darkening
draw.NoTexture()
surface.SetDrawColor(ColorAlpha(color_black, 255 * (1 - wep:GetIronSightsProgress())))
surface.DrawRect(0, 0, rtw, rth)
surface.SetMaterial(wep:GetStatL("RTReticleMaterial", fallbackReticle))
surface.SetDrawColor(wep:GetStatL("RTReticleColor", color_white))
local retScale = wep:GetStatL("RTReticleScale", 1)
surface.DrawTexturedRect(rtw / 2 - rtw * retScale / 2, rth / 2 - rth * retScale / 2, rtw * retScale, rth * retScale)
surface.SetMaterial(wep:GetStatL("RTShadowMaterial", fallbackShadow))
surface.SetDrawColor(wep:GetStatL("RTShadowColor", color_white))
local shadScale = wep:GetStatL("RTShadowScale", 2)
surface.DrawTexturedRect(rtw / 2 - rtw * shadScale / 2, rth / 2 - rth * shadScale / 2, rtw * shadScale, rth * shadScale)
cam.End2D()
end
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,403 @@
--[[
| 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()
--[[Bullet Struct:
[BULLET_ID] = {
["owner"] = Entity, --used for dmginfo SetAttacker
["inflictor"] = Entity, --used for dmginfo SetInflictor
["damage"] = Double, --floating point number representing inflicted damage
["force"] = Double,
["pos"] = Vector, --vector representing current position
["velocity"] = Vector, --vector representing movement velocity
["model"] = String --optional variable representing the given model,
["bul"] = {} --optional table containing bullet data,
["smokeparticle"] = String, --smoke particle name from within pcf
["bulletOverride"] = Bool --disable coming out of gun barrel on clientside
}
]]
local BallisticBullet = {
["owner"] = NULL,
["inflictor"] = NULL,
["damage"] = 0,
["force"] = 0,
["pos"] = vector_origin,
["velocity"] = vector_origin,
["model"] = "models/bullets/w_pbullet1.mdl",
["bul"] = {},
["delete"] = false,
["smokeparticle"] = "tfa_bullet_smoke_tracer"
}
local traceRes = {}
local traceData = {
mask = MASK_SHOT,
collisiongroup = COLLISION_GROUP_NONE,
ignoreworld = false,
output = traceRes
}
local MASK_SHOT_NOWATER = MASK_SHOT
--main update block
function BallisticBullet:Update(delta)
if self.delete then return end
self:_setup()
if self.delete then return end
local realdelta = (delta - self.last_update) / TFA.Ballistics.SubSteps
self.last_update = delta
local newPos = self:_getnewPosition(realdelta)
newPos = self:_checkWater(realdelta, newPos)
self:_accelerate(realdelta)
self:_moveSafe(newPos)
end
--internal function for sanity checks, etc.
function BallisticBullet:_setup()
self.creationTime = CurTime()
if (not IsValid(self.owner)) or (not IsValid(self.inflictor)) then
self:Remove()
end
if CurTime() > self.creationTime + TFA.Ballistics.BulletLife then
self:Remove()
end
self.playerOwned = self.owner.IsPlayer and self.owner:IsPlayer()
self.startVelocity = self.velocity:Length()
self.startDamage = self.damage
end
function BallisticBullet:_think()
if (not IsValid(self.owner)) or (not IsValid(self.inflictor)) then
self:Remove()
end
if CurTime() > self.creationTime + TFA.Ballistics.BulletLife then
self:Remove()
end
end
--internal function for calculating position change
function BallisticBullet:_getnewPosition(delta)
--verlet
return self.pos + (self.velocity + TFA.Ballistics.Gravity * delta * 0.5) * delta
end
--internal function for handling water
function BallisticBullet:_checkWater(delta, target)
local newPos = target
traceData.start = self.pos
traceData.endpos = newPos
traceData.filter = {self.owner, self.inflictor}
traceData.mask = MASK_WATER
util.TraceLine(traceData)
if traceRes.Hit and traceRes.Fraction < 1 and traceRes.Fraction > 0 and not self.Underwater then
self.Underwater = true
newPos = traceRes.HitPos + traceRes.Normal
self.velocity = self.velocity / TFA.Ballistics.WaterEntranceResistance
local fx = EffectData()
fx:SetOrigin(newPos)
local sc = math.sqrt(self.damage / 28) * 6
fx:SetScale(sc)
util.Effect("gunshotsplash", fx)
end
return newPos
end
--internal function for handling acceleration
local function GetWind()
return vector_origin
end
if StormFox and StormFox.Version then
if StormFox.Version < 2 then -- SF1
local SF_GetNetworkData = StormFox.GetNetworkData
function GetWind()
local windSpeed = SF_GetNetworkData("Wind") * TFA.Ballistics.UnitScale
local windAng = Angle(0, SF_GetNetworkData("WindAngle"), 0)
return windSpeed * windAng:Forward():GetNormalized()
end
elseif StormFox.Wind then -- SF2
local SFW_GetForce = StormFox.Wind.GetForce
local SFW_GetYaw = StormFox.Wind.GetYaw
function GetWind()
local windSpeed = SFW_GetForce() * TFA.Ballistics.UnitScale
local windAng = Angle(0, SFW_GetYaw(), 0)
return windSpeed * windAng:Forward():GetNormalized()
end
end
end
function BallisticBullet:_accelerate(delta)
local dragDensity = self.Underwater and TFA.Ballistics.WaterResistance or TFA.Ballistics.AirResistance
local drag = -self.velocity:GetNormalized() * self.velocity:Length() * self.velocity:Length() * 0.00006 * dragDensity
local wind = GetWind()
if self.Underwater then
self.velocity = self.velocity / (1 + TFA.Ballistics.WaterResistance * delta)
end
self.velocity = self.velocity + (TFA.Ballistics.Gravity + drag + wind) * delta
self.damage = self.startDamage * math.sqrt(self.velocity:Length() / self.startVelocity)
end
local IsInWorld, IsInWorld2
do
local tr = {collisiongroup = COLLISION_GROUP_WORLD}
function IsInWorld2(pos)
tr.start = pos
tr.endpos = pos
return not util.TraceLine(tr).AllSolid
end
end
if CLIENT then
IsInWorld = IsInWorld2
else
IsInWorld = util.IsInWorld
end
--internal function for moving with collision test
function BallisticBullet:_moveSafe(newPos)
if not self.tr_filter then
if IsValid(self.IgnoreEntity) then
self.tr_filter = {self.owner, self.inflictor, self.IgnoreEntity}
else
self.tr_filter = {self.owner, self.inflictor}
end
end
traceData.start = self.pos
traceData.endpos = newPos + (newPos - self.pos):GetNormalized()
traceData.filter = self.tr_filter
traceData.mask = MASK_SHOT_NOWATER
--collision trace
if self.playerOwned then
self.owner:LagCompensation(true)
end
util.TraceLine(traceData)
if self.playerOwned then
self.owner:LagCompensation(false)
end
--collision check
if traceRes.Hit and traceRes.Fraction < 1 and traceRes.Fraction > 0 then
self:Impact(traceRes)
elseif IsInWorld(newPos) then
self.pos = newPos
else
self:Remove()
end
end
--called when hitting something, or manually if necessary
function BallisticBullet:Impact(tr)
self.pos = tr.HitPos
self:Remove()
if CLIENT and (game.SinglePlayer() or self.owner ~= LocalPlayer()) then return end
if tr.HitSky then return end
local vn = self.velocity:GetNormalized()
local bul = {
["Damage"] = self.damage,
["Force"] = self.force,
["Num"] = 1,
["Src"] = self.pos - vn * 4,
["Dir"] = vn * 8,
["Spread"] = vector_origin,
["IgnoreEntity"] = self.owner,
["Attacker"] = self.owner,
["Distance"] = 8,
["Tracer"] = 0
}
setmetatable(bul, {
["__index"] = self.bul
})
self.owner:FireBullets(bul)
end
--Render
--local cv_bullet_style, cv_tracers_adv
local cv_bullet_style
if CLIENT then
CreateClientConVar("cl_tfa_ballistics_mp", "1", true, false, "Receive bullet data from other players?")
cv_bullet_style = CreateClientConVar("cl_tfa_ballistics_fx_bullet", "1", true, false, "Display bullet models for each TFA ballistics bullet?")
CreateClientConVar("cl_tfa_ballistics_fx_tracers_style", "1", true, false, "Style of tracers for TFA ballistics? 0=disable,1=smoke")
CreateClientConVar("cl_tfa_ballistics_fx_tracers_mp", "1", true, false, "Enable tracers for other TFA ballistics users?")
--cv_tracers_adv = CreateClientConVar("cl_tfa_ballistics_fx_tracers_adv", "1", true, false, "Enable advanced tracer calculations for other users? This corrects smoke trail to their barrel")
--[[
cv_receive = GetConVar("cl_tfa_ballistics_mp")
cv_bullet_style = GetConVar("cl_tfa_ballistics_fx_bullet")
cv_tracers_style = GetConVar("cl_tfa_ballistics_fx_tracers_style")
cv_tracers_mp = GetConVar("cl_tfa_ballistics_fx_tracers_mp")
cv_tracers_adv = GetConVar("cl_tfa_ballistics_fx_tracers_adv")
]]
--
end
--[[local DEFANGPOS = {
Pos = vector_origin,
Ang = angle_zero
}]]
function BallisticBullet:Render()
if SERVER then return end
if self.delete then return end
if not self.curmodel then
self.curmodel = ClientsideModel(self.model, RENDERGROUP_OPAQUE)
self.curmodel:SetNoDraw(not cv_bullet_style:GetBool())
end
--[==[if IsValid(self.curmodel) and (cv_bullet_style:GetBool() or self.smokeparticle ~= "") then
if self.customPosition then
fpos = self.pos
--fang = self.velocity:Angle()
else
if self.owner == GetViewEntity() or self.owner == LocalPlayer() then
local spos, sang = self.pos, self.velocity:Angle()
self.curmodel:SetPos(spos)
self.curmodel:SetAngles(sang)
if not self.vOffsetPos then
local att
if self.inflictor.GetMuzzleAttachment and self.inflictor:GetMuzzleAttachment() then
att = self.inflictor:GetMuzzleAttachment()
else
att = self.inflictor.MuzzleAttachmentRaw or 1
end
if LocalPlayer():ShouldDrawLocalPlayer() then
local npos = LocalPlayer():GetActiveWeapon():GetAttachment(att) or DEFANGPOS
self.vOffsetPos = self.curmodel:WorldToLocal(npos.Pos)
self.vOffsetAng = self.curmodel:WorldToLocalAngles(npos.Ang)
else
local npos = LocalPlayer():GetViewModel():GetAttachment(att) or DEFANGPOS
self.vOffsetPos = self.curmodel:WorldToLocal(npos.Pos)
self.vOffsetAng = self.curmodel:WorldToLocalAngles(npos.Ang)
end
end
fpos = self.curmodel:LocalToWorld(self.vOffsetPos)
--fang = self.curmodel:LocalToWorldAngles(self.vOffsetAng)
elseif self.owner:IsPlayer() and cv_tracers_adv:GetBool() then
local spos, sang = self.pos, self.velocity:Angle()
self.curmodel:SetPos(spos)
self.curmodel:SetAngles(sang)
if not self.vOffsetPos then
local npos = self.owner:GetActiveWeapon():GetAttachment(1) or DEFANGPOS
self.vOffsetPos = self.curmodel:WorldToLocal(npos.Pos)
self.vOffsetAng = self.curmodel:WorldToLocalAngles(npos.Ang)
end
fpos = self.curmodel:LocalToWorld(self.vOffsetPos)
--fang = self.curmodel:LocalToWorldAngles(self.vOffsetAng)
else
fpos = self.pos
--fang = self.velocity:Angle()
end
end
--[[if cv_bullet_style:GetBool() then
self.curmodel:SetupBones()
self.curmodel:DrawModel()
end]]
end]==]
local fpos, fang = self.pos, self.velocity:Angle()
self.curmodel:SetPos(fpos)
self.curmodel:SetAngles(fang)
if self.smokeparticle ~= "" and not self.cursmoke then
self.cursmoke = CreateParticleSystem(self.curmodel, self.smokeparticle, PATTACH_ABSORIGIN_FOLLOW, 1)
if not self.cursmoke then return end
self.cursmoke:StartEmission()
elseif self.cursmoke and IsValid(self.owner) then
self.cursmoke:SetSortOrigin(self.owner.GetShootPos and self.owner:GetShootPos() or self.owner.EyePos and self.owner:EyePos() or vector_origin)
if self.Underwater then
self.cursmoke:StopEmission()
self.cursmoke = nil
self.smokeparticle = ""
end
end
end
function BallisticBullet:Remove()
if self.cursmoke then
self.cursmoke:StopEmission()
self.cursmoke = nil
end
if self.curmodel and self.curmodel.Remove then
self.curmodel:Remove()
self.curmodel = nil
end
self.delete = true
end
local CopyTable = table.Copy
function TFA.Ballistics:Bullet(t)
local b = CopyTable(t or {})
setmetatable(b, {
["__index"] = BallisticBullet
})
return b
end

View File

@@ -0,0 +1,84 @@
--[[
| 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/
--]]
-- TFA Base Attachment Template by TFA Base Devs
-- To the extent possible under law, the person who associated CC0 with
-- TFA Base Template has waived all copyright and related or neighboring rights
-- to TFA Base Template.
-- You should have received a copy of the CC0 legalcode along with this
-- work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
if not ATTACHMENT then
ATTACHMENT = {}
end
ATTACHMENT.TFADataVersion = 1 -- If it is undefined, it fallbacks to 0 and WeaponTable gets migrated like SWEPs do
-- ATTACHMENT.Base = "base" -- Attachment baseclass, defaults to "base" attachment
ATTACHMENT.Name = "Example Attachment"
ATTACHMENT.ShortName = nil -- Abbreviation shown on the bottom left of the icon, generated from name if not defined
ATTACHMENT.Description = {
TFA.Attachments.Colors["+"], "Does something good",
TFA.Attachments.Colors["-"], "Does something bad",
-- Color(255, 255, 255), "bottom text",
} -- all colors are defined in lua/tfa/modules/tfa_attachments.lua
ATTACHMENT.Icon = nil -- "entities/tfa_ammo_match.png" -- Full path to the icon, reverts to '?' by default
ATTACHMENT.WeaponTable = { -- The place where you change the stats (CACHED STATS ONLY!)
["Primary"] = {
["Damage"] = 60, -- For example, you want to change SWEP.Primary.Damage value to 60
["ClipSize"] = function(wep, stat)
return wep.Primary_TFA.ClipSize_Override or stat * 1.5
end -- Stat functions support changing value dynamically (which is cached afterwards), SWEP.Primary_TFA contains original unchanged values
}
}
-- ATTACHMENT.DInv2_GridSizeX = nil -- DInventory/2 Specific. Determines attachment's width in grid.
-- ATTACHMENT.DInv2_GridSizeY = nil -- DInventory/2 Specific. Determines attachment's height in grid.
-- ATTACHMENT.DInv2_Volume = nil -- DInventory/2 Specific. Determines attachment's volume in liters.
-- ATTACHMENT.DInv2_Mass = nil -- DInventory/2 Specific. Determines attachment's mass in kilograms.
-- ATTACHMENT.DInv2_StackSize = nil -- DInventory/2 Specific. Determines attachment's maximal stack size.
--[[
-- Default behavior is always allow, override to change
function ATTACHMENT:CanAttach(wep)
return true
end
]]--
--[[
-- These functions are called BEFORE stat cache is rebuilt
function ATTACHMENT:Attach(wep)
end
function ATTACHMENT:Detach(wep)
end
]]--
-- Attachment functions called from base
--[[
-- Called from render target code if SWEP.RTDrawEnabled is true
function ATTACHMENT:RTCode(wep, rt_texture, w, h)
end
]]--
--[[
-- Called from FireBullets for each bullet trace hit; arguments are passed from bullet callback
function ATTACHMENT:CustomBulletCallback(wep, attacker, trace, dmginfo)
end
]]--
if not TFA_ATTACHMENT_ISUPDATING then
TFAUpdateAttachments()
end

View File

@@ -0,0 +1,103 @@
--[[
| 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 presents from becoming blank
--[[
--general
TFA_GetStat(wepom,stat,value) --modify value in here, oh and you have to return
--deploy+init
TFA_SetupDataTables(wepom) --do things in here
TFA_PathStatsTable(wepom) --do things in here
TFA_PreInitialize(wepom) --do things in here
TFA_Initialize(wepom) --do things in here
TFA_PreDeploy(wepom) --do things in here
TFA_Deploy(wepom) --do things in here; return to override what the thingy returns
--holster+remove
TFA_PreHolster(wepom, target) --do things in here, called before we truly holster, but in the holster hook; return to override what the thingy returns
TFA_Holster(wepom) --really the finishholster func; return to override what the thingy returns
TFA_OnRemove(wepom) --return to override what the thingy returns
TFA_OnDrop(wepom) -- return to override what the thingy returns
--think
--primary fire related things
TFA_PreCanPrimaryAttack(wepom) --return to override our answer before doing base checks
TFA_CanPrimaryAttack(wepom) --return to override our answer, after TFA's checks
TFA_PrimaryAttack(wepom) --do things here; return to prevent proceeding
TFA_PostPrimaryAttack(wepom) --do things here
--secondary
TFA_SecondaryAttack(wepom) --do things here; return to override
--reload related things
TFA_PreReload(wepom,keyreleased) --called before sanity checks. do things here; return to prevent proceeding
TFA_Reload(wepom) --called when you take ammo. do things here; return to prevent proceeding
TFA_LoadShell(wepom) --called when insert a shotgun shell and play an animation. This runs before that; return to do your own logic
TFA_Pump(wepom) --called when you pump the shotgun as a separate action, playing the animation. This runs before that; return to do your own logic
TFA_CompleteReload(wepom) --the function that takes from reserve and loads into clip; return to override
TFA_CheckAmmo(wepom) --the function that fidgets when you reload with a full clip; return to override
TFA_PostReload(wepom) --do things here
--FOV
TFA_PreTranslateFOV(wepom,fov) --return a value to entirely override the fov with your own stuff, before TFA Base calcs it
TFA_TranslateFOV(wepom,fov) --return a value to modify the fov with your own stuff
--attachments
TFA_PreInitAttachments(wepom) --modify attachments here
TFA_PostInitAttachments(wepom) --runs before building attachment cache
TFA_FinalInitAttachments(wepom) --final attachment init hook
TFA_PreCanAttach(wepom, attid) --can we attach a thingy? called before exclusions/dependencies
TFA_CanAttach(wepom, attid) --can we attach a thingy? called after exclusions/dependencies
TFA_Attachment_Attached(wepom, attid, atttable, category, attindex, forced) --called after attachment was attached to the gun
TFA_Attachment_Detached(wepom, attid, atttable, category, attindex, forced) --called after attachment was detached from the gun
--animation
TFA_AnimationRate(wep,act,rate) --return modified rate value here
--effects
TFA_MakeShell(wep) --return something to cancel making a shell. runs predicted
TFA_EjectionSmoke(wep) --return something to cancel making an effect. runs predicted
TFA_MuzzleSmoke(wep) --return something to cancel making an effect. runs predicted
TFA_MuzzleFlash(wep) --return something to cancel making an effect. runs predicted
--ironsights
TFA_IronSightSounds(wepom) --called when we actually play a sound; return to prevent this
--HUD
TFA_DrawCrosshair(wepom, x, y) -- crosshair; return false to draw only hl2 crosshair, true to prevent drawing both
TFA_DrawHUDAmmo(wepom, x, y, alpha) -- 3d2d ammo indicator; return false to disable, true to override values (return true, x, y, alpha)
TFA_DrawScopeOverlay(wepom) -- called when 2d scope overlay is drawn; return true to prevent
--bash
TFA_CanBash(wepom) -- called before bashing; return false to prevent bashing
TFA_Bash(wepom) -- called after all checks, animation started playing
TFA_PostBash(wepom) -- do things here
--Inspection VGUI
TFA_InspectVGUI_Start(wepom) -- called before creating main panel; return false to prevent
TFA_InspectVGUI_Finish(wepom, mainpanel, contentpanel) -- called after adding every panel
TFA_InspectVGUI_InfoStart(wepom, contentpanel) -- called before adding main info (weapon name and stuff); return false to prevent
TFA_InspectVGUI_InfoFinish(wepom, contentpanel) -- called after adding main info
TFA_InspectVGUI_StatsStart(wepom, contentpanel) -- called before adding bottom info (stats); return false to prevent
TFA_InspectVGUI_StatsFinish(wepom, contentpanel) -- called after adding bottom info
TFA_InspectVGUI_AttachmentsStart(wepom, contentpanel) -- called before adding attachments panel; return false to prevent
TFA_InspectVGUI_AttachmentsFinish(wepom, contentpanel, attachmentspanel) -- called after adding attachments panel
TFA_InspectVGUI_FalloffStart(wepom, contentpanel) -- called before adding damage falloff graph; return false to prevent
TFA_InspectVGUI_FalloffFinish(wepom, contentpanel, falloffpanel) -- called after adding falloff panel
]]

View File

@@ -0,0 +1,713 @@
--[[
| 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/
--]]
-- TFA Base Template by TFA Base Devs
-- To the extent possible under law, the person who associated CC0 with
-- TFA Base Template has waived all copyright and related or neighboring rights
-- to TFA Base Template.
-- You should have received a copy of the CC0 legalcode along with this
-- work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --
-- ! ! --
-- ! WARNING! This template is outdated, not supported anymore ! --
-- ! and is only kept in for reference/comparison reasons. ! --
-- ! ! --
-- ! Please use the updated template ! --
-- ! located at lua/weapons/tfa_base_template/shared.lua ! --
-- ! for future weapon development purposes. ! --
-- ! ! --
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --
SWEP.Base = "tfa_gun_base"
SWEP.Category = "TFA Template" -- The category. Please, just choose something generic or something I've already done if you plan on only doing like one swep..
SWEP.Manufacturer = nil -- Gun Manufactrer (e.g. Hoeckler and Koch )
SWEP.Author = "" -- Author Tooltip
SWEP.Contact = "" -- Contact Info Tooltip
SWEP.Purpose = "" -- Purpose Tooltip
SWEP.Instructions = "" -- Instructions Tooltip
SWEP.Spawnable = false -- Can you, as a normal user, spawn this?
SWEP.AdminSpawnable = false -- Can an adminstrator spawn this? Does not tie into your admin mod necessarily, unless its coded to allow for GMod's default ranks somewhere in its code. Evolve and ULX should work, but try to use weapon restriction rather than these.
SWEP.DrawCrosshair = true -- Draw the crosshair?
SWEP.DrawCrosshairIS = false -- Draw the crosshair in ironsights?
SWEP.PrintName = "TFA Base Template" -- Weapon name (Shown on HUD)
SWEP.Slot = 2 -- Slot in the weapon selection menu. Subtract 1, as this starts at 0.
SWEP.SlotPos = 73 -- Position in the slot
SWEP.AutoSwitchTo = true -- Auto switch to if we pick it up
SWEP.AutoSwitchFrom = true -- Auto switch from if you pick up a better weapon
SWEP.Weight = 30 -- This controls how "good" the weapon is for autopickup.
-- [[WEAPON HANDLING]] --
SWEP.Primary.Sound = Sound("") -- This is the sound of the weapon, when you shoot.
SWEP.Primary.SilencedSound = nil -- This is the sound of the weapon, when silenced.
SWEP.Primary.PenetrationMultiplier = 1 -- Change the amount of something this gun can penetrate through
-- the LESSER this value is, the BETTER is penetration
-- this is basically multiplier for next values
-- you don't need to uncomment these if you are not going to modify them!
--[[
SWEP.PenetrationMaterials = {
[MAT_DEFAULT] = 1,
[MAT_VENT] = 0.4, --Since most is aluminum and stuff
[MAT_METAL] = 0.6, --Since most is aluminum and stuff
[MAT_WOOD] = 0.2,
[MAT_PLASTIC] = 0.23,
[MAT_FLESH] = 0.48,
[MAT_CONCRETE] = 0.87,
[MAT_GLASS] = 0.16,
[MAT_SAND] = 1,
[MAT_SLOSH] = 1,
[MAT_DIRT] = 0.95, --This is plaster, not dirt, in most cases.
[MAT_FOLIAGE] = 0.9
}
]]
SWEP.Primary.Damage = 0.01 -- Damage, in standard damage points.
SWEP.Primary.DamageTypeHandled = true -- true will handle damagetype in base
SWEP.Primary.DamageType = nil -- See DMG enum. This might be DMG_SHOCK, DMG_BURN, DMG_BULLET, etc. Leave nil to autodetect. DMG_AIRBOAT opens doors.
SWEP.Primary.Force = nil -- Force value, leave nil to autocalc
SWEP.Primary.Knockback = nil -- Autodetected if nil; this is the velocity kickback
SWEP.Primary.HullSize = 0 -- Big bullets, increase this value. They increase the hull size of the hitscan bullet.
SWEP.Primary.NumShots = 1 -- The number of shots the weapon fires. SWEP.Shotgun is NOT required for this to be >1.
SWEP.Primary.Automatic = true -- Automatic/Semi Auto
SWEP.Primary.RPM = 600 -- This is in Rounds Per Minute / RPM
SWEP.Primary.RPM_Semi = nil -- RPM for semi-automatic or burst fire. This is in Rounds Per Minute / RPM
SWEP.Primary.RPM_Burst = nil -- RPM for burst fire, overrides semi. This is in Rounds Per Minute / RPM
SWEP.Primary.DryFireDelay = nil -- How long you have to wait after firing your last shot before a dryfire animation can play. Leave nil for full empty attack length. Can also use SWEP.StatusLength[ ACT_VM_BLABLA ]
SWEP.Primary.BurstDelay = nil -- Delay between bursts, leave nil to autocalculate
SWEP.Primary.LoopSound = nil -- Looped fire sound, unsilenced
SWEP.Primary.LoopSoundSilenced = nil -- Looped fire sound, silenced
SWEP.Primary.LoopSoundTail = nil -- Loop end/tail sound, unsilenced
SWEP.Primary.LoopSoundTailSilenced = nil -- Loop end/tail sound, silenced
SWEP.Primary.LoopSoundAutoOnly = false -- Play loop sound for full-auto only? Fallbacks to Primary.Sound for semi/burst if true
-- WORLD/THIRDPERSON/NPC FIRING SOUNDS! Fallbacks to first person sound if not defined.
SWEP.Primary.Sound_World = nil -- This is the sound of the weapon, when you shoot.
SWEP.Primary.SilencedSound_World = nil -- This is the sound of the weapon, when silenced.
SWEP.Primary.LoopSound_World = nil -- Looped fire sound, unsilenced
SWEP.Primary.LoopSoundSilenced_World = nil -- Looped fire sound, silenced
SWEP.Primary.LoopSoundTail_World = nil -- Loop end/tail sound, unsilenced
SWEP.Primary.LoopSoundTailSilenced_World = nil -- Loop end/tail sound, silenced
SWEP.ViewModelPunchPitchMultiplier = nil -- Default value is 0.5
SWEP.ViewModelPunchPitchMultiplier_IronSights = nil -- Default value is 0.09
SWEP.ViewModelPunch_MaxVertialOffset = nil -- Default value is 3
SWEP.ViewModelPunch_MaxVertialOffset_IronSights = nil -- Default value is 1.95
SWEP.ViewModelPunch_VertialMultiplier = nil -- Default value is 1
SWEP.ViewModelPunch_VertialMultiplier_IronSights = nil -- Default value is 0.25
SWEP.ViewModelPunchYawMultiplier = nil -- Default value is 0.6
SWEP.ViewModelPunchYawMultiplier_IronSights = nil -- Default value is 0.25
SWEP.CanJam = true -- whenever weapon cam jam
SWEP.JamChance = 0.04 -- the (maximal) chance the weapon will jam. Newly spawned weapon will never jam on first shot for example.
-- Default value is 0.04 (4%)
-- Maxmial value is 1, means weapon will always jam when factor become 100
-- Also remember that there is a minimal factor before weapon can jam
-- This number is not treated "as-is" but as basic value that needs to be concluded as chance
-- You don't really need to cry over it and trying to balance it, TFA Base will do the job for you
-- (TFA Base will calculate the best value between 0 and JamChance based on current JamFactor of the weapon)
SWEP.JamFactor = 0.06 -- How to increase jam factor after each shot.
-- When factor reach 100 it will mean that on each shot there will be SWEP.Primary.JamChance chance to jam
-- When factor reach 50 it will mean that on each shot there will be SWEP.Primary.JamChance / 2 chance to jam
-- and so on
-- Default value is 0.06, means weapon will jam with SWEP.Primary.JamChance chance right after 1666 shots
-- These settings are good for Assault Rifles, however, not good for anything else.
-- Suggested stats:
--[[
-- Pistols
SWEP.JamChance = 0.20
SWEP.JamFactor = 0.14
]]
--[[
-- Revolvers
SWEP.JamChance = 0.17
SWEP.JamFactor = 0.50
]]
--[[
-- Miniguns
SWEP.JamChance = 0.03
SWEP.JamFactor = 0.01
]]
--[[
-- Submachine gun
SWEP.JamChance = 0.04
SWEP.JamFactor = 0.09
]]
--[[
-- Auto shotguns
SWEP.JamChance = 0.15
SWEP.JamFactor = 0.2
]]
--[[
-- Pump-action shotguns
SWEP.JamChance = 0.25
SWEP.JamFactor = 0.3
]]
--[[
-- Sniper rifle
SWEP.JamChance = 0.17
SWEP.JamFactor = 0.35
]]
SWEP.FiresUnderwater = false
-- Miscelaneous Sounds
SWEP.IronInSound = nil -- Sound to play when ironsighting in? nil for default
SWEP.IronOutSound = nil -- Sound to play when ironsighting out? nil for default
-- Silencing
SWEP.CanBeSilenced = false -- Can we silence? Requires animations.
SWEP.Silenced = false -- Silenced by default?
-- Selective Fire Stuff
SWEP.SelectiveFire = false -- Allow selecting your firemode?
SWEP.DisableBurstFire = false -- Only auto/single?
SWEP.OnlyBurstFire = false -- No auto, only burst/single?
SWEP.BurstFireCount = nil -- Burst fire count override (autocalculated by the clip size if nil)
SWEP.DefaultFireMode = "" -- Default to auto or whatev
SWEP.FireModeName = nil -- Change to a text value to override it
SWEP.FireSoundAffectedByClipSize = true -- Whenever adjuct pitch (and proably other properties) of fire sound based on current clip / maxclip
-- This is always false when either:
-- Weapon has no primary clip
-- Weapon's clip is smaller than 4 rounds
-- Weapon is a shotgun
-- Ammo Related
SWEP.Primary.ClipSize = 0 -- This is the size of a clip
SWEP.Primary.DefaultClip = 0 -- This is the number of bullets the gun gives you, counting a clip as defined directly above.
SWEP.Primary.Ammo = "none" -- What kind of ammo. Options, besides custom, include pistol, 357, smg1, ar2, buckshot, slam, SniperPenetratedRound, and AirboatGun.
SWEP.Primary.AmmoConsumption = 1 -- Ammo consumed per shot
-- Pistol, buckshot, and slam like to ricochet. Use AirboatGun for a light metal peircing shotgun pellets
SWEP.DisableChambering = false -- Disable round-in-the-chamber
-- Recoil Related
SWEP.Primary.KickUp = 0 -- This is the maximum upwards recoil (rise)
SWEP.Primary.KickDown = 0 -- This is the maximum downwards recoil (skeet)
SWEP.Primary.KickHorizontal = 0 -- This is the maximum sideways recoil (no real term)
SWEP.Primary.StaticRecoilFactor = 0.5 -- Amount of recoil to directly apply to EyeAngles. Enter what fraction or percentage (in decimal form) you want. This is also affected by a convar that defaults to 0.5.
-- Firing Cone Related
SWEP.Primary.Spread = .01 -- This is hip-fire acuracy. Less is more (1 is horribly awful, .0001 is close to perfect)
SWEP.Primary.IronAccuracy = .005 -- Ironsight accuracy, should be the same for shotguns
-- Unless you can do this manually, autodetect it. If you decide to manually do these, uncomment this block and remove this line.
SWEP.Primary.SpreadMultiplierMax = nil -- How far the spread can expand when you shoot. Example val: 2.5
SWEP.Primary.SpreadIncrement = nil -- What percentage of the modifier is added on, per shot. Example val: 1/3.5
SWEP.Primary.SpreadRecovery = nil -- How much the spread recovers, per second. Example val: 3
-- Range Related
-- DEPRECATED. Automatically converted to RangeFalloffLUT table
SWEP.Primary.Range = -1 -- The distance the bullet can travel in source units. Set to -1 to autodetect based on damage/rpm.
SWEP.Primary.RangeFalloff = -1 -- The percentage of the range the bullet damage starts to fall off at. Set to 0.8, for example, to start falling off after 80% of the range.
-- Use these if you don't want/understand how to use LUT below. These values are automatically converted to RangeFalloffLUT table
SWEP.Primary.FalloffMetricBased = false -- Set to true if you set up values below
SWEP.Primary.FalloffByMeter = nil -- How much damage points will bullet loose when travel
SWEP.Primary.MinRangeStartFalloff = nil -- How long will bullet travel in Meters before starting to lose damage?
SWEP.Primary.MaxFalloff = nil -- Maximal amount of damage to be lost
-- Use this for full control over damage dropoff.
--[[
SWEP.Primary.RangeFalloffLUT = {
bezier = true, -- Whenever to use Bezier or not to interpolate points?
-- you probably always want it to be set to true
range_func = "quintic", -- function to spline range
-- "linear" for linear splining.
-- Possible values are "quintic", "cubic", "cosine", "sinusine", "linear" or your own function
units = "meters", -- possible values are "inches", "inch", "hammer", "hu" (are all equal)
-- everything else is considered to be meters
lut = { -- providing zero point is not required
-- without zero point it is considered to be as {range = 0, damage = 1}
{range = 5, damage = 0.9},
{range = 12, damage = 0.8},
{range = 18, damage = 0.5},
{range = 24, damage = 0.2},
{range = 30, damage = 0.55},
{range = 38, damage = 0.76},
{range = 50, damage = 1},
{range = 52, damage = 0.96},
{range = 60, damage = 0.3},
{range = 70, damage = 0.1},
}
}
]]
SWEP.DisplayFalloff = nil -- Defaults to true (false for melees)
--[[
SWEP.Primary.RecoilLUT_IronSightsMult = nil -- Defaults to 0.5
-- controls how much effective LUT is when iron sighting
SWEP.Primary.RecoilLUT_AnglePunchMult = nil -- Defaults to 0.25
-- controls how much effective LUT at pushing EyeAngles of shooter
SWEP.Primary.RecoilLUT_ViewPunchMult = nil -- Defaults to 1
-- controls how much effective LUT at viewpunch
SWEP.Primary.RecoilLUT = {
["in"] = {
bezier = true,
func = "quintic", -- function to inerpolate progress when sampling points from table
-- Possible values are "quintic", "cubic", "cosine", "sinusine", "linear" or your own function
cooldown_speed = 1, -- how much to loose progress when we are at this stage
-- 1 means we lose entire progress in a second
increase = 0.1, -- how much to increase progress after shot
-- 0.1 means that this stage would be full after 10 shots
wait = 0.1, -- how much time do we wait in seconds after we stopped shooting
-- after this time, IN stage begin to cooldown until it reach zero
-- table is always prepended with an Angle()
-- only Pitch and Yaw are utilized
-- sampled point is added to aimvector of player
-- when they shoot
points = {
Angle(-1, 0.4),
Angle(-4, -2),
Angle(-6, -4),
Angle(-10, -6),
}
},
["loop"] = {
bezier = true,
func = "quintic",
-- this stage can not cooldown, so no cooldown_speed is defined
increase = 0.1, -- when LOOP stage reach 1, it is reset to 0
wait = 0.1, -- how much time do we wait in seconds after we stopped shooting
-- after this time, stage switch to OUT
-- table is NOT prepended with an Angle()
-- make sure it's starting point match the one from IN stage
-- last and first points are connected automatically
points = {
Angle(-10, -6),
Angle(-12, -0.4),
Angle(-8, 9),
Angle(-11, 12),
Angle(-13, 2),
Angle(-8, -4),
}
},
["out"] = {
bezier = true,
func = "quintic",
-- this stage is different
-- it is only started after LOOP took place
-- shooting in this stage will actually roll back it's state
-- until it reach zero and switch back to LOOP
-- cooling down actually increase stage's progress
cooldown_speed = 1,
-- increase act as negative number to reach zero in this stage
increase = 0.2,
-- after this stage reach 1, everything reset to IN and wait for next fire
-- table is always appended with an Angle()
-- starting point is dynamic
-- and will always match current LOOP's one
points = {
Angle(-7, -2),
Angle(-4, -1),
Angle(-2, 0),
}
}
}
]]
-- Penetration Related
SWEP.MaxPenetrationCounter = 4 -- The maximum number of ricochets. To prevent stack overflows.
-- Misc
SWEP.IronRecoilMultiplier = 0.5 -- Multiply recoil by this factor when we're in ironsights. This is proportional, not inversely.
SWEP.CrouchAccuracyMultiplier = 0.5 -- Less is more. Accuracy * 0.5 = Twice as accurate, Accuracy * 0.1 = Ten times as accurate
-- Movespeed
SWEP.MoveSpeed = 1 -- Multiply the player's movespeed by this.
SWEP.IronSightsMoveSpeed = 0.8 -- Multiply the player's movespeed by this when sighting.
-- PROJECTILES
SWEP.Primary.Projectile = nil -- Entity to shoot
SWEP.Primary.ProjectileVelocity = 0 -- Entity to shoot's velocity
SWEP.Primary.ProjectileModel = nil -- Entity to shoot's model
-- VIEWMODEL
SWEP.ViewModel = "models/your/path/here.mdl" -- Viewmodel path
SWEP.ViewModelFOV = 65 -- This controls how big the viewmodel looks. Less is more.
SWEP.ViewModelFlip = false -- Set this to true for CSS models, or false for everything else (with a righthanded viewmodel.)
SWEP.UseHands = false -- Use gmod c_arms system.
SWEP.VMPos = Vector(0, 0, 0) -- The viewmodel positional offset, constantly. Subtract this from any other modifications to viewmodel position.
SWEP.VMAng = Vector(0, 0, 0) -- The viewmodel angular offset, constantly. Subtract this from any other modifications to viewmodel angle.
SWEP.VMPos_Additive = true -- Set to false for an easier time using VMPos. If true, VMPos will act as a constant delta ON TOP OF ironsights, run, whateverelse
SWEP.CenteredPos = nil -- The viewmodel positional offset, used for centering. Leave nil to autodetect using ironsights.
SWEP.CenteredAng = nil -- The viewmodel angular offset, used for centering. Leave nil to autodetect using ironsights.
SWEP.Bodygroups_V = nil -- {
-- [0] = 1,
-- [1] = 4,
-- [2] = etc.
-- }
SWEP.AllowIronSightsDoF = true -- whenever allow DoF effect on viewmodel when zoomed in with iron sights
SWEP.IronSightsReloadEnabled = nil -- Enable ADS reload animations support (requires animations to be enabled in SWEP.Animations)
SWEP.IronSightsReloadLock = true -- Lock ADS state when reloading
-- WORLDMODEL
SWEP.WorldModel = "models/your/wmodel/path/here.mdl" -- Weapon world model path
SWEP.Bodygroups_W = nil -- {
-- [0] = 1,
-- [1] = 4,
-- [2] = etc.
-- }
SWEP.HoldType = "" -- This is how others view you carrying the weapon. Options include:
-- normal melee melee2 fist knife smg ar2 pistol rpg physgun grenade shotgun crossbow slam passive
-- You're mostly going to use ar2, smg, shotgun or pistol. rpg and crossbow make for good sniper rifles
SWEP.Offset = {
Pos = {
Up = 0,
Right = 0,
Forward = 0
},
Ang = {
Up = -1,
Right = -2,
Forward = 178
},
Scale = 1
} -- Procedural world model animation, defaulted for CS:S purposes.
SWEP.ThirdPersonReloadDisable = false -- Disable third person reload? True disables.
-- SCOPES
SWEP.IronSightsSensitivity = 1 -- Useful for a RT scope. Change this to 0.25 for 25% sensitivity. This is if normal FOV compenstaion isn't your thing for whatever reason, so don't change it for normal scopes.
SWEP.BoltAction = false -- Unscope/sight after you shoot?
SWEP.Scoped = false -- Draw a scope overlay?
SWEP.ScopeOverlayThreshold = 0.875 -- Percentage you have to be sighted in to see the scope.
SWEP.BoltTimerOffset = 0.25 -- How long you stay sighted in after shooting, with a bolt action.
SWEP.ScopeScale = 0.5 -- Scale of the scope overlay
SWEP.ReticleScale = 0.7 -- Scale of the reticle overlay
-- GDCW Overlay Options. Only choose one.
SWEP.Secondary.UseACOG = false -- Overlay option
SWEP.Secondary.UseMilDot = false -- Overlay option
SWEP.Secondary.UseSVD = false -- Overlay option
SWEP.Secondary.UseParabolic = false -- Overlay option
SWEP.Secondary.UseElcan = false -- Overlay option
SWEP.Secondary.UseGreenDuplex = false -- Overlay option
if surface then
SWEP.Secondary.ScopeTable = nil --[[
{
scopetex = surface.GetTextureID("scope/gdcw_closedsight"),
reticletex = surface.GetTextureID("scope/gdcw_acogchevron"),
dottex = surface.GetTextureID("scope/gdcw_acogcross")
}
]] --
end
-- [[SHOTGUN CODE]] --
SWEP.Shotgun = false -- Enable shotgun style reloading.
SWEP.ShotgunEmptyAnim = false -- Enable emtpy reloads on shotguns?
SWEP.ShotgunEmptyAnim_Shell = true -- Enable insertion of a shell directly into the chamber on empty reload?
SWEP.ShotgunStartAnimShell = false -- shotgun start anim inserts shell
SWEP.ShellTime = .35 -- For shotguns, how long it takes to insert a shell.
-- [[SPRINTING]] --
SWEP.RunSightsPos = Vector(0, 0, 0) -- Change this, using SWEP Creation Kit preferably
SWEP.RunSightsAng = Vector(0, 0, 0) -- Change this, using SWEP Creation Kit preferably
-- [[CROUCHING]] --
-- Viewmodel offset when player is crouched
-- SWEP.CrouchPos = Vector(0, 0, 0)
-- SWEP.CrouchAng = Vector(0, 0, 0)
-- [[IRONSIGHTS]] --
SWEP.data = {}
SWEP.data.ironsights = 1 -- Enable Ironsights
SWEP.Secondary.IronFOV = 70 -- How much you "zoom" in. Less is more! Don't have this be <= 0. A good value for ironsights is like 70.
-- SWEP.IronViewModelFOV = 65 -- Target viewmodel FOV when aiming down the sights.
SWEP.IronSightsPos = Vector(0, 0, 0) -- Change this, using SWEP Creation Kit preferably
SWEP.IronSightsAng = Vector(0, 0, 0) -- Change this, using SWEP Creation Kit preferably
-- [[INSPECTION]] --
SWEP.InspectPos = nil -- Vector(0, 0, 0) -- Replace with a vector, in style of ironsights position, to be used for inspection
SWEP.InspectAng = nil -- Vector(0, 0, 0) -- Replace with a vector, in style of ironsights angle, to be used for inspection
-- [[VIEWMODEL BLOWBACK]] --
SWEP.BlowbackEnabled = false -- Enable Blowback?
SWEP.BlowbackVector = Vector(0, -1, 0) -- Vector to move bone <or root> relative to bone <or view> orientation.
SWEP.BlowbackAngle = nil -- Angle(0, 0, 0)
SWEP.BlowbackCurrentRoot = 0 -- Amount of blowback currently, for root
SWEP.BlowbackCurrent = 0 -- Amount of blowback currently, for bones
SWEP.BlowbackBoneMods = nil -- Viewmodel bone mods via SWEP Creation Kit
SWEP.Blowback_Only_Iron = true -- Only do blowback on ironsights
SWEP.Blowback_PistolMode = false -- Do we recover from blowback when empty?
SWEP.Blowback_Shell_Enabled = true -- Shoot shells through blowback animations
SWEP.Blowback_Shell_Effect = "ShellEject" -- Which shell effect to use
SWEP.BlowbackAllowAnimation = nil -- Allow playing shoot animation with blowback?
-- [[VIEWMODEL PROCEDURAL ANIMATION]] --
SWEP.DoProceduralReload = false -- Animate first person reload using lua?
SWEP.ProceduralReloadTime = 1 -- Procedural reload time?
-- [[HOLDTYPES]] --
SWEP.IronSightHoldTypeOverride = "" -- This variable overrides the ironsights holdtype, choosing it instead of something from the above tables. Change it to "" to disable.
SWEP.SprintHoldTypeOverride = "" -- This variable overrides the sprint holdtype, choosing it instead of something from the above tables. Change it to "" to disable.
-- [[ANIMATION]] --
SWEP.StatusLengthOverride = {} -- Changes the status delay of a given animation; only used on reloads. Otherwise, use SequenceLengthOverride or one of the others
SWEP.SequenceLengthOverride = {} -- Changes both the status delay and the nextprimaryfire of a given animation
SWEP.SequenceTimeOverride = {} -- Like above but changes animation length to a target
SWEP.SequenceRateOverride = {} -- Like above but scales animation length rather than being absolute
SWEP.ProceduralHolsterEnabled = nil
SWEP.ProceduralHolsterTime = 0.3
SWEP.ProceduralHolsterPos = Vector(3, 0, -5)
SWEP.ProceduralHolsterAng = Vector(-40, -30, 10)
SWEP.Idle_Mode = TFA.Enum.IDLE_BOTH -- TFA.Enum.IDLE_DISABLED = no idle, TFA.Enum.IDLE_LUA = lua idle, TFA.Enum.IDLE_ANI = mdl idle, TFA.Enum.IDLE_BOTH = TFA.Enum.IDLE_ANI + TFA.Enum.IDLE_LUA
SWEP.Idle_Blend = 0.25 -- Start an idle this far early into the end of a transition
SWEP.Idle_Smooth = 0.05 -- Start an idle this far early into the end of another animation
-- MDL Animations Below
SWEP.Sights_Mode = TFA.Enum.LOCOMOTION_LUA -- LOCOMOTION_ANI = mdl, LOCOMOTION_HYBRID = ani + lua, LOCOMOTION_LUA = lua only
--[[
SWEP.IronAnimation = {
["in"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Idle_To_Iron", -- Number for act, String/Number for sequence
["value_empty"] = "Idle_To_Iron_Dry",
["transition"] = true
}, -- Inward transition
["loop"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Idle_Iron", -- Number for act, String/Number for sequence
["value_empty"] = "Idle_Iron_Dry"
}, -- Looping Animation
["out"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Iron_To_Idle", -- Number for act, String/Number for sequence
["value_empty"] = "Iron_To_Idle_Dry",
["transition"] = true
}, -- Outward transition
["shoot"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Fire_Iron", -- Number for act, String/Number for sequence
["value_last"] = "Fire_Iron_Last",
["value_empty"] = "Fire_Iron_Dry"
} -- What do you think
}
]]
SWEP.Sprint_Mode = TFA.Enum.LOCOMOTION_LUA -- LOCOMOTION_ANI = mdl, LOCOMOTION_HYBRID = ani + lua, LOCOMOTION_LUA = lua only
--[[
SWEP.SprintAnimation = {
["in"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Idle_to_Sprint", -- Number for act, String/Number for sequence
["value_empty"] = "Idle_to_Sprint_Empty",
["transition"] = true
}, -- Inward transition
["loop"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Sprint_", -- Number for act, String/Number for sequence
["value_empty"] = "Sprint_Empty_",
["is_idle"] = true
}, -- looping animation
["out"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Sprint_to_Idle", -- Number for act, String/Number for sequence
["value_empty"] = "Sprint_to_Idle_Empty",
["transition"] = true
} -- Outward transition
}
]]
SWEP.Walk_Mode = TFA.Enum.LOCOMOTION_LUA -- LOCOMOTION_ANI = mdl, LOCOMOTION_HYBRID = ani + lua, LOCOMOTION_LUA = lua only
--[[
SWEP.WalkAnimation = {
["in"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Idle_to_Walk", -- Number for act, String/Number for sequence
["value_empty"] = "Idle_to_Walk_Empty",
["transition"] = true
}, -- Inward transition
["loop"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Walk", -- Number for act, String/Number for sequence
["value_empty"] = "Walk_Empty",
["is_idle"] = true
}, -- looping animation
["out"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "Walk_to_Idle", -- Number for act, String/Number for sequence
["value_empty"] = "Walk_to_Idle_Empty",
["transition"] = true
} -- Outward transition
}
]]
--[[
-- Looping fire animation (full-auto only)
SWEP.ShootAnimation = {
["in"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "ShootLoop_Start", -- Number for act, String/Number for sequence
["value_is"] = "ShootLoop_Iron_Start", -- Number for act, String/Number for sequence
["transition"] = true
}, -- Looping Start, fallbacks to loop
["loop"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "ShootLoop", -- Number for act, String/Number for sequence,
["value_is"] = "ShootLoop_Iron", -- Number for act, String/Number for sequence,
["is_idle"] = true,
}, -- Looping Animation
["out"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "ShootLoop_End", -- Number for act, String/Number for sequence
["value_is"] = "ShootLoop_Iron_End", -- Number for act, String/Number for sequence
["transition"] = true
}, -- Looping End
}
]]
SWEP.Customize_Mode = TFA.Enum.LOCOMOTION_LUA -- LOCOMOTION_ANI = mdl, LOCOMOTION_HYBRID = ani + lua, LOCOMOTION_LUA = lua only
--[[
SWEP.CustomizeAnimation = {
["in"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "customization_in", -- Number for act, String/Number for sequence
["transition"] = true
},
["loop"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "customization_idle", -- Number for act, String/Number for sequence
["is_idle"] = true
},
["out"] = {
["type"] = TFA.Enum.ANIMATION_SEQ, -- Sequence or act
["value"] = "customization_out", -- Number for act, String/Number for sequence
["transition"] = true
}
}
]]
--[[
SWEP.PumpAction = { -- Pump/bolt animations
["type"] = TFA.Enum.ANIMATION_ACT, -- Sequence or act
["value"] = ACT_VM_PULLBACK_HIGH, -- Number for act, String/Number for sequence
["value_empty"] = ACT_VM_PULLBACK, -- Last shot pump
["value_is"] = ACT_VM_PULLBACK_LOW, -- ADS pump
}
]] --
-- [[EFFECTS]] --
-- Attachments
SWEP.MuzzleAttachment = "1" -- Should be "1" for CSS models or "muzzle" for hl2 models
SWEP.ShellAttachment = "2" -- Should be "2" for CSS models or "shell" for hl2 models
SWEP.MuzzleFlashEnabled = true -- Enable muzzle flash
SWEP.MuzzleAttachmentRaw = nil -- This will override whatever string you gave. This is the raw attachment number. This is overridden or created when a gun makes a muzzle event.
SWEP.AutoDetectMuzzleAttachment = false -- For multi-barrel weapons, detect the proper attachment?
SWEP.MuzzleFlashEffect = nil -- Change to a string of your muzzle flash effect. Copy/paste one of the existing from the base.
SWEP.SmokeParticle = nil -- Smoke particle (ID within the PCF), defaults to something else based on holdtype; "" to disable
SWEP.EjectionSmokeEnabled = true -- Disable automatic ejection smoke
-- Shell eject override
SWEP.LuaShellEject = false -- Enable shell ejection through lua?
SWEP.LuaShellEjectDelay = 0 -- The delay to actually eject things
SWEP.LuaShellModel = nil -- The model to use for ejected shells
SWEP.LuaShellScale = nil -- The model scale to use for ejected shells
SWEP.LuaShellYaw = nil -- The model yaw rotation ( relative ) to use for ejected shells
-- Tracer Stuff
SWEP.TracerName = nil -- Change to a string of your tracer name. Can be custom. There is a nice example at https://github.com/garrynewman/garrysmod/blob/master/garrysmod/gamemodes/base/entities/effects/tooltracer.lua
SWEP.TracerCount = 3 -- 0 disables, otherwise, 1 in X chance
-- Impact Effects
SWEP.ImpactEffect = nil -- Impact Effect
SWEP.ImpactDecal = nil -- Impact Decal
-- [[EVENT TABLE]] --
SWEP.EventTable = {} -- Event Table, used for custom events when an action is played. This can even do stuff like playing a pump animation after shooting.
-- example:
-- SWEP.EventTable = {
-- [ACT_VM_RELOAD] = {
-- -- ifp is IsFirstTimePredicted()
-- { ["time"] = 0.1, ["type"] = "lua", ["value"] = function( wep, viewmodel, ifp ) end, ["client"] = true, ["server"] = true},
-- { ["time"] = 0.1, ["type"] = "sound", ["value"] = Sound("x") }
-- }
-- }
-- [[RENDER TARGET]] --
SWEP.RTMaterialOverride = nil -- Take the material you want out of print(LocalPlayer():GetViewModel():GetMaterials()), subtract 1 from its index, and set it to this.
SWEP.RTOpaque = false -- Do you want your render target to be opaque?
SWEP.RTCode = nil -- function(self) return end -- This is the function to draw onto your rendertarget
SWEP.RTBGBlur = true -- Draw background blur when 3D scope is active?
-- [[AKIMBO]] --
SWEP.Akimbo = false -- Akimbo gun? Alternates between primary and secondary attacks.
SWEP.AnimCycle = 1 -- Start on the right
SWEP.AkimboHUD = true -- Draw holographic HUD for both weapons?
-- [[ATTACHMENTS]] --
SWEP.VElements = nil -- Export from SWEP Creation Kit. For each item that can/will be toggled, set active=false in its individual table
SWEP.WElements = nil -- Export from SWEP Creation Kit. For each item that can/will be toggled, set active=false in its individual table
SWEP.Attachments = {
-- [ORDER] = = { atts = { "si_eotech" }, sel = 0 }
-- sel allows you to have an attachment pre-selected, and is used internally by the base to show which attachment is selected in each category.
}
SWEP.AttachmentDependencies = {} -- {["si_acog"] = {"bg_rail", ["type"] = "OR"}} -- type could also be AND to require multiple
SWEP.AttachmentExclusions = {} -- { ["si_iron"] = { [1] = "bg_heatshield"} }
SWEP.AttachmentTableOverride = {} --[[{ -- overrides WeaponTable for attachments
["ins2_ub_laser"] = { -- attachment id, root of WeaponTable override
["VElements"] = {
["laser_rail"] = {
["active"] = true
},
},
}
}]]
SWEP.DInv2_GridSizeX = nil -- DInventory/2 Specific. Determines weapon's width in grid. This is not TFA Base specific and can be specified to any Scripted SWEP.
SWEP.DInv2_GridSizeY = nil -- DInventory/2 Specific. Determines weapon's height in grid. This is not TFA Base specific and can be specified to any Scripted SWEP.
SWEP.DInv2_Volume = nil -- DInventory/2 Specific. Determines weapon's volume in liters. This is not TFA Base specific and can be specified to any Scripted SWEP.
SWEP.DInv2_Mass = nil -- DInventory/2 Specific. Determines weapon's mass in kilograms. This is not TFA Base specific and can be specified to any Scripted SWEP.
-- [[MISC INFO FOR MODELERS]] --
--[[
Used Animations (for modelers):
ACT_VM_DRAW - Draw
ACT_VM_DRAW_EMPTY - Draw empty
ACT_VM_DRAW_SILENCED - Draw silenced, overrides empty
ACT_VM_IDLE - Idle
ACT_VM_IDLE_SILENCED - Idle empty, overwritten by silenced
ACT_VM_IDLE_SILENCED - Idle silenced
ACT_VM_PRIMARYATTACK - Shoot
ACT_VM_PRIMARYATTACK_EMPTY - Shoot last chambered bullet
ACT_VM_PRIMARYATTACK_SILENCED - Shoot silenced, overrides empty
ACT_VM_PRIMARYATTACK_1 - Shoot ironsights, overriden by everything besides normal shooting
ACT_VM_DRYFIRE - Dryfire
ACT_VM_RELOAD - Reload / Tactical Reload / Insert Shotgun Shell
ACT_SHOTGUN_RELOAD_START - Start shotgun reload, unless ACT_VM_RELOAD_EMPTY is there.
ACT_SHOTGUN_RELOAD_FINISH - End shotgun reload.
ACT_VM_RELOAD_EMPTY - Empty mag reload, chambers the new round. Works for shotguns too, where applicable.
ACT_VM_RELOAD_SILENCED - Silenced reload, overwrites all
ACT_VM_HOLSTER - Holster
ACT_VM_HOLSTER_SILENCED - Holster empty, overwritten by silenced
ACT_VM_HOLSTER_SILENCED - Holster silenced
]] --
DEFINE_BASECLASS( SWEP.Base )

View File

@@ -0,0 +1,102 @@
--[[
| 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/
--]]
-- TFA Base Melee Template by TFA Base Devs
-- To the extent possible under law, the person who associated CC0 with
-- TFA Base Template has waived all copyright and related or neighboring rights
-- to TFA Base Template.
-- You should have received a copy of the CC0 legalcode along with this
-- work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-- M9K compatible version is dated as 0 (and 0 is also fallback if TFADataVersion not present)
-- as well as everything made for TFA Base before 4.7
SWEP.TFADataVersion = 1
----------------- Basic Garry's Mod SWEP structure stats / TFA Base properties
SWEP.Base = "tfa_melee_base"
SWEP.Category = "TFA Template" -- The category.
-- Please, just choose something generic or something I've already done if you plan on only doing like one (or two or three) swep(s).
SWEP.Manufacturer = nil -- Gun Manufactrer (e.g. Hoeckler and Koch)
SWEP.Author = "" -- Author Tooltip
SWEP.Contact = "" -- Contact Info Tooltip
SWEP.Purpose = "" -- Purpose Tooltip
SWEP.Instructions = "" -- Instructions Tooltip
SWEP.Spawnable = false -- Can you, as a normal user, spawn this?
SWEP.AdminSpawnable = false -- Can an adminstrator spawn this? Does not tie into your admin mod necessarily, unless its coded to allow for GMod's default ranks somewhere in its code. Evolve and ULX should work, but try to use weapon restriction rather than these.
SWEP.DrawCrosshair = true -- Draw the crosshair?
SWEP.PrintName = "TFA Base Melee Template" -- Weapon name (Shown on HUD)
SWEP.Slot = 0 -- Slot in the weapon selection menu. Subtract 1, as this starts at 0.
SWEP.SlotPos = 73 -- Position in the slot
SWEP.AutoSwitchTo = true -- Auto switch to if we pick it up
SWEP.AutoSwitchFrom = true -- Auto switch from if you pick up a better weapon
SWEP.Weight = 30 -- This controls how "good" the weapon is for autopickup.
-- For base values please refer to the base template at lua/weapons/tfa_base_template/shared.lua
-- Display values (inspection screen etc.)
SWEP.Primary.Damage = 0.01 -- Damage, in standard damage points.
SWEP.Primary.RPM = 600 -- This is in Rounds Per Minute / RPM
----------------- ViewModel related
SWEP.ViewModel = "models/your/path/here.mdl" -- Viewmodel path
SWEP.ViewModelFOV = 65 -- This controls how big the viewmodel looks. Less is more.
SWEP.ViewModelFlip = false -- Set this to true for CSS models, or false for everything else (with a righthanded viewmodel.)
SWEP.UseHands = false -- Use gmod c_arms system.
----------------- Worldmodel related
SWEP.WorldModel = "models/your/wmodel/path/here.mdl" -- Weapon world model path
SWEP.HoldType = "" -- This is how others view you carrying the weapon. Options include:
-- normal melee melee2 fist knife smg ar2 pistol rpg physgun grenade shotgun crossbow slam passive
-- Attacks - Primary
SWEP.Primary.Attacks = { -- main attacks table, the values are selected randomly
{
["act"] = ACT_VM_HITLEFT, -- Animation acvitity to use (ACT_ enum value)
["len"] = 8 * 4.5, -- Trace distance
["src"] = Vector(20, 10, 0), -- Trace source; X ( +right, -left ), Y ( +forward, -back ), Z ( +up, -down )
["dir"] = Vector(-40, 30, 0), -- Trace direction/length; X ( +right, -left ), Y ( +forward, -back ), Z ( +up, -down )
["dmg"] = 60, -- Damage
["dmgtype"] = DMG_SLASH, -- Damage type (DMG_ enum value)
["delay"] = 0.2, -- Delay (in seconds) before attack trace
["force"] = 12, -- Damage force
["hull"] = 10, -- Trace hull size
["spr"] = true, -- Allow attack while sprinting?
["snd"] = "Swing.Sound", -- Soundscript name for swing sound
["hitflesh"] = "TFA.BashFlesh", -- Soundscript name for flesh hit
["hitworld"] = "TFA.BashWall", -- Soundscript name for non-flesh hit
["snd_delay"] = 0.1, -- Delay before swing sound
["viewpunch"] = Angle(1, -10, 0), -- Viewpunch angle
["end"] = 0.5, -- Time (from attack start) until next attack is allowed
["direction"] = "L", -- Swing direction (for directional preference); L,R,F,B
},
}
SWEP.Primary.MaxCombo = -1 -- How many attacks are allowed on single attack key hold
SWEP.Primary.Directional = false -- Prefer attacks with player's movement direction first
-- Attacks - Secondary
-- If secondary attacks table is empty or not defined, it falls back to primary table
SWEP.Secondary.Attacks = {} -- same as SWEP.Primary.Attacks
SWEP.Secondary.MaxCombo = -1
SWEP.Secondary.Directional = false
-- Attacks - Alternative (melee bash)
SWEP.Secondary.CanBash = true -- set to false to disable bashing
SWEP.Secondary.BashDamage = 25 -- Melee bash damage
SWEP.Secondary.BashSound = "TFA.Bash" -- Soundscript name for bash swing sound
SWEP.Secondary.BashHitSound = "TFA.BashWall" -- Soundscript name for non-flesh hit sound
SWEP.Secondary.BashHitSound_Flesh = "TFA.BashFlesh" -- Soundscript name for flesh hit sound
SWEP.Secondary.BashLength = 54 -- Length of bash melee trace in units
SWEP.Secondary.BashDelay = 0.2 -- Delay (in seconds) from bash start to bash attack trace
SWEP.Secondary.BashDamageType = DMG_SLASH -- Damage type (DMG_ enum value)
SWEP.Secondary.BashEnd = nil -- Bash end time (in seconds), defaults to animation end if undefined
SWEP.Secondary.BashInterrupt = false -- Bash attack interrupts everything (reload, draw, whatever)

View File

@@ -0,0 +1,45 @@
--[[
| 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.
-- luacheck: globals ACT_VM_FIDGET_EMPTY ACT_VM_FIDGET_SILENCED ACT_VM_BLOWBACK ACT_VM_HOLSTER_SILENCED
TFA.Enum.ANIMATION_ACT = 0
TFA.Enum.ANIMATION_SEQ = 1
ACT_VM_FIDGET_EMPTY = ACT_VM_FIDGET_EMPTY or ACT_CROSSBOW_FIDGET_UNLOADED
ACT_VM_FIDGET_SILENCED = ACT_VM_FIDGET_SILENCED or ACT_RPG_FIDGET_UNLOADED
ACT_VM_HOLSTER_SILENCED = ACT_VM_HOLSTER_SILENCED or ACT_CROSSBOW_HOLSTER_UNLOADED
ACT_VM_BLOWBACK = ACT_VM_BLOWBACK or -2
-- luacheck: globals ACT_VM_RELOAD_ADS ACT_VM_RELOAD_EMPTY_ADS ACT_VM_RELOAD_SILENCED_ADS ACT_SHOTGUN_RELOAD_START_ADS ACT_SHOTGUN_RELOAD_FINISH_ADS
ACT_VM_RELOAD_ADS = ACT_VM_RELOAD_ADS or ACT_IDLE_AIM_RIFLE_STIMULATED
ACT_VM_RELOAD_EMPTY_ADS = ACT_VM_RELOAD_EMPTY_ADS or ACT_WALK_AIM_RIFLE_STIMULATED
ACT_VM_RELOAD_SILENCED_ADS = ACT_VM_RELOAD_SILENCED_ADS or ACT_RUN_AIM_RIFLE_STIMULATED
ACT_SHOTGUN_RELOAD_START_ADS = ACT_SHOTGUN_RELOAD_START_ADS or ACT_IDLE_SHOTGUN_RELAXED
ACT_SHOTGUN_RELOAD_FINISH_ADS = ACT_SHOTGUN_RELOAD_FINISH_ADS or ACT_IDLE_SHOTGUN_STIMULATED

View File

@@ -0,0 +1,36 @@
--[[
| 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.
--IDLE TYPE ENUM
TFA.Enum.IDLE_DISABLED = 0
TFA.Enum.IDLE_LUA = 1
TFA.Enum.IDLE_ANI = 2
TFA.Enum.IDLE_BOTH = 3

View File

@@ -0,0 +1,35 @@
--[[
| 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.
--LOCOMOTION ENUM
TFA.Enum.LOCOMOTION_LUA = 0
TFA.Enum.LOCOMOTION_HYBRID = 1
TFA.Enum.LOCOMOTION_ANI = 2

View File

@@ -0,0 +1,37 @@
--[[
| 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.Enum.SIGHTSPOS_ATTACH = 0
TFA.Enum.SIGHTSPOS_BONE = 1
TFA.Enum.RETICLE_FLAT = 0
TFA.Enum.RETICLE_MODEL = 1
TFA.Enum.RETICLE_QUAD = 2

View File

@@ -0,0 +1,179 @@
--[[
| 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.ENUM_COUNTER = TFA.ENUM_COUNTER or 0
TFA.Enum.InverseStatus = TFA.Enum.InverseStatus or {}
local upper = string.upper
local function gen(input)
return "STATUS_" .. upper(input)
end
function TFA.AddStatus(input)
local key = gen(input)
local getkey = TFA.Enum[key]
if not getkey then
getkey = TFA.ENUM_COUNTER
TFA.ENUM_COUNTER = TFA.ENUM_COUNTER + 1
TFA.Enum[key] = getkey
end
TFA.Enum.InverseStatus[getkey] = key
return getkey
end
function TFA.GetStatus(input)
local key = gen(input)
local getkey = TFA.Enum[key]
if not getkey then
return TFA.AddStatus(input) -- DANGEROUS:
-- Race condition:
-- If something go terribly wrong and order of addition of new statuses fuck up
-- everything will fail horribly!
end
return getkey
end
TFA.AddStatus("idle")
TFA.AddStatus("draw")
TFA.AddStatus("holster")
TFA.AddStatus("holster_final")
TFA.AddStatus("holster_ready")
TFA.AddStatus("reloading")
TFA.AddStatus("reloading_wait")
TFA.AddStatus("reloading_loop_start")
TFA.AddStatus("reloading_loop_start_empty")
TFA.AddStatus("reloading_loop")
TFA.AddStatus("reloading_loop_end")
TFA.Enum.STATUS_RELOADING_SHOTGUN_START = TFA.Enum.STATUS_RELOADING_LOOP_START
TFA.Enum.STATUS_RELOADING_SHOTGUN_START_SHELL = TFA.Enum.STATUS_RELOADING_LOOP_START_EMPTY
TFA.Enum.STATUS_RELOADING_SHOTGUN_LOOP = TFA.Enum.STATUS_RELOADING_LOOP
TFA.Enum.STATUS_RELOADING_SHOTGUN_END = TFA.Enum.STATUS_RELOADING_LOOP_END
TFA.AddStatus("shooting")
TFA.AddStatus("silencer_toggle")
TFA.AddStatus("bashing")
TFA.AddStatus("bashing_wait")
TFA.AddStatus("inspecting")
TFA.AddStatus("fidget")
TFA.AddStatus("firemode")
TFA.AddStatus("pump")
TFA.AddStatus("grenade_pull")
TFA.AddStatus("grenade_ready")
TFA.AddStatus("grenade_throw")
TFA.AddStatus("blocking")
TFA.AddStatus("blocking_end")
TFA.AddStatus("bow_shoot")
TFA.AddStatus("bow_cancel")
TFA.AddStatus("grenade_pull")
TFA.AddStatus("grenade_throw")
TFA.AddStatus("grenade_ready")
TFA.AddStatus("grenade_throw_wait")
TFA.Enum.HolsterStatus = {
[TFA.Enum.STATUS_HOLSTER] = true,
[TFA.Enum.STATUS_HOLSTER_FINAL] = true,
[TFA.Enum.STATUS_HOLSTER_READY] = true
}
TFA.Enum.HolsterStatusFinal = {
[TFA.Enum.STATUS_HOLSTER_FINAL] = true,
[TFA.Enum.STATUS_HOLSTER_READY] = true
}
TFA.Enum.ReloadStatus = {
[TFA.Enum.STATUS_RELOADING] = true,
[TFA.Enum.STATUS_RELOADING_WAIT] = true,
[TFA.Enum.STATUS_RELOADING_LOOP_START] = true,
[TFA.Enum.STATUS_RELOADING_LOOP_START_EMPTY] = true,
[TFA.Enum.STATUS_RELOADING_LOOP] = true,
[TFA.Enum.STATUS_RELOADING_LOOP_END] = true
}
TFA.Enum.ReadyStatus = {
[TFA.Enum.STATUS_IDLE] = true,
[TFA.Enum.STATUS_INSPECTING] = true,
[TFA.Enum.STATUS_FIDGET] = true
}
TFA.Enum.IronStatus = {
[TFA.Enum.STATUS_IDLE] = true,
[TFA.Enum.STATUS_SHOOTING] = true,
[TFA.Enum.STATUS_PUMP] = true,
[TFA.Enum.STATUS_FIREMODE] = true--,
--[TFA.Enum.STATUS_FIDGET] = true
}
TFA.Enum.HUDDisabledStatus = {
[TFA.Enum.STATUS_IDLE] = true,
[TFA.Enum.STATUS_SHOOTING] = true,
[TFA.Enum.STATUS_FIREMODE] = true,
[TFA.Enum.STATUS_BASHING] = true,
[TFA.Enum.STATUS_BASHING_WAIT] = true,
[TFA.Enum.STATUS_HOLSTER] = true,
[TFA.Enum.STATUS_HOLSTER_FINAL] = true,
[TFA.Enum.STATUS_HOLSTER_READY] = true,
[TFA.Enum.STATUS_GRENADE_PULL] = true,
[TFA.Enum.STATUS_GRENADE_READY] = true,
[TFA.Enum.STATUS_GRENADE_THROW] = true,
[TFA.Enum.STATUS_BLOCKING] = true,
[TFA.Enum.STATUS_BLOCKING_END] = true,
[TFA.Enum.STATUS_PUMP] = true
}
TFA.Enum.SHOOT_IDLE = 0
TFA.Enum.SHOOT_START = 1
TFA.Enum.SHOOT_LOOP = 2
TFA.Enum.SHOOT_CHECK = 3
TFA.Enum.SHOOT_END = 4
TFA.Enum.ShootReadyStatus = {
[TFA.Enum.SHOOT_IDLE] = true,
[TFA.Enum.SHOOT_END] = true
}
TFA.Enum.ShootLoopingStatus = {
[TFA.Enum.SHOOT_START] = true,
[TFA.Enum.SHOOT_LOOP] = true,
[TFA.Enum.SHOOT_CHECK] = true
}

View File

@@ -0,0 +1,278 @@
--[[
| 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() end
TFA = TFA or {}
local do_load = true
local version = 50.454
local version_string = "50.4.5.4.0"
local changelog = [[
* Fixed bullet force value being completely ignored in favor of autocalculated one
* Various inspection menu improvements (localized weapon type, multiline description with word wrap)
* Fixed attachments not syncing properly from NPCs and other players
* Fixed skins not updating on worldmodels
]]
local function testFunc()
end
local my_path = debug.getinfo(testFunc)
if my_path and type(my_path) == "table" and my_path.short_src then
my_path = my_path["short_src"]
else
my_path = "legacy"
end
if TFA_BASE_VERSION then
if TFA_BASE_VERSION > version then
print("You have a newer, conflicting version of TFA Base.")
print("It's located at: " .. ( TFA_FILE_PATH or "" ) )
print("Contact the author of that pack, not TFA.")
do_load = false
elseif TFA_BASE_VERSION < version then
print("You have an older, conflicting version of TFA Base.")
print("It's located at: " .. ( TFA_FILE_PATH or "" ) )
print("Contact the author of that pack, not TFA.")
elseif TFA_BASE_VERSION == version then
print("You have an equal, conflicting version of TFA Base.")
print("It's located at: " .. ( TFA_FILE_PATH or "" ) )
print("Contact the author of that pack, not TFA.")
end
end
local official_modules_sorted = {
"tfa_commands.lua",
"cl_tfa_commands.lua", -- we need to load clientside convars before anything else
"tfa_data.lua",
"tfa_ammo.lua",
"tfa_attachments.lua",
"tfa_ballistics.lua",
"tfa_bodygroups.lua",
"tfa_darkrp.lua",
"tfa_effects.lua",
"tfa_envcheck.lua",
"tfa_functions.lua",
"tfa_hooks.lua",
"tfa_keybinds.lua",
"tfa_keyvalues.lua",
"tfa_matproxies.lua",
"tfa_melee_autorun.lua",
"tfa_meta.lua",
"tfa_netcode.lua",
"tfa_small_entities.lua",
"tfa_npc_weaponmenu.lua",
"tfa_nzombies.lua",
"tfa_particles.lua",
"tfa_snd_timescale.lua",
"tfa_soundscripts.lua",
"tfa_tttpatch.lua",
"sv_tfa_settingsmenu.lua",
"cl_tfa_attachment_icon.lua",
"cl_tfa_attachment_panel.lua",
"cl_tfa_attachment_tip.lua",
"cl_tfa_changelog.lua",
"cl_tfa_devtools.lua",
"cl_tfa_fonts.lua",
"cl_tfa_hitmarker.lua",
"cl_tfa_inspection.lua",
"cl_tfa_materials.lua",
"cl_tfa_models.lua",
"cl_tfa_particles_lua.lua",
"cl_tfa_projtex.lua",
"cl_tfa_rendertarget.lua",
"cl_tfa_rtbgblur.lua",
"cl_tfa_settingsmenu.lua",
"cl_tfa_vgui.lua",
"cl_tfa_vm_blur.lua",
"cl_tfa_stencilsights.lua",
}
local official_modules = {}
for _, modulename in ipairs(official_modules_sorted) do
official_modules[modulename] = true
end
if do_load then
-- luacheck: globals TFA_BASE_VERSION TFA_BASE_VERSION_STRING TFA_BASE_VERSION_CHANGES TFA_FILE_PATH
TFA_BASE_VERSION = version
TFA_BASE_VERSION_STRING = version_string
TFA_BASE_VERSION_CHANGES = changelog
TFA_FILE_PATH = my_path
TFA.Enum = TFA.Enum or {}
local flist = file.Find("tfa/enums/*.lua","LUA")
for _, filename in pairs(flist) do
local typev = "SHARED"
if filename:StartWith("cl_") then
typev = "CLIENT"
elseif filename:StartWith("sv_") then
typev = "SERVER"
end
if SERVER and typev ~= "SERVER" then
AddCSLuaFile("tfa/enums/" .. filename)
end
if SERVER and typev ~= "CLIENT" or CLIENT and typev ~= "SERVER" then
include("tfa/enums/" .. filename)
end
end
hook.Run("TFABase_PreEarlyInit")
for _, filename in ipairs(official_modules_sorted) do
if filename:StartWith("cl_") then
if SERVER then
AddCSLuaFile("tfa/modules/" .. filename)
else
include("tfa/modules/" .. filename)
end
elseif filename:StartWith("sv_") then
if SERVER then
include("tfa/modules/" .. filename)
end
else
if SERVER then
AddCSLuaFile("tfa/modules/" .. filename)
end
include("tfa/modules/" .. filename)
end
end
hook.Run("TFABase_EarlyInit")
hook.Run("TFABase_PreInit")
flist = file.Find("tfa/modules/*.lua", "LUA")
local toload = {}
local toload2 = {}
for _, filename in pairs(flist) do
if not official_modules[filename] then
local typev = "SHARED"
if filename:StartWith("cl_") then
typev = "CLIENT"
elseif filename:StartWith("sv_") then
typev = "SERVER"
end
if SERVER and typev ~= "SERVER" then
AddCSLuaFile("tfa/modules/" .. filename)
end
if SERVER and typev == "SERVER" or CLIENT and typev == "CLIENT" then
table.insert(toload2, filename)
elseif typev == "SHARED" then
table.insert(toload, filename)
end
end
end
local yell = #toload ~= 0 or #toload2 ~= 0
table.sort(toload)
table.sort(toload2)
for _, filename in ipairs(toload) do
include("tfa/modules/" .. filename)
print("[TFA Base] [!] Loaded unofficial module " .. string.sub(filename, 1, -5) .. ".")
end
for _, filename in ipairs(toload2) do
include("tfa/modules/" .. filename)
print("[TFA Base] [!] Loaded unofficial module " .. string.sub(filename, 1, -5) .. ".")
end
hook.Run("TFABase_Init")
hook.Run("TFABase_PreFullInit")
flist = file.Find("tfa/external/*.lua", "LUA")
toload = {}
toload2 = {}
for _, filename in pairs(flist) do
local typev = "SHARED"
if filename:StartWith("cl_") then
typev = "CLIENT"
elseif filename:StartWith("sv_") then
typev = "SERVER"
end
if SERVER and typev ~= "SERVER" then
AddCSLuaFile("tfa/external/" .. filename)
end
if SERVER and typev == "SERVER" or CLIENT and typev == "CLIENT" then
table.insert(toload2, filename)
elseif typev == "SHARED" then
table.insert(toload, filename)
end
end
table.sort(toload)
table.sort(toload2)
for _, filename in ipairs(toload) do
include("tfa/external/" .. filename)
end
for _, filename in ipairs(toload2) do
include("tfa/external/" .. filename)
end
if yell then
print("[TFA Base] [!] Some of files not belonging to TFA Base were loaded from tfa/modules/ directory")
print("[TFA Base] This behavior is kept for backward compatiblity and using this is highly discouraged!")
print("[TFA Base] Files loaded this way have no pre-defined sorting applied and result of execution of those files is undefined.")
print("[TFA Base] If you are author of these files, please consider moving your modules to tfa/external/ as soon as possible.")
end
hook.Run("TFABase_FullInit")
if not VLL2_FILEDEF then
TFAUpdateAttachments()
end
hook.Run("TFABase_LateInit")
end

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

Some files were not shown because too many files have changed in this diff Show More