6ad75df85d
Even though git internally knows the difference between upper and lower case, all of it's commands rely on the file system to do so as well. This results in incorrect behavior when renaming A to a for example, as the source and destination is identical on the file system according to git. Windows does support such renames, but git seems to shit itself.
252 lines
7.7 KiB
Lua
252 lines
7.7 KiB
Lua
-- SWEP Information
|
|
SWEP.Author = "Michael 'Xaymar' Dirks"
|
|
SWEP.Contact = "info@project-kube.de"
|
|
SWEP.PrintName = "PH Submachine Gun"
|
|
SWEP.Purpose = "More accurate SMG for Prop Hunt."
|
|
SWEP.Instructions = "Fire away! Alternative fire to fire a grenade."
|
|
SWEP.Category = "Prop Hunt Weapons"
|
|
|
|
-- Weapon Information
|
|
SWEP.Weight = 5
|
|
SWEP.AutoSwitchTo = false
|
|
SWEP.AutoSwitchFrom = false
|
|
|
|
SWEP.Slot = 2
|
|
SWEP.SlotPos = 1
|
|
SWEP.DrawAmmo = true
|
|
SWEP.DrawCrosshair = true
|
|
|
|
-- Weapon is spawnable for everyone, not just administrators.
|
|
SWEP.Spawnable = true
|
|
SWEP.AdminSpawnable = true
|
|
|
|
-- Model
|
|
SWEP.ViewModel = "models/weapons/c_smg1.mdl"
|
|
SWEP.WorldModel = "models/weapons/w_smg1.mdl"
|
|
SWEP.UseHands = true
|
|
|
|
-- Primary Ammunition: SMG
|
|
SWEP.Primary.ClipSize = 45
|
|
SWEP.Primary.DefaultClip = 45
|
|
SWEP.Primary.Automatic = true
|
|
SWEP.Primary.Ammo = "SMG1"
|
|
SWEP.Primary.Damage = 5
|
|
SWEP.Primary.RefireTime = 0.1
|
|
|
|
-- Secondary Ammunition: SMG Grenades
|
|
SWEP.Secondary.ClipSize = 1
|
|
SWEP.Secondary.DefaultClip = 0
|
|
SWEP.Secondary.Automatic = false
|
|
SWEP.Secondary.Ammo = "SMG1_Grenade"
|
|
SWEP.Secondary.Damage = 100
|
|
SWEP.Secondary.RefireTime = 1.0
|
|
|
|
-- Recoil
|
|
SWEP.Recoil = {}
|
|
SWEP.Recoil.SingleFire = 0.2
|
|
SWEP.Recoil.BurstFire = 1.0
|
|
SWEP.Recoil.SecondaryFire = 8.0
|
|
|
|
-- Accuracy
|
|
SWEP.Accuracy = {}
|
|
SWEP.Accuracy.Primary = {}
|
|
SWEP.Accuracy.Primary.Min = 0.975
|
|
SWEP.Accuracy.Primary.Max = 1.00
|
|
SWEP.Accuracy.Primary.Reduction = 0.005
|
|
SWEP.Accuracy.Primary.Recovery = 0.0025
|
|
SWEP.Accuracy.Primary.Delay = 0.1
|
|
SWEP.Accuracy.Secondary = {}
|
|
SWEP.Accuracy.Secondary.Min = 1.00
|
|
SWEP.Accuracy.Secondary.Max = 1.00
|
|
SWEP.Accuracy.Secondary.Reduction = 0.00
|
|
SWEP.Accuracy.Secondary.Recovery = 0.00
|
|
SWEP.Accuracy.Secondary.Delay = 0.00
|
|
|
|
-- Sounds
|
|
SWEP.Sound = {}
|
|
SWEP.Sound.SwitchSingle = "weapons/smg1/switch_single.wav"
|
|
SWEP.Sound.SwitchBurst = "weapons/smg1/switch_burst.wav"
|
|
SWEP.Sound.SingleFire = "weapons/smg1/smg1_fire1.wav"
|
|
SWEP.Sound.BurstFire = "weapons/smg1/smg1_fireburst1.wav"
|
|
SWEP.Sound.SecondaryFire = "weapons/ar2/ar2_altfire.wav"
|
|
SWEP.Sound.Reload = "weapons/smg1/smg1_reload.wav"
|
|
SWEP.Sound.NoPrimaryAmmo = "weapons/pistol/pistol_empty.wav"
|
|
SWEP.Sound.NoSecondaryAmmo = "weapons/pistol/pistol_empty.wav"
|
|
|
|
-- Initialization
|
|
function SWEP:Initialize()
|
|
-- Set holding type to smg.
|
|
self:SetHoldType("smg");
|
|
|
|
-- Precache sounds for lagless experience.
|
|
for i,v in ipairs(self.Sound) do
|
|
util.PrecacheSound(v)
|
|
end
|
|
|
|
-- Initialize default values.
|
|
self.BurstFire = false
|
|
self:SetNWBool("BurstFire", false)
|
|
self.LastReload = CurTime()
|
|
|
|
self.PrimaryAccuracy = self.Accuracy.Primary.Max
|
|
self.LastPrimaryAttack = CurTime()
|
|
self.SecondaryAccuracy = self.Accuracy.Secondary.Max
|
|
self.LastSecondaryAttack = CurTime()
|
|
|
|
end
|
|
|
|
-- Primary Attack
|
|
function SWEP:CanPrimaryAttack()
|
|
-- Check if there is ammo in the clip.
|
|
if (self:Clip1() <= 0) then
|
|
-- If not, check if there's ammo available.
|
|
if (self:Ammo1() > 0) then
|
|
-- If yes, reload and wait for weapon to be ready again.
|
|
self.Weapon:EmitSound(self.Sound.NoPrimaryAmmo)
|
|
self:Reload()
|
|
return false
|
|
end
|
|
|
|
-- If no, emit empty sound for primary fire.
|
|
self.Weapon:EmitSound(self.Sound.NoPrimaryAmmo)
|
|
self:SetNextPrimaryFire(CurTime() + 0.1)
|
|
return false
|
|
end
|
|
|
|
-- Otherwise, return true.
|
|
return true
|
|
end
|
|
|
|
function SWEP:PrimaryAttack()
|
|
-- Can't fire without Ammo
|
|
if (!self:CanPrimaryAttack()) then return end
|
|
|
|
if (self:GetNWBool("BurstFire") == false) then
|
|
-- Single Mode: fire and take one bullet from the clip.
|
|
self:TakePrimaryAmmo(1)
|
|
self:SetNextPrimaryFire( CurTime() + self.Primary.RefireTime )
|
|
self.Weapon:EmitSound(self.Sound.SingleFire)
|
|
|
|
-- Apply recoil
|
|
if IsValid(self.Owner) then
|
|
self.Owner:ViewPunch( Angle(-1, 0, 0) * self.Recoil.SingleFire * (1 + (1 - self.PrimaryAccuracy)) )
|
|
self:ShootBullet(self.Primary.Damage, 1, 1.0 - self.PrimaryAccuracy)
|
|
end
|
|
|
|
-- Decrease accuracy
|
|
self.PrimaryAccuracy = math.Clamp(self.PrimaryAccuracy - self.Accuracy.Primary.Reduction, self.Accuracy.Primary.Min, self.Accuracy.Primary.Max)
|
|
else
|
|
-- Burst Mode: fire and take up to three bullets from the clip
|
|
local bulletCount = math.Clamp(self:Clip1(), 1, 3)
|
|
self:TakePrimaryAmmo(bulletCount)
|
|
self:SetNextPrimaryFire( CurTime() + self.Primary.RefireTime * bulletCount )
|
|
self.Weapon:EmitSound(self.Sound.BurstFire)
|
|
|
|
for i = 1, bulletCount do
|
|
if (IsValid(self)) && (IsValid(self.Owner)) then
|
|
-- Apply recoil & shoot
|
|
self.Owner:ViewPunch(Angle(-1, 0, 0) * self.Recoil.BurstFire * (1 + (1 - self.PrimaryAccuracy)))
|
|
self:ShootBullet(self.Primary.Damage, 1, 1.0 - self.PrimaryAccuracy)
|
|
|
|
-- Decrease accuracy
|
|
self.PrimaryAccuracy = math.Clamp(self.PrimaryAccuracy - self.Accuracy.Primary.Reduction, self.Accuracy.Primary.Min, self.Accuracy.Primary.Max)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Set Animation and attack time.
|
|
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
|
|
self.LastPrimaryAttack = CurTime()
|
|
return
|
|
end
|
|
|
|
-- Secondary Attack
|
|
function SWEP:CanSecondaryAttack()
|
|
if (self:Clip2() == 0) then
|
|
if (self:Ammo2() == 0) then
|
|
self.Weapon:EmitSound(self.Sound.NoSecondaryAmmo)
|
|
self:SetNextSecondaryFire( CurTime() + 1.0 )
|
|
return false
|
|
else
|
|
self:SetClip2( 1 )
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function SWEP:SecondaryAttack()
|
|
-- Can't fire without Ammo
|
|
if (!self:CanSecondaryAttack()) then return end
|
|
|
|
self.Owner:SetAmmo( self.Owner:GetAmmoCount( self:GetSecondaryAmmoType() ) - 1, self:GetSecondaryAmmoType() )
|
|
|
|
-- Emit a sound.
|
|
self.Weapon:EmitSound(self.Sound.SecondaryFire)
|
|
self:SetNextSecondaryFire( CurTime() + self.Secondary.RefireTime )
|
|
self:TakeSecondaryAmmo(1)
|
|
|
|
-- Create grenade
|
|
if SERVER then
|
|
local grenade = ents.Create("grenade_ar2")
|
|
if (!IsValid(grenade)) then return end
|
|
grenade:SetPos( self.Owner:GetShootPos() + self.Owner:GetAimVector() * 30 )
|
|
grenade:SetVelocity( self.Owner:GetAimVector() * 1000 )
|
|
grenade:SetAngles( self.Owner:GetAngles() )
|
|
grenade:SetOwner( self.Owner )
|
|
grenade:Spawn()
|
|
grenade:SetPhysicsAttacker( self.Owner, 60 )
|
|
end
|
|
|
|
-- Set Animation and attack time.
|
|
self:SendWeaponAnim(ACT_VM_SECONDARYATTACK)
|
|
self.LastSecondaryAttack = CurTime()
|
|
return
|
|
end
|
|
|
|
-- Reload: Combination of reloading and switching fire type.
|
|
function SWEP:Reload()
|
|
-- Fix reload for secondary
|
|
if (self:Clip2() == 0) then
|
|
if (self:Ammo2() > 0) then
|
|
self:SetClip2( 1 )
|
|
end
|
|
end
|
|
|
|
if self:DefaultReload(ACT_VM_RELOAD) then
|
|
self.Weapon:EmitSound(self.Sound.Reload)
|
|
else
|
|
if (self.LastReload) && ((CurTime() - self.LastReload) > 1) then
|
|
self.BurstFire = !self:GetNWBool("BurstFire")
|
|
self.LastReload = CurTime()
|
|
|
|
if (self.BurstFire) then
|
|
self.Weapon:EmitSound(self.Sound.SwitchBurst)
|
|
if SERVER then self:GetOwner():ChatPrint("Weapon: BurstFire is now on.") end
|
|
else
|
|
self.Weapon:EmitSound(self.Sound.SwitchSingle)
|
|
if SERVER then self:GetOwner():ChatPrint("Weapon: BurstFire is now off.") end
|
|
end
|
|
if SERVER then self:SetNWBool("BurstFire", self.BurstFire) end
|
|
end
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
function SWEP:ShootEffects()
|
|
|
|
end
|
|
|
|
-- Think: Restore accuracy over time.
|
|
function SWEP:Think()
|
|
local ThinkTime = CurTime()
|
|
|
|
if (ThinkTime >= (self.LastPrimaryAttack + self.Accuracy.Primary.Delay)) then
|
|
self.PrimaryAccuracy = math.Clamp(self.PrimaryAccuracy + self.Accuracy.Primary.Recovery, self.Accuracy.Primary.Min, self.Accuracy.Primary.Max)
|
|
end
|
|
if (ThinkTime >= (self.LastSecondaryAttack + self.Accuracy.Secondary.Delay)) then
|
|
self.SecondaryAccuracy = math.Clamp(self.SecondaryAccuracy + self.Accuracy.Secondary.Recovery, self.Accuracy.Secondary.Min, self.Accuracy.Secondary.Max)
|
|
end
|
|
end
|