mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
594
gamemodes/terrortown/entities/weapons/weapon_tttbase.lua
Normal file
594
gamemodes/terrortown/entities/weapons/weapon_tttbase.lua
Normal file
@@ -0,0 +1,594 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
-- Custom weapon base, used to derive from CS one, still very similar
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
---- TTT SPECIAL EQUIPMENT FIELDS
|
||||
|
||||
-- This must be set to one of the WEAPON_ types in TTT weapons for weapon
|
||||
-- carrying limits to work properly. See /gamemode/shared.lua for all possible
|
||||
-- weapon categories.
|
||||
SWEP.Kind = WEAPON_NONE
|
||||
|
||||
-- If CanBuy is a table that contains ROLE_TRAITOR and/or ROLE_DETECTIVE, those
|
||||
-- players are allowed to purchase it and it will appear in their Equipment Menu
|
||||
-- for that purpose. If CanBuy is nil this weapon cannot be bought.
|
||||
-- Example: SWEP.CanBuy = { ROLE_TRAITOR }
|
||||
-- (just setting to nil here to document its existence, don't make this buyable)
|
||||
SWEP.CanBuy = nil
|
||||
|
||||
if CLIENT then
|
||||
-- If this is a buyable weapon (ie. CanBuy is not nil) EquipMenuData must be
|
||||
-- a table containing some information to show in the Equipment Menu. See
|
||||
-- default equipment weapons for real-world examples.
|
||||
SWEP.EquipMenuData = nil
|
||||
|
||||
-- Example data:
|
||||
-- SWEP.EquipMenuData = {
|
||||
--
|
||||
---- Type tells players if it's a weapon or item
|
||||
-- type = "Weapon",
|
||||
--
|
||||
---- Desc is the description in the menu. Needs manual linebreaks (via \n).
|
||||
-- desc = "Text."
|
||||
-- };
|
||||
|
||||
-- This sets the icon shown for the weapon in the DNA sampler, search window,
|
||||
-- equipment menu (if buyable), etc.
|
||||
SWEP.Icon = "vgui/ttt/icon_nades" -- most generic icon I guess
|
||||
|
||||
-- You can make your own weapon icon using the template in:
|
||||
-- /garrysmod/gamemodes/terrortown/template/
|
||||
|
||||
-- Open one of TTT's icons with VTFEdit to see what kind of settings to use
|
||||
-- when exporting to VTF. Once you have a VTF and VMT, you can
|
||||
-- resource.AddFile("materials/vgui/...") them here. GIVE YOUR ICON A UNIQUE
|
||||
-- FILENAME, or it WILL be overwritten by other servers! Gmod does not check
|
||||
-- if the files are different, it only looks at the name. I recommend you
|
||||
-- create your own directory so that this does not happen,
|
||||
-- eg. /materials/vgui/ttt/mycoolserver/mygun.vmt
|
||||
end
|
||||
|
||||
---- MISC TTT-SPECIFIC BEHAVIOUR CONFIGURATION
|
||||
|
||||
-- ALL weapons in TTT must have weapon_tttbase as their SWEP.Base. It provides
|
||||
-- some functions that TTT expects, and you will get errors without them.
|
||||
-- Of course this is weapon_tttbase itself, so I comment this out here.
|
||||
-- SWEP.Base = "weapon_tttbase"
|
||||
|
||||
-- If true AND SWEP.Kind is not WEAPON_EQUIP, then this gun can be spawned as
|
||||
-- random weapon by a ttt_random_weapon entity.
|
||||
SWEP.AutoSpawnable = false
|
||||
|
||||
-- Set to true if weapon can be manually dropped by players (with Q)
|
||||
SWEP.AllowDrop = true
|
||||
|
||||
-- Set to true if weapon kills silently (no death scream)
|
||||
SWEP.IsSilent = false
|
||||
|
||||
-- If this weapon should be given to players upon spawning, set a table of the
|
||||
-- roles this should happen for here
|
||||
-- SWEP.InLoadoutFor = { ROLE_TRAITOR, ROLE_DETECTIVE, ROLE_INNOCENT }
|
||||
|
||||
-- DO NOT set SWEP.WeaponID. Only the standard TTT weapons can have it. Custom
|
||||
-- SWEPs do not need it for anything.
|
||||
-- SWEP.WeaponID = nil
|
||||
|
||||
---- YE OLDE SWEP STUFF
|
||||
|
||||
if CLIENT then
|
||||
SWEP.DrawCrosshair = false
|
||||
SWEP.ViewModelFOV = 82
|
||||
SWEP.ViewModelFlip = true
|
||||
SWEP.CSMuzzleFlashes = true
|
||||
end
|
||||
|
||||
SWEP.Base = "weapon_base"
|
||||
|
||||
SWEP.Category = "TTT"
|
||||
SWEP.Spawnable = false
|
||||
|
||||
SWEP.IsGrenade = false
|
||||
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.Primary.Sound = Sound( "Weapon_Pistol.Empty" )
|
||||
SWEP.Primary.Recoil = 1.5
|
||||
SWEP.Primary.Damage = 1
|
||||
SWEP.Primary.NumShots = 1
|
||||
SWEP.Primary.Cone = 0.02
|
||||
SWEP.Primary.Delay = 0.15
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "none"
|
||||
SWEP.Primary.ClipMax = -1
|
||||
|
||||
SWEP.Secondary.ClipSize = 1
|
||||
SWEP.Secondary.DefaultClip = 1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
SWEP.Secondary.ClipMax = -1
|
||||
|
||||
SWEP.HeadshotMultiplier = 2.7
|
||||
|
||||
SWEP.StoredAmmo = 0
|
||||
SWEP.IsDropped = false
|
||||
|
||||
SWEP.DeploySpeed = 1.4
|
||||
|
||||
SWEP.PrimaryAnim = ACT_VM_PRIMARYATTACK
|
||||
SWEP.ReloadAnim = ACT_VM_RELOAD
|
||||
|
||||
SWEP.fingerprints = {}
|
||||
|
||||
local sparkle = CLIENT and CreateConVar("ttt_crazy_sparks", "0", FCVAR_ARCHIVE)
|
||||
|
||||
-- crosshair
|
||||
if CLIENT then
|
||||
local sights_opacity = CreateConVar("ttt_ironsights_crosshair_opacity", "0.8", FCVAR_ARCHIVE)
|
||||
local crosshair_brightness = CreateConVar("ttt_crosshair_brightness", "1.0", FCVAR_ARCHIVE)
|
||||
local crosshair_size = CreateConVar("ttt_crosshair_size", "1.0", FCVAR_ARCHIVE)
|
||||
local disable_crosshair = CreateConVar("ttt_disable_crosshair", "0", FCVAR_ARCHIVE)
|
||||
|
||||
function SWEP:DrawHUD()
|
||||
if self.HUDHelp then
|
||||
self:DrawHelp()
|
||||
end
|
||||
|
||||
local client = LocalPlayer()
|
||||
if disable_crosshair:GetBool() or (not IsValid(client)) then return end
|
||||
|
||||
local sights = (not self.NoSights) and self:GetIronsights()
|
||||
|
||||
local x = math.floor(ScrW() / 2.0)
|
||||
local y = math.floor(ScrH() / 2.0)
|
||||
local scale = math.max(0.2, 10 * self:GetPrimaryCone())
|
||||
|
||||
local LastShootTime = self:LastShootTime()
|
||||
scale = scale * (2 - math.Clamp( (CurTime() - LastShootTime) * 5, 0.0, 1.0 ))
|
||||
|
||||
local alpha = sights and sights_opacity:GetFloat() or 1
|
||||
local bright = crosshair_brightness:GetFloat() or 1
|
||||
|
||||
-- somehow it seems this can be called before my player metatable
|
||||
-- additions have loaded
|
||||
if client.IsTraitor and client:IsTraitor() then
|
||||
surface.SetDrawColor(255 * bright,
|
||||
50 * bright,
|
||||
50 * bright,
|
||||
255 * alpha)
|
||||
else
|
||||
surface.SetDrawColor(0,
|
||||
255 * bright,
|
||||
0,
|
||||
255 * alpha)
|
||||
end
|
||||
|
||||
local gap = math.floor(20 * scale * (sights and 0.8 or 1))
|
||||
local length = math.floor(gap + (25 * crosshair_size:GetFloat()) * scale)
|
||||
surface.DrawLine( x - length, y, x - gap, y )
|
||||
surface.DrawLine( x + length, y, x + gap, y )
|
||||
surface.DrawLine( x, y - length, x, y - gap )
|
||||
surface.DrawLine( x, y + length, x, y + gap )
|
||||
end
|
||||
|
||||
local GetPTranslation = LANG.GetParamTranslation
|
||||
|
||||
-- Many non-gun weapons benefit from some help
|
||||
local help_spec = {text = "", font = "TabLarge", xalign = TEXT_ALIGN_CENTER}
|
||||
function SWEP:DrawHelp()
|
||||
local data = self.HUDHelp
|
||||
|
||||
local translate = data.translatable
|
||||
local primary = data.primary
|
||||
local secondary = data.secondary
|
||||
|
||||
if translate then
|
||||
primary = primary and GetPTranslation(primary, data.translate_params)
|
||||
secondary = secondary and GetPTranslation(secondary, data.translate_params)
|
||||
end
|
||||
|
||||
help_spec.pos = {ScrW() / 2.0, ScrH() - 40}
|
||||
help_spec.text = secondary or primary
|
||||
draw.TextShadow(help_spec, 2)
|
||||
|
||||
-- if no secondary exists, primary is drawn at the bottom and no top line
|
||||
-- is drawn
|
||||
if secondary then
|
||||
help_spec.pos[2] = ScrH() - 60
|
||||
help_spec.text = primary
|
||||
draw.TextShadow(help_spec, 2)
|
||||
end
|
||||
end
|
||||
|
||||
-- mousebuttons are enough for most weapons
|
||||
local default_key_params = {
|
||||
primaryfire = Key("+attack", "LEFT MOUSE"),
|
||||
secondaryfire = Key("+attack2", "RIGHT MOUSE"),
|
||||
usekey = Key("+use", "USE")
|
||||
};
|
||||
|
||||
function SWEP:AddHUDHelp(primary_text, secondary_text, translate, extra_params)
|
||||
extra_params = extra_params or {}
|
||||
|
||||
self.HUDHelp = {
|
||||
primary = primary_text,
|
||||
secondary = secondary_text,
|
||||
translatable = translate,
|
||||
translate_params = table.Merge(extra_params, default_key_params)
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
-- Shooting functions largely copied from weapon_cs_base
|
||||
function SWEP:PrimaryAttack(worldsnd)
|
||||
|
||||
self:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
|
||||
self:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
|
||||
|
||||
if not self:CanPrimaryAttack() then return end
|
||||
|
||||
if not worldsnd then
|
||||
self:EmitSound( self.Primary.Sound, self.Primary.SoundLevel )
|
||||
elseif SERVER then
|
||||
sound.Play(self.Primary.Sound, self:GetPos(), self.Primary.SoundLevel)
|
||||
end
|
||||
|
||||
self:ShootBullet( self.Primary.Damage, self.Primary.Recoil, self.Primary.NumShots, self:GetPrimaryCone() )
|
||||
|
||||
self:TakePrimaryAmmo( 1 )
|
||||
|
||||
local owner = self:GetOwner()
|
||||
if not IsValid(owner) or owner:IsNPC() or (not owner.ViewPunch) then return end
|
||||
|
||||
owner:ViewPunch( Angle( util.SharedRandom(self:GetClass(),-0.2,-0.1,0) * self.Primary.Recoil, util.SharedRandom(self:GetClass(),-0.1,0.1,1) * self.Primary.Recoil, 0 ) )
|
||||
end
|
||||
|
||||
function SWEP:DryFire(setnext)
|
||||
if CLIENT and LocalPlayer() == self:GetOwner() then
|
||||
self:EmitSound( "Weapon_Pistol.Empty" )
|
||||
end
|
||||
|
||||
setnext(self, CurTime() + 0.2)
|
||||
|
||||
self:Reload()
|
||||
end
|
||||
|
||||
function SWEP:CanPrimaryAttack()
|
||||
if not IsValid(self:GetOwner()) then return end
|
||||
|
||||
if self:Clip1() <= 0 then
|
||||
self:DryFire(self.SetNextPrimaryFire)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:CanSecondaryAttack()
|
||||
if not IsValid(self:GetOwner()) then return end
|
||||
|
||||
if self:Clip2() <= 0 then
|
||||
self:DryFire(self.SetNextSecondaryFire)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function Sparklies(attacker, tr, dmginfo)
|
||||
if tr.HitWorld and tr.MatType == MAT_METAL then
|
||||
local eff = EffectData()
|
||||
eff:SetOrigin(tr.HitPos)
|
||||
eff:SetNormal(tr.HitNormal)
|
||||
util.Effect("cball_bounce", eff)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:ShootBullet( dmg, recoil, numbul, cone )
|
||||
|
||||
self:SendWeaponAnim(self.PrimaryAnim)
|
||||
|
||||
self:GetOwner():MuzzleFlash()
|
||||
self:GetOwner():SetAnimation( PLAYER_ATTACK1 )
|
||||
|
||||
local sights = self:GetIronsights()
|
||||
|
||||
numbul = numbul or 1
|
||||
cone = cone or 0.01
|
||||
|
||||
local bullet = {}
|
||||
bullet.Num = numbul
|
||||
bullet.Src = self:GetOwner():GetShootPos()
|
||||
bullet.Dir = self:GetOwner():GetAimVector()
|
||||
bullet.Spread = Vector( cone, cone, 0 )
|
||||
bullet.Tracer = 4
|
||||
bullet.TracerName = self.Tracer or "Tracer"
|
||||
bullet.Force = 10
|
||||
bullet.Damage = dmg
|
||||
if CLIENT and sparkle:GetBool() then
|
||||
bullet.Callback = Sparklies
|
||||
end
|
||||
|
||||
self:GetOwner():FireBullets( bullet )
|
||||
|
||||
-- Owner can die after firebullets
|
||||
if (not IsValid(self:GetOwner())) or self:GetOwner():IsNPC() or (not self:GetOwner():Alive()) then return end
|
||||
|
||||
if ((game.SinglePlayer() and SERVER) or
|
||||
((not game.SinglePlayer()) and CLIENT and IsFirstTimePredicted())) then
|
||||
|
||||
-- reduce recoil if ironsighting
|
||||
recoil = sights and (recoil * 0.6) or recoil
|
||||
|
||||
local eyeang = self:GetOwner():EyeAngles()
|
||||
eyeang.pitch = eyeang.pitch - recoil
|
||||
self:GetOwner():SetEyeAngles( eyeang )
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:GetPrimaryCone()
|
||||
local cone = self.Primary.Cone or 0.2
|
||||
-- 15% accuracy bonus when sighting
|
||||
return self:GetIronsights() and (cone * 0.85) or cone
|
||||
end
|
||||
|
||||
function SWEP:GetHeadshotMultiplier(victim, dmginfo)
|
||||
return self.HeadshotMultiplier
|
||||
end
|
||||
|
||||
function SWEP:IsEquipment()
|
||||
return WEPS.IsEquipment(self)
|
||||
end
|
||||
|
||||
function SWEP:DrawWeaponSelection() end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
if self.NoSights or (not self.IronSightsPos) then return end
|
||||
|
||||
self:SetIronsights(not self:GetIronsights())
|
||||
|
||||
self:SetNextSecondaryFire(CurTime() + 0.3)
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
self:SetIronsights(false)
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
if ( self:Clip1() == self.Primary.ClipSize or self:GetOwner():GetAmmoCount( self.Primary.Ammo ) <= 0 ) then return end
|
||||
self:DefaultReload(self.ReloadAnim)
|
||||
self:SetIronsights( false )
|
||||
end
|
||||
|
||||
|
||||
function SWEP:OnRestore()
|
||||
self.NextSecondaryAttack = 0
|
||||
self:SetIronsights( false )
|
||||
end
|
||||
|
||||
function SWEP:Ammo1()
|
||||
return IsValid(self:GetOwner()) and self:GetOwner():GetAmmoCount(self.Primary.Ammo) or false
|
||||
end
|
||||
|
||||
-- The OnDrop() hook is useless for this as it happens AFTER the drop. OwnerChange
|
||||
-- does not occur when a drop happens for some reason. Hence this thing.
|
||||
function SWEP:PreDrop()
|
||||
if SERVER and IsValid(self:GetOwner()) and self.Primary.Ammo != "none" then
|
||||
local ammo = self:Ammo1()
|
||||
|
||||
-- Do not drop ammo if we have another gun that uses this type
|
||||
for _, w in ipairs(self:GetOwner():GetWeapons()) do
|
||||
if IsValid(w) and w != self and w:GetPrimaryAmmoType() == self:GetPrimaryAmmoType() then
|
||||
ammo = 0
|
||||
end
|
||||
end
|
||||
|
||||
self.StoredAmmo = ammo
|
||||
|
||||
if ammo > 0 then
|
||||
self:GetOwner():RemoveAmmo(ammo, self.Primary.Ammo)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:DampenDrop()
|
||||
-- For some reason gmod drops guns on death at a speed of 400 units, which
|
||||
-- catapults them away from the body. Here we want people to actually be able
|
||||
-- to find a given corpse's weapon, so we override the velocity here and call
|
||||
-- this when dropping guns on death.
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:SetVelocityInstantaneous(Vector(0,0,-75) + phys:GetVelocity() * 0.001)
|
||||
phys:AddAngleVelocity(phys:GetAngleVelocity() * -0.99)
|
||||
end
|
||||
end
|
||||
|
||||
local SF_WEAPON_START_CONSTRAINED = 1
|
||||
|
||||
-- Picked up by player. Transfer of stored ammo and such.
|
||||
function SWEP:Equip(newowner)
|
||||
if SERVER then
|
||||
if self:IsOnFire() then
|
||||
self:Extinguish()
|
||||
end
|
||||
|
||||
self.fingerprints = self.fingerprints or {}
|
||||
|
||||
if not table.HasValue(self.fingerprints, newowner) then
|
||||
table.insert(self.fingerprints, newowner)
|
||||
end
|
||||
|
||||
if self:HasSpawnFlags(SF_WEAPON_START_CONSTRAINED) then
|
||||
-- If this weapon started constrained, unset that spawnflag, or the
|
||||
-- weapon will be re-constrained and float
|
||||
local flags = self:GetSpawnFlags()
|
||||
local newflags = bit.band(flags, bit.bnot(SF_WEAPON_START_CONSTRAINED))
|
||||
self:SetKeyValue("spawnflags", newflags)
|
||||
end
|
||||
end
|
||||
|
||||
if SERVER and IsValid(newowner) and self.StoredAmmo > 0 and self.Primary.Ammo != "none" then
|
||||
local ammo = newowner:GetAmmoCount(self.Primary.Ammo)
|
||||
local given = math.min(self.StoredAmmo, self.Primary.ClipMax - ammo)
|
||||
|
||||
newowner:GiveAmmo( given, self.Primary.Ammo)
|
||||
self.StoredAmmo = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- We were bought as special equipment, some weapons will want to do something
|
||||
-- extra for their buyer
|
||||
function SWEP:WasBought(buyer)
|
||||
end
|
||||
|
||||
function SWEP:SetIronsights(b)
|
||||
if (b ~= self:GetIronsights()) then
|
||||
self:SetIronsightsPredicted(b)
|
||||
self:SetIronsightsTime(CurTime())
|
||||
if CLIENT then
|
||||
self:CalcViewModel()
|
||||
end
|
||||
end
|
||||
end
|
||||
function SWEP:GetIronsights()
|
||||
return self:GetIronsightsPredicted()
|
||||
end
|
||||
|
||||
--- Dummy functions that will be replaced when SetupDataTables runs. These are
|
||||
--- here for when that does not happen (due to e.g. stacking base classes)
|
||||
function SWEP:GetIronsightsTime() return -1 end
|
||||
function SWEP:SetIronsightsTime( time ) end
|
||||
function SWEP:GetIronsightsPredicted() return false end
|
||||
function SWEP:SetIronsightsPredicted( bool ) end
|
||||
|
||||
-- Set up ironsights dt bool. Weapons using their own DT vars will have to make
|
||||
-- sure they call this.
|
||||
function SWEP:SetupDataTables()
|
||||
self:NetworkVar("Bool", 3, "IronsightsPredicted")
|
||||
self:NetworkVar("Float", 3, "IronsightsTime")
|
||||
end
|
||||
|
||||
function SWEP:Initialize()
|
||||
if CLIENT and self:Clip1() == -1 then
|
||||
self:SetClip1(self.Primary.DefaultClip)
|
||||
elseif SERVER then
|
||||
self.fingerprints = {}
|
||||
|
||||
self:SetIronsights(false)
|
||||
end
|
||||
|
||||
self:SetDeploySpeed(self.DeploySpeed)
|
||||
|
||||
-- compat for gmod update
|
||||
if self.SetHoldType then
|
||||
self:SetHoldType(self.HoldType or "pistol")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:CalcViewModel()
|
||||
if (not CLIENT) or (not IsFirstTimePredicted() and not game.SinglePlayer()) then return end
|
||||
self.bIron = self:GetIronsights()
|
||||
self.fIronTime = self:GetIronsightsTime()
|
||||
self.fCurrentTime = CurTime()
|
||||
self.fCurrentSysTime = SysTime()
|
||||
end
|
||||
|
||||
-- Note that if you override Think in your SWEP, you should call
|
||||
-- BaseClass.Think(self) so as not to break ironsights
|
||||
function SWEP:Think()
|
||||
self:CalcViewModel()
|
||||
end
|
||||
|
||||
function SWEP:DyingShot()
|
||||
local fired = false
|
||||
if self:GetIronsights() then
|
||||
self:SetIronsights(false)
|
||||
|
||||
if self:GetNextPrimaryFire() > CurTime() then
|
||||
return fired
|
||||
end
|
||||
|
||||
-- Owner should still be alive here
|
||||
if IsValid(self:GetOwner()) then
|
||||
local punch = self.Primary.Recoil or 5
|
||||
|
||||
-- Punch view to disorient aim before firing dying shot
|
||||
local eyeang = self:GetOwner():EyeAngles()
|
||||
eyeang.pitch = eyeang.pitch - math.Rand(-punch, punch)
|
||||
eyeang.yaw = eyeang.yaw - math.Rand(-punch, punch)
|
||||
self:GetOwner():SetEyeAngles( eyeang )
|
||||
|
||||
MsgN(self:GetOwner():Nick() .. " fired his DYING SHOT")
|
||||
|
||||
self:GetOwner().dying_wep = self
|
||||
|
||||
self:PrimaryAttack(true)
|
||||
|
||||
fired = true
|
||||
end
|
||||
end
|
||||
|
||||
return fired
|
||||
end
|
||||
|
||||
local ttt_lowered = CreateConVar("ttt_ironsights_lowered", "1", FCVAR_ARCHIVE)
|
||||
local host_timescale = GetConVar("host_timescale")
|
||||
|
||||
local LOWER_POS = Vector(0, 0, -2)
|
||||
|
||||
local IRONSIGHT_TIME = 0.25
|
||||
function SWEP:GetViewModelPosition( pos, ang )
|
||||
if (not self.IronSightsPos) or (self.bIron == nil) then return pos, ang end
|
||||
|
||||
local bIron = self.bIron
|
||||
local time = self.fCurrentTime + (SysTime() - self.fCurrentSysTime) * game.GetTimeScale() * host_timescale:GetFloat()
|
||||
|
||||
if bIron then
|
||||
self.SwayScale = 0.3
|
||||
self.BobScale = 0.1
|
||||
else
|
||||
self.SwayScale = 1.0
|
||||
self.BobScale = 1.0
|
||||
end
|
||||
|
||||
local fIronTime = self.fIronTime
|
||||
if (not bIron) and fIronTime < time - IRONSIGHT_TIME then
|
||||
return pos, ang
|
||||
end
|
||||
|
||||
local mul = 1.0
|
||||
|
||||
if fIronTime > time - IRONSIGHT_TIME then
|
||||
mul = math.Clamp( (time - fIronTime) / IRONSIGHT_TIME, 0, 1 )
|
||||
|
||||
if not bIron then mul = 1 - mul end
|
||||
end
|
||||
|
||||
local offset = self.IronSightsPos + (ttt_lowered:GetBool() and LOWER_POS or vector_origin)
|
||||
|
||||
if self.IronSightsAng then
|
||||
ang = ang * 1
|
||||
ang:RotateAroundAxis( ang:Right(), self.IronSightsAng.x * mul )
|
||||
ang:RotateAroundAxis( ang:Up(), self.IronSightsAng.y * mul )
|
||||
ang:RotateAroundAxis( ang:Forward(), self.IronSightsAng.z * mul )
|
||||
end
|
||||
|
||||
pos = pos + offset.x * ang:Right() * mul
|
||||
pos = pos + offset.y * ang:Forward() * mul
|
||||
pos = pos + offset.z * ang:Up() * mul
|
||||
|
||||
return pos, ang
|
||||
end
|
||||
Reference in New Issue
Block a user