Trace -- Recoil and ammo bug

so I’m having a bug with this code.


if (CLIENT) then
	SWEP.Author = "CSE - Night Eagle"
	SWEP.Contact = ""
	SWEP.Purpose = ""
	SWEP.Instructions = ""
	SWEP.PrintName = "M4"
	SWEP.Instructions = "Hold use and right-click to change firemodes or left-click to attach silencer."
	SWEP.Slot = 2
	SWEP.SlotPos = 0
	SWEP.IconLetter = "w"

	killicon.AddFont("cse_m4","CSKillIcons",SWEP.IconLetter,Color(255,80,0,255))
end

if (SERVER) then
	AddCSLuaFile("shared.lua")
end

SWEP.Base = "weapon_cs_base2"

SWEP.Spawnable = true
SWEP.AdminSpawnable = true

SWEP.ViewModel = "models/weapons/v_rif_m4a1.mdl"
SWEP.WorldModel = "models/weapons/w_rif_m4a1.mdl"
SWEP.HoldType = "ar2"

SWEP.Weight = 5
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false

SWEP.Primary.Sound = Sound("Weapon_M4A1.Single")
SWEP.Primary.Recoil = 1.25
SWEP.Primary.Unrecoil = 8
SWEP.Primary.Damage = 15
SWEP.Primary.NumShots = 1
SWEP.Primary.Cone	 = 0.03
SWEP.Primary.ClipSize = 31
SWEP.Primary.Delay = 0.06
SWEP.Primary.DefaultClip = 61
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "smg1"
SWEP.Primary.SpreadCone = 0.015

SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"

-- Start of Firemode configuration

SWEP.IronSightsPos = Vector(5.95, -4.0283, 1.1023)
SWEP.IronSightsAng = Vector(3.0803, 2.5, 3.674)

function SWEP:PrimaryAttack()

	 	local trace = { }
	 	trace.start = self.Owner:GetShootPos();
	 	trace.endpos = trace.start + self.Owner:GetAimVector() * 600;
	 	trace.filter = self.Owner;
	 	
	 	local tr = util.TraceLine( trace );
	 	 
		 	local trace = { }
		 	trace.start = tr.HitPos;
		 	trace.endpos = trace.start + self.Owner:GetAimVector() * 600;
		 	trace.filter = tr.Entity;
		 	
		 	local tr2 = util.TraceLine( trace );
	 	
	 		local mul2 = ( tr.HitPos - tr2.HitPos ):Length() * .01;
	 	 
		 	local bullet = {} 
		 	bullet.Num 		= self.Primary.NumShots;
		 	bullet.Src 		= tr.HitPos + self.Owner:GetAimVector() * 5;
		 	bullet.Dir 		= self.Owner:GetAimVector()	
		 	bullet.Spread 	= self.Primary.SpreadCone * self.Primary.Recoil;
		 	bullet.Tracer	= 1									
		 	bullet.Force	= .1									
		 	bullet.Damage	= self.Primary.Damage;
	 	 	bullet.TracerName = self.Primary.Tracer;
	 	 	
	 	 	self.Owner:FireBullets( bullet ) 
	 	 
	 	end

How do I get the recoil and ammo to work again?

Edit: This is the base code


if (SERVER) then
	AddCSLuaFile("shared.lua")
	SWEP.Weight = 5
	SWEP.AutoSwitchTo = false
	SWEP.AutoSwitchFrom = false
end

if (CLIENT) then
	SWEP.DrawAmmo			= true
	SWEP.DrawCrosshair		= false
	SWEP.ViewModelFOV		= 82
	SWEP.ViewModelFlip		= true
	SWEP.CSMuzzleFlashes	= true

	-- This is the font that's used to draw the death icons
	surface.CreateFont("csd", ScreenScale(30), 500, true, true, "CSKillIcons")
	surface.CreateFont("csd", ScreenScale(60), 500, true, true, "CSSelectIcons")
end

SWEP.Autho = "Rickster"
SWEP.Contact = ""
SWEP.Purpose = ""
SWEP.Instructions = ""

SWEP.Spawnable = false
SWEP.AdminSpawnable = false

SWEP.Primary.Sound = Sound("Weapon_AK47.Single")
SWEP.Primary.Recoil = 1.5
SWEP.Primary.Damage = 40
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.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"

/*---------------------------------------------------------
---------------------------------------------------------*/
function SWEP:Initialize()
	if (SERVER) then
		self:SetWeaponHoldType("normal")
		self:SetNPCMinBurst( 30 )
		self:SetNPCMaxBurst( 30 )
		self:SetNPCFireRate( 0.01 )
	end

	self.Ironsights = false
end

/*---------------------------------------------------------
Deploy
---------------------------------------------------------*/
function SWEP:Deploy()
	if SERVER then
		self:SetWeaponHoldType("normal")
	end
	return true
