timer.Simple not working

I’m trying to create a TTT traitor weapon that makes you Innocent for a certain amount of time defined by:
[lua]
CreateConVar( “innocent_time”, “15”, { FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE } )
[/lua]

Everything works ( with better results than expected, you still show as Traitor on your HUD and the scoreboard :smiley: ), but the timer doesn’t set you back to Traitor after the time decided by the ConVar. This is my timer code:
[lua]
timer.Simple( tostring(GetConVarNumber(“innocent_time”)), function() ply:SetRole( ROLE_TRAITOR ); ply:StripWeapon( “weapon_ttt_inno” ) end )
[/lua]
StripWeapon doesn’t work either, not sure if it’s because I set the weapon droppable to false.
NOTE: I tried both using and not using using tostring, neither worked.
Any clues?

My whole code:
[lua]
if SERVER then
AddCSLuaFile( “shared.lua” )
end

if CLIENT then
SWEP.PrintName = “Innocent Timer”
SWEP.Slot = 7 – add 1 to get the slot number key
SWEP.DrawCrosshair = false
SWEP.ViewModelFOV = 54
SWEP.ViewModelFlip = false
end

– Always derive from weapon_tttbase.
SWEP.Base = “weapon_tttbase”

— Standard GMod values

SWEP.HoldType = “physgun”

SWEP.Primary.Delay = 1
SWEP.Primary.Recoil = 1
SWEP.Primary.Automatic = false
SWEP.Primary.Damage = 0
SWEP.Primary.Cone = 0.009
SWEP.Primary.Ammo = “none”
SWEP.Primary.ClipSize = 0
SWEP.Primary.ClipMax = 0
SWEP.Primary.DefaultClip = 0
SWEP.Primary.Sound = Sound( “weapons/airboat/airboat_gun_energy1.wav” )

SWEP.UseHands = true
SWEP.ViewModel = “models/weapons/v_watch.mdl”
SWEP.WorldModel = “models/weapons/w_watch.mdl”
SWEP.Kind = WEAPON_EQUIP2
SWEP.AmmoEnt = “none”
SWEP.CanBuy = { ROLE_TRAITOR }
SWEP.InLoadoutFor = nil
SWEP.LimitedStock = true
SWEP.AllowDrop = false
SWEP.NoSights = true

if CLIENT then

SWEP.Icon = “VGUI/ttt/icon_time”

SWEP.EquipMenuData = {
type = “Make yourself innocent”,
desc = “Makes you innocent for " … tostring(GetConVarNumber(“innocent_time”)) … " seconds.”
};
end

CreateConVar( “innocent_time”, “15”, { FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE } )

function SWEP:PrimaryAttack()
local ply = self:GetOwner()
if ply:GetRole() == ROLE_TRAITOR then
ply:SetRole( ROLE_INNOCENT )
timer.Simple( tostring(GetConVarNumber(“innocent_time”)), function() ply:SetRole( ROLE_TRAITOR ); ply:StripWeapon( “weapon_ttt_inno” ) end )
end
end
[/lua]

No need tostring the convar number; the timer won’t work with strings. If below doesn’t work then try removing the quotations from the CreateConVar( “innocent_time”, "15"

Replace your current timer with this:

[lua]
timer.Simple( GetConVarNumber(“innocent_time”), function()
self:Remove()
end)
[/lua]

and add this function below SWEP:PrimaryAttack()

[lua]
function SWEP:OnRemove()
self.Owner:SetRole(ROLE_TRAITOR)
end
[/lua]

Thank you, I’ll test it in a second. Do I need to remove SWEP.AllowDrop in order to be able to strip it?

No.

So, I just use [lua]self.Owner:StripWEapon(“weapon_ttt_inno”)[/lua], right?
Everything else works great, thanks!

timer.Simple? tostring in the first argument?
You scrip came down? : DD

What??

It’s necessary in the first argument ( T shop desc ) and I didn’t want to use timer.Create because it wasn’t necessary

timer.Simple(second number , function callback) -_-

timer.Simple takes a number as its first argument. I’m not sure where you saw that it takes a string, but that’s certainly not how it works.

Also encase your PrimaryAttack code inside an “if SERVER then … end” check. Changing roles and stripping weapons are things that are done serverside only. Clientside is for visual stuff and weapon prediction, and you don’t need that in your case.

[lua]function SWEP:PrimaryAttack()
if SERVER then
local ply = self:GetOwner()
if ply:GetRole() == ROLE_TRAITOR then
ply:SetRole( ROLE_INNOCENT )
timer.Simple(GetConVarNumber(“innocent_time”), function() ply:SetRole( ROLE_TRAITOR ); ply:StripWeapon( “weapon_ttt_inno” ) end)
end
end
end[/lua]

I think it would be better if you immediately strip the weapon after using it too. Otherwise people would be able to “fire” it multiple times. It wouldn’t change much, but timer.Simple would be called more than once and would then set your role to ROLE_INNOCENT several times. Which is a bit ugly.
Also be careful with timer.Simple. If the player uses this weapon and disconnects from the server before the delay is over, the game is going to attempt to set the role of a player who no longer exists, which is going to cause errors.
Even worse, if a player uses this weapon at the end of a match, and then respawns as an innocent on the next match before the delay is over, he will turn into a traitor for the whole match. Make sure you take this case into account.