Hold to upgrade timer

I’m attempting to make a timer to upgrade printers. I want the user to have to hold the use button for 2 seconds before the printer will upgrade. (to prevent accidental upgrades.) Here is what I was trying:


function ENT:Initialize()
	self:SetModel(HOOPLA3.MoneyPrinter3.TheModel)
	self:PhysicsInit(SOLID_VPHYSICS)
	self:SetMoveType(MOVETYPE_VPHYSICS)
	self:SetSolid(SOLID_VPHYSICS)
	self:SetUseType(SIMPLE_USE)
	local phys = self:GetPhysicsObject()
	if phys:IsValid() then phys:Wake() end
	
	self:SetColor( HOOPLA3.MoneyPrinter3.OriginalColor )

	self.sparking = false
	self.damage = 100
	self.IsMoneyPrinter = true
	timer.Create( "print" .. tostring(self.Entity), HOOPLA3.MoneyPrinter3.PrintTime, 0,  function() PrintMore(self) end)
	
	self:SetNWInt("Level", 1)
	self:SetNWInt( "hold", 0 )
end


function settinghold()
	if self:GetNWInt( "hold" ) == 0 then
		self:SetNWInt( "hold", 1 )
	end
end


function ENT:Use( activator, caller )

		if self:GetNWInt("Level") < HOOPLA3.MoneyPrinter3.MaxLevel and self:GetNWInt("hold") == 0 then
		timer.Create( "hold" .. tostring(self.Entity), 3, 0, function() settinghold() end )
			if self:GetNWInt( "hold" ) == 1 then
			if activator:canAfford(price) then
				activator:addMoney(-price)
				self:SetNWInt("Level", self:GetNWInt("Level") + 1)
				DarkRP.notify( activator, 2, 4, "Your "..HOOPLA3.MoneyPrinter3.DisplayName.." is now level "..self:GetNWInt("Level").."." )
			end
			end
		end
	
	end




It just doesn’t upgrade when I hold the use button. I could have the logic of it all messed up. Any insight would be greatly appreciated!

Edit: It does upgrade without the timer in there.

Could use any ideas!

There are ways to use a timer to do what you’re doing; I use a similar method for vehicle ignition. For it to work, you need to be tracking a button via PlayerBindPress or similar hook in order to detect when the key is released ( when key is released, you kill the timer; in the timer another check should check to see if the key is still held at point of execution ) Without those two cancellation features it may not work correctly.

You could use the continuous use via SetUseType; but I can’t recall if you can check Player:KeyDown( KEY_USE ) and it be false for the last time it executes. If it does, then you can use the use function for the entire procedure…

Count the delta-time between executions, add them up to one sum variable, if the sum is >= time needed to execute, then do so. If it isn’t, continue processing. On key-release, set the sum to -1… On key press / first-use, if sum is -1 ( should be set as -1 by default too ) then activate by setting to 0. If the sum is < 0 then don’t allow adding ( prevents the delta-time being 30 seconds by ensuring one call is strictly associated with enabling / starting the sum var and setting the start-time for the delta-time so it is an accurate measurement )

So, if it does detect KeyDown as false on last use, then the code required to perform should be only a few lines long… Think recursively.

Try it, SetUseType to continuous, and print out the KeyDown; show us the results and try the logic above if it works as specified.

If it doesn’t work, the timer method wouldn’t work either ( because the key can be released without stopping the timer, so they can keep tapping and then hold without the timer resetting properly )… It could be done crudely, check key-down in the timer, but each time the use-key is pressed on use-type simple timer.Create ( using a named timer so it can be overwritten each time use is pressed to reset the timer ) and in the timer check for key-down to execute, if no key down then just end…

Okay, thank you for the explanation. I will try this in the morning and let you know the results.