end

/*---------------------------------------------------------
Reload does nothing
---------------------------------------------------------*/
function SWEP:Reload()
	self.Weapon:DefaultReload(ACT_VM_RELOAD)
	self.Ironsights = false
end

/*---------------------------------------------------------
PrimaryAttack
---------------------------------------------------------*/
function SWEP:PrimaryAttack()
	self.Weapon:SetNextSecondaryFire(CurTime() + self.Primary.Delay)
	self.Weapon:SetNextPrimaryFire(CurTime() + self.Primary.Delay)

	if not self:CanPrimaryAttack() then return end
	if not self.Ironsights then return end
	-- Play shoot sound
	self.Weapon:EmitSound(self.Primary.Sound)

	-- Shoot the bullet
	self:CSShootBullet(self.Primary.Damage, self.Primary.Recoil + 3, self.Primary.NumShots, self.Primary.Cone + .05)

	-- Remove 1 bullet from our clip
	self:TakePrimaryAmmo(1)
	
	if ( self.Owner:IsNPC() ) then return end

	-- Punch the player's view
	self.Owner:ViewPunch(Angle(math.Rand(-0.2,-0.1) * self.Primary.Recoil, math.Rand(-0.1,0.1) *self.Primary.Recoil, 0))
end
/*---------------------------------------------------------
Name: SWEP:PrimaryAttack()
Desc: +attack1 has been pressed
---------------------------------------------------------*/
function SWEP:CSShootBullet(dmg, recoil, numbul, cone)
	if not ValidEntity(self.Owner) then return end
	numbul = numbul or 1
	cone = cone or 0.01

	local bullet = {}
	bullet.Num = numbul or 1
	bullet.Src = self.Owner:GetShootPos()       -- Source
	bullet.Dir = self.Owner:GetAimVector()      -- Dir of bullet
	bullet.Spread = Vector(cone, cone, 0)     -- Aim Cone
	bullet.Tracer = 4       -- Show a tracer on every x bullets
	bullet.Force = 5        -- Amount of force to give to phys objects
	bullet.Damage = dmg

	self.Owner:FireBullets(bullet)
	self.Weapon:SendWeaponAnim(ACT_VM_PRIMARYATTACK)      -- View model animation
	self.Owner:MuzzleFlash()        -- Crappy muzzle light
	self.Owner:SetAnimation(PLAYER_ATTACK1)       -- 3rd Person Animation
	
	if ( self.Owner:IsNPC() ) then return end

	// CUSTOM RECOIL !
	if ( (SinglePlayer() && SERVER) || ( !SinglePlayer() && CLIENT && IsFirstTimePredicted() ) ) then
		local eyeang = self.Owner:EyeAngles()
		eyeang.pitch = eyeang.pitch - recoil
		self.Owner:SetEyeAngles( eyeang )
	end
end

/*---------------------------------------------------------
Checks the objects before any action is taken
This is to make sure that the entities haven't been removed
---------------------------------------------------------*/
function SWEP:DrawWeaponSelection(x, y, wide, tall, alpha)
	draw.SimpleText(self.IconLetter, "CSSelectIcons", x + wide/2, y + tall*0.2, Color(255, 210, 0, 255), TEXT_ALIGN_CENTER)

	-- try to fool them into thinking they're playing a Tony Hawks game
	draw.SimpleText(self.IconLetter, "CSSelectIcons", x + wide/2 + math.Rand(-4, 4), y + tall*0.2+ math.Rand(-14, 14), Color(255, 210, 0, math.Rand(10, 120)), TEXT_ALIGN_CENTER)
	draw.SimpleText(self.IconLetter, "CSSelectIcons", x + wide/2 + math.Rand(-4, 4), y + tall*0.2+ math.Rand(-9, 9), Color(255, 210, 0, math.Rand(10, 120)), TEXT_ALIGN_CENTER)
end

local IRONSIGHT_TIME = 0.25

/*---------------------------------------------------------
Name: GetViewModelPosition
Desc: Allows you to re-position the view model
---------------------------------------------------------*/
function SWEP:GetViewModelPosition(pos, ang)
	if (not self.IronSightsPos) then return pos, ang end

	local bIron = self.Ironsights

	if (bIron != self.bLastIron) then
		self.bLastIron = bIron
		self.fIronTime = CurTime()

		if (bIron) then
			self.SwayScale 	= 0.3
			self.BobScale 	= 0.1
		else
			self.SwayScale 	= 1.0
			self.BobScale 	= 1.0
		end
	end

	local fIronTime = self.fIronTime or 0
	
	ang:RotateAroundAxis(ang:Right(), -15)
	if (not bIron and fIronTime < CurTime() - IRONSIGHT_TIME) then	
		return pos, ang
	end

	local Mul = 1.0

	if (fIronTime > CurTime() - IRONSIGHT_TIME) then
		Mul = math.Clamp((CurTime() - fIronTime) / IRONSIGHT_TIME, 0, 1)

		if not bIron then Mul = 1 - Mul end
	end

	local Offset	= self.IronSightsPos

	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
	
	ang:RotateAroundAxis(ang:Right(), Mul * 15)

	local Right 	= ang:Right()
	local Up 		= ang:Up()
	local Forward 	= ang:Forward()

	pos = pos + Offset.x * Right * Mul
	pos = pos + Offset.y * Forward * Mul
	pos = pos + Offset.z * Up * Mul

	return pos, ang
end


/*---------------------------------------------------------
SetIronsights
---------------------------------------------------------*/
function SWEP:SetIronsights(b)
	if b and SERVER then 
		self:SetWeaponHoldType(self.HoldType)
	elseif SERVER then
		self:SetWeaponHoldType("normal")
	end
	self.Ironsights = b
end

function SWEP:GetIronsights()
	return self.Ironsights
end

SWEP.NextSecondaryAttack = 0
/*---------------------------------------------------------
SecondaryAttack
---------------------------------------------------------*/
function SWEP:SecondaryAttack()
	if not self.IronSightsPos then return end

	if (self.NextSecondaryAttack > CurTime()) then return end

	bIronsights = not self.Ironsights
	self:SetIronsights(bIronsights)
	self.NextSecondaryAttack = CurTime() + 0.3
end

/*---------------------------------------------------------
onRestore
	Loaded a saved game (or changelevel)
---------------------------------------------------------*/
function SWEP:OnRestore()
	self.NextSecondaryAttack = 0
	self.Ironsights = false
end

You’re missing:
self:TakePrimaryAmmo(1)
and
self.Owner:ViewPunch()

from your primaryfire function, you’re not calling a firebullets function it’s embedded within your primaryfire, hence no recoil calculation

so



	 	local trace = { }
	 	trace.start = self.Owner:GetShootPos();
	 	trace.endpos = trace.start + self.Owner:GetAimVector() * 600;
	 	trace.filter = self.Owner;
	 	
	 	local tr = util.TraceLine( trace );
	 	 
		 	local trace = { }
		 	trace.start = tr.HitPos;
		 	trace.endpos = trace.start + self.Owner:GetAimVector() * 600;
		 	trace.filter = tr.Entity;
		 	
		 	local tr2 = util.TraceLine( trace );
	 	
	 		local mul2 = ( tr.HitPos - tr2.HitPos ):Length() * .01;
	 	 
		 	local bullet = {} 
		 	bullet.Num 		= self.Primary.NumShots;
		 	bullet.Src 		= tr.HitPos + self.Owner:GetAimVector() * 5;
		 	bullet.Dir 		= self.Owner:GetAimVector()			 
		 	bullet.Spread 	= self.Primary.SpreadCone * self.Primary.Recoil;
		 	bullet.Tracer	= 1									
		 	bullet.Force	= .1									
		 	bullet.Damage	= self.Primary.Damage;
	 	 	bullet.TracerName = self.Primary.Tracer;
	 	 	
	 	 	self.Owner:FireBullets( bullet ) 
	 	 
	 	end


should be


	 	local trace = { }
	 	trace.start = self.Owner:GetShootPos();
	 	trace.endpos = trace.start + self.Owner:GetAimVector() * 600;
	 	trace.filter = self.Owner;
	 	
	 	local tr = util.TraceLine( trace );
	 	 
		 	local trace = { }
		 	trace.start = tr.HitPos;
		 	trace.endpos = trace.start + self.Owner:GetAimVector() * 600;
		 	trace.filter = tr.Entity;
		 	
		 	local tr2 = util.TraceLine( trace );
	 	
	 		local mul2 = ( tr.HitPos - tr2.HitPos ):Length() * .01;
	 	 
		 	local bullet = {} 
		 	bullet.Num 		= self.Primary.NumShots;
		 	bullet.Src 		= tr.HitPos + self.Owner:GetAimVector() * 5;
		 	bullet.Dir 		= self.Owner:GetAimVector()			
		 	bullet.Spread 	= self.Primary.SpreadCone * self.Primary.Recoil;
		 	bullet.Tracer	= 1									
		 	bullet.Force	= .1									
		 	bullet.Damage	= self.Primary.Damage;
	 	 	bullet.TracerName = self.Primary.Tracer;
	 	 	
	 	 	self.Owner:FireBullets( bullet ) 
                        self:TakePrimaryAmmo(1)
self.Owner:ViewPunch( Angle( -1, 0, 0 ) )

	 	end

EDIT: New bug, when you hit 0 ammo. still fires. And their is no spread on the bullets.
H2Fix?