Problem with timers.

I’ve been trying to add a timer to my SWEP so that people can’t fire quickly by clicking rapidly.

Here’s my code:


if (SERVER) then --the init.lua stuff goes in here
 
 
   AddCSLuaFile ("shared.lua");
 
 
   SWEP.Weight = 5;
   SWEP.AutoSwitchTo = false;
   SWEP.AutoSwitchFrom = false;
 
end
 
if (CLIENT) then --the cl_init.lua stuff goes in here
 
 
   SWEP.PrintName = "Barrel launcher";
   SWEP.Slot = 3;
   SWEP.SlotPos = 1;
   SWEP.DrawAmmo = false;
   SWEP.DrawCrosshair = false;
 
end
 
 
SWEP.Author = "Idolon";
SWEP.Contact = "";
SWEP.Purpose = "Playing DodgeBarrel or just having fun with barrels.";
SWEP.Instructions = "Click to launch an explosive barrel.";
SWEP.Category = "Prop Launchers"
 
SWEP.Spawnable = true;
SWEP.AdminSpawnable = true;
 
SWEP.ViewModel = "models/weapons/v_pistol.mdl";
SWEP.WorldModel = "models/weapons/w_rocket_launcher.mdl";
 
SWEP.Primary.ClipSize = 50;
SWEP.Primary.DefaultClip = 0;
SWEP.Primary.Automatic = false;
SWEP.Primary.Ammo = "none";

local ShootSound = Sound ("weapons/grenade_launcher1.wav");

local canShoot = true;

function SWEP:shoot_enable()
	canShoot = true;
end

function SWEP:Think()
end
 
/* Spawn and throw the specified model */
function SWEP:throw_attack (model_file)
	if ( !self:CanPrimaryAttack() ) then return end
	if ( !canShoot ) then return end
	
	//Get an eye trace. This basically finds out where the shot hit
	//This SWEP makes very little use of the trace, except to calculate
	//the amount of force to apply to the object to throw it.
	local tr = self.Owner:GetEyeTrace();
 
	//We now make some shooting noises and effects using the sound we
	//loaded up earlier
	self.Weapon:EmitSound (ShootSound);
	self.BaseClass.ShootEffects (self);
 
	//We now exit if this function is not running on the server
	if (!SERVER) then return end;
 
	//The next task is to create a physics entity based on the supplied model.
	local ent = ents.Create ("prop_physics");
	ent:SetModel (model_file);
 
	//Set the initial position of the object. This might need some fine tuning; but it
	//seems to work for the models I have tried
	ent:SetPos (self.Owner:EyePos() + (self.Owner:GetAimVector() * 16));
	ent:SetAngles (self.Owner:EyeAngles());
	ent:Spawn();
 
	//Now we need to get the physics object for our entity so we can apply a force to it
	local phys = ent:GetPhysicsObject();
 
	//Time to apply the force.
	//Also, ignite it. :D
	local shot_length = tr.HitPos:Length();
	phys:ApplyForceCenter (self.Owner:GetAimVector():GetNormalized() *  math.pow(shot_length, 3));
	ent:Ignite(100,0)
	self:TakePrimaryAmmo(1) //Remove ammo
 
	//Now for the all important part of adding the spawned objects to the undo and cleanup data.
	cleanup.Add (self.Owner, "props", ent);
 
	undo.Create ("Launched Barrel");
	undo.AddEntity (ent);
	undo.SetPlayer (self.Owner);
	undo.Finish();
	
	//Don't forget to reset the shoot timer!
	canShoot = false;
	timer:Simple( 5, SWEP:shoot_enable )
end
 
/* throw barrels */
function SWEP:PrimaryAttack()
	//Call the throw attack function
	self:throw_attack ("models/props_c17/oildrum001_explosive.mdl");
end

function SWEP:SecondaryAttack()
end

function SWEP:Reload()
end

I looked in the console on Gmod, and found these things pertaining to the SWEP:

Timer Error: autorun/client/cl_joystick_numpad.lua:5: attempt to index global ‘jcon’ (a nil value)

weapons/barrel_shooter/shared.lua:101: function arguments expected near ‘)’

Any ideas as to what’s going on?

In your timer, the format would be like this:


timer.Simple(5,self.shoot_enable)

If that didn’t work, you could do this to make sure it’s fine:


timer.Simple(5,function() self:shoot_enable() end)

But make sure to define the shoot_enable function.

In that case you would also need to pass self as an argument to the function.

If I were you I would ditch the timers and use CurTime().

To check if the player can use his weapon’s primary fire check if self.NextPrimary is smaller then CurTime(). When the primary fire is used set self.NextPrimary to CurTime() + self.PrimaryDelay (which you will have to define).

CurTime() returns the current time, doing this will make it so that everytime a shot is fired you have to wait for a set delay before shooting again,

Well, I fixed it, but just caused another problem. I’ve gotten the weapon in the spawn menu and useable, but I can’t get it to shoot. Here’s my code:


if (SERVER) then --the init.lua stuff goes in here
 
 
   AddCSLuaFile ("shared.lua");
 
 
   SWEP.Weight = 5;
   SWEP.AutoSwitchTo = false;
   SWEP.AutoSwitchFrom = false;
 
end
 
if (CLIENT) then --the cl_init.lua stuff goes in here
 
 
   SWEP.PrintName = "Barrel launcher";
   SWEP.Slot = 4;
   SWEP.SlotPos = 1;
   SWEP.DrawAmmo = false;
   SWEP.DrawCrosshair = false;
 
end
 
 
SWEP.Author = "Idolon";
SWEP.Contact = "";
SWEP.Purpose = "Playing DodgeBarrel or just having fun with barrels.";
SWEP.Instructions = "Click to launch an explosive barrel.";
SWEP.Category = "Prop Launchers"
 
SWEP.Spawnable = true;
SWEP.AdminSpawnable = true;
 
SWEP.ViewModel = "models/weapons/v_pistol.mdl";
SWEP.WorldModel = "models/weapons/w_rocket_launcher.mdl";
 
SWEP.Primary.ClipSize = 50;
SWEP.Primary.DefaultClip = 0;
SWEP.Primary.Automatic = false;
SWEP.Primary.Ammo = "none";

local ShootSound = Sound ("weapons/grenade_launcher1.wav");

function SWEP:Think()
end
 
local NextPrimary = 2;
 
/* Spawn and throw the specified model */
function SWEP:throw_attack (model_file)
	if ( !self:CanPrimaryAttack() ) then return end
	
	//Get an eye trace. This basically finds out where the shot hit
	//This SWEP makes very little use of the trace, except to calculate
	//the amount of force to apply to the object to throw it.
	local tr = self.Owner:GetEyeTrace();
 
	//We now make some shooting noises and effects using the sound we
	//loaded up earlier
	self.Weapon:EmitSound (ShootSound);
	self.BaseClass.ShootEffects (self);
 
	//We now exit if this function is not running on the server
	if (!SERVER) then return end;
 
	//The next task is to create a physics entity based on the supplied model.
	local ent = ents.Create ("prop_physics");
	ent:SetModel (model_file);
 
	//Set the initial position of the object. This might need some fine tuning; but it
	//seems to work for the models I have tried
	ent:SetPos (self.Owner:EyePos() + (self.Owner:GetAimVector() * 16));
	ent:SetAngles (self.Owner:EyeAngles());
	ent:Spawn();
 
	//Now we need to get the physics object for our entity so we can apply a force to it
	local phys = ent:GetPhysicsObject();
 
	//Time to apply the force.
	//Also, ignite it. :D
	local shot_length = tr.HitPos:Length();
	phys:ApplyForceCenter (self.Owner:GetAimVector():GetNormalized() *  math.pow(shot_length, 3));
	ent:Ignite(100,0)
	self:TakePrimaryAmmo(1) //Remove ammo
 
	//Now for the all important part of adding the spawned objects to the undo and cleanup data.
	cleanup.Add (self.Owner, "props", ent);
 
	undo.Create ("Launched Barrel");
	undo.AddEntity (ent);
	undo.SetPlayer (self.Owner);
	undo.Finish();
	
	//TESTING
	Msg("Shoot dangit")
end
 
/* throw barrels */
function SWEP:PrimaryAttack()
	//Call the throw attack function
	if ( NextPrimary >= CurTime() ) then return end
	NextPrimary = CurTime() + 2
	self:throw_attack ("models/props_c17/oildrum001_explosive.mdl");
end

function SWEP:SecondaryAttack()
end

function SWEP:Reload()
end

Any ideas?

Umm, do you ever define model_file?

Yep, it’s the argument for the function, which in this case is models/props_c17/oildrum001_explosive.mdl.

He does, but does “Shoot dangit” get printed? If no you have an error somewhere and it should show up in your console.

Also I’m seeing a problem here, all of your values like NextPrimary and shootsound should be part of the object itself. So SWEP.NextPrimary which becomes self.NextPrimary in functions.

[editline]09:32PM[/editline]

Or you could just ditch all of that and use the newly implemented SetNextPrimaryFire function.

[Weapon.SetNextPrimaryFire

http://wiki.garrysmod.com/favicon.ico](http://wiki.garrysmod.com/?search=Weapon.SetNextPrimaryFire)

I haven’t got around using it yet but I assume it works perfectly well.

Well, I solved it! I must’ve screwed something else in the code, because starting over from scratch solved it, and it works fine! Thanks, guys.

SOLVED