Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Sprint drains/regens too fast when shift is spammed?

I made a server-sided sprint that goes like this:

[1] - Gets input from the client when the player presses shift and passes it to the server.

[2] - The server places players into a table when input is begun and takes them out when the input is ended.

[3] - Runs a loop that repeats until they are put into/taken out of the table which subtracts/adds a set amount of stamina.

The problem is that when someone presses shift really fast, it regens/drains really fast as well. This would lead to players being able to just shift spam in order to get back to the max stamina after they run out.

(Ex. https://gyazo.com/3dc28ed6e0f9c5193d6477de1a9370af.gif)

Any ideas on what the problem could be?

Server

local PlayerService, RepStorage, RunService = game:GetService('Players'), game:GetService('ReplicatedStorage'), game:GetService('RunService')	;
local Module = require(RepStorage:WaitForChild('Modules'):FindFirstChild('MechanicsModule'))	;
local Events = RepStorage.RemoteEvents	;	local Sprint, UpdateStamina = Events.Sprint, Events.StaminaUpdate	;
local MaxStamina = Module.MaxStamina	;	local SprintCost, SprintModifier, SprintRegen = Module.SprintCost, Module.SprintModifier, Module.SprintRegen	;
local NormalSpeed = Module.NormalSpeed	;	local SprintSpeed = Module.SprintSpeed	;	local WaitTime = .01	;

local SprintingPlayers = {}	;

function isPlayerInTable(Player)
	for Index, Value in pairs(SprintingPlayers) do
		if Player.Name == Value then
			return true
		end
	end
end

function Sprinting(Stamina, Player, Humanoid)
	for i, SprintingPlayer in pairs(SprintingPlayers) do
		if isPlayerInTable(Player) ~= true then print'no sprint' return end
		repeat
			if Module.IsMoving(Humanoid) and isPlayerInTable(Player) then
				if Stamina.Value >= SprintCost then
					Stamina.Value = Stamina.Value - SprintCost	;	Humanoid.WalkSpeed = SprintSpeed	;	wait(WaitTime)	;
				else
					Humanoid.WalkSpeed = NormalSpeed	;	wait(WaitTime)	;
				end
			elseif not Module.IsMoving(Humanoid) and isPlayerInTable(Player) then
				if Stamina.Value < MaxStamina then
					Stamina.Value = Stamina.Value + SprintRegen	;	Humanoid.WalkSpeed = NormalSpeed	;	wait(WaitTime)	;
				end
			end
			wait()	;
		until not isPlayerInTable(Player) or Humanoid:GetState() == Enum.HumanoidStateType.Dead	
	end
end

function NotSprinting(Stamina, Player, Humanoid)
	if #SprintingPlayers > 0 then
		for i, SprintingPlayer in pairs(SprintingPlayers) do
			if not isPlayerInTable(Player) then
				repeat
					if Stamina.Value < MaxStamina then
						Stamina.Value = Stamina.Value + SprintRegen	;	Humanoid.WalkSpeed = NormalSpeed	;	wait(WaitTime)	;
					elseif Stamina.Value > MaxStamina then
						Stamina.Value = MaxStamina
					end
					wait()	;
				until isPlayerInTable(Player) or Humanoid:GetState() == Enum.HumanoidStateType.Dead		
			end
		end
	elseif #SprintingPlayers <= 0 and not isPlayerInTable(Player) then
		repeat
			if Stamina.Value < MaxStamina then
				Stamina.Value = Stamina.Value + SprintRegen	;	Humanoid.WalkSpeed = NormalSpeed	;	wait(WaitTime)	;
			elseif Stamina.Value > MaxStamina then
				Stamina.Value = MaxStamina
			end
			wait()	;
		until isPlayerInTable(Player) or Humanoid:GetState() == Enum.HumanoidStateType.Dead
	end
end

function AddToTable(Stamina, Player, Humanoid)
	if not isPlayerInTable(Player) then	
		table.insert(SprintingPlayers, Player.Name)	
		Sprinting(Stamina, Player, Humanoid)	
	end
end

function RemoveFromTable(Stamina, Player, Humanoid)
	if #SprintingPlayers > 0 then
		for Index, Value in pairs(SprintingPlayers) do
			if Value == Player.Name then
				table.remove(SprintingPlayers, Index)	;
				NotSprinting(Stamina, Player, Humanoid)	;	
			end
		end
	else
		NotSprinting(Stamina, Player, Humanoid)	;	
	end
end

PlayerService.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local Root = Character:WaitForChild('HumanoidRootPart') or Character:FindFirstChild('HumanoidRootPart')	;
		local Stamina = Instance.new('IntValue', Root)	;
		Stamina.Name = 'Stamina'	;	Stamina.Value = MaxStamina	;
		
		Stamina.Changed:Connect(function(Property)
			UpdateStamina:FireClient(Player, Stamina.Value, MaxStamina)
		end)
		
	end)
end)

Sprint.OnServerEvent:Connect(function(Player, State, Tick)
	local Character = Player.Character	;
	local Root = Character:WaitForChild('HumanoidRootPart') or Character:FindFirstChild('HumanoidRootPart')	;
	local Stamina = Root:FindFirstChild('Stamina') or Root:WaitForChild('Stamina')	;	local Humanoid = Character:FindFirstChild('Humanoid')	;
	if State then	
		if not isPlayerInTable(Player) then
			AddToTable(Stamina, Player, Humanoid)	;	
		--	print(Player.Name, 'IS SPRINTING', State)	;	
		end
	elseif not State then
		if isPlayerInTable(Player) then
			RemoveFromTable(Stamina, Player, Humanoid)
		--	print(Player.Name, 'STOPPED SPRINTING', State)	;	
		end
	end
end)

Client

InputService.InputBegan:Connect(function(Input, gameProcessed)	
	if not gameProcessed then
		if Input.KeyCode == Enum.KeyCode.LeftShift then
		--	print(Player.Name, 'began sprinting')
			Sprint:FireServer(true)		;	
		end
	end	
end)

InputService.InputEnded:Connect(function(Input, gameProcessed)	
	if not gameProcessed then
		if Input.KeyCode == Enum.KeyCode.LeftShift then
		--	print(Player.Name, 'stopped sprinting')
			Sprint:FireServer(false)	;
		end
	end
end)

7 comments

0

I have a function for this but for some reason it doesn't print if the player is already in the table

0

can i see the code? that would make it easier to solve >wO

0

Sorry, I'll add an edit

0

Also, if there's a better way to do what I'm trying to achieve please do suggest

0

what's the full server script, with isPlayerScripting function and Connect to the Sprint remote event

0

Another edit coming up

0

nice looking script but why dont u use table.find() in function isPlayerInTable

1 answer

Since then I've fixed the issue, thanks for all suggestions, and whaaaa- table.find() is a thing?

This discussion is preserved as it was. New answers, comments, and votes are closed.