Hello! Recently I’ve struggled for a few days to find a way over walkspeed overlapping in stuns, slows.
(scenario-below)
[Say you click M1 to swing in game, you get briefly slowed as you swing for about 0.65 seconds, then say you get slowed for a longer duration between the first 0.65 seconds, you’d be un-slowed by the first brief slow and the new one would be ignored, which is what I wanted to overcome without using TICK() or OS.CLOCK() in while loops.)
Now I would like to hear feedback on any bad practices here or generally what could be improved, if there’s an embarassing mistake that’s my bad I’m dead tired from this, here’s the code.
local AddedSpeeds = {}
local repStorage = game:GetService("ReplicatedStorage")
local character = script.Parent
local player = game.Players:GetPlayerFromCharacter(character)
local function getlength(Dictionary)
local currentIteration = 0
local iterationIncrement = 1
for _,Table in pairs(Dictionary) do
currentIteration += iterationIncrement
end
return currentIteration
end
local speedHandlerEvent = Instance.new("BindableEvent")
speedHandlerEvent.Parent = character
speedHandlerEvent.Event:Connect(function(a,b)
if a == "AddWS" then
local name,ws,dura,priority = b.Name or "AddedWalkSpeed",b.WSVal or 16,b.Dura or 0, b.Priorty or 0
local returnState = repStorage.Remotes.Functions.mainFunc:InvokeClient(player,"ReturnState")--get a state which is just a table containing the speed number
if not AddedSpeeds[name] then --create a table for the new string if it doesnt exist
print(name.." has been added to WalkSpeedQueue")
AddedSpeeds[name] = {
Name = name, --the string
Speed = ws, --the speed amount
Duration = dura, --duration
Priority = priority, --speed priority [higher-prefered]
}
else
return
end
--set speed to new speed only if the new speed is lower than the current OR if new priority is higher than current
local LastSpeedFirst = ws
for i,Table in pairs(AddedSpeeds) do
local foundName, foundSpeed, foundDuration, foundPriority = Table.Name, Table.Speed, Table.Duration, Table.Priority;
if foundSpeed <=ws then
LastSpeedFirst = foundSpeed
end
if foundPriority < priority then
LastSpeedFirst = foundSpeed
end
end
returnState.Speed = LastSpeedFirst
repStorage.Remotes.Events.Main:FireClient(player,"SetSpeed",returnState)--update to new speed
if dura and dura ~= math.huge then --if duration is math.huge that means its a speed modifications that lasts until manually removed using ``bindableEvent:Fire("RemoveWS",{Name = ..string..})``
task.delay(dura,function()
--remove added speed from queue
if AddedSpeeds and AddedSpeeds[name] then
print("Removed speed table "..name..".")
AddedSpeeds[name] = nil
end
local Length = getlength(AddedSpeeds)
if Length<=0 then --remove any speed modifications if the table is empty
local returnState = repStorage.Remotes.Functions.mainFunc:InvokeClient(player,"ReturnState")
returnState.Speed = 16 --set speed to roblox default
repStorage.Remotes.Events.Main:FireClient(player,"SetSpeed",returnState) --update to new speed
else
--if the table isnt empty after the added speed is removed it means there's more speeds in queue so we check for the one with lowest speed and duration then use it
local returnState2 = repStorage.Remotes.Functions.mainFunc:InvokeClient(player,"ReturnState")--update to new speed
local LastSpeed,LastDuration,LastPriority,LastName = 16,50,0,"";
for i,Table in pairs(AddedSpeeds) do
local foundName, foundSpeed, foundDuration, foundPriority = Table.Name, Table.Speed, Table.Duration, Table.Priority;
if foundName then
LastName = foundName
end
if foundSpeed<LastSpeed and foundDuration>LastDuration then
LastSpeed,LastDuration = foundSpeed,foundDuration;
end
if foundPriority > LastPriority then
LastSpeed,LastDuration = foundSpeed,foundDuration;
end
end
returnState2.Speed = LastSpeed
repStorage.Remotes.Events.Main:FireClient(player,"SetSpeed",returnState2)--update to new speed
end
end)
end
elseif a == "RemoveWS" then
local name = b.Name
--remove a speed (based on the sent string) from queue table
if AddedSpeeds and AddedSpeeds[name] then
print("Removed speed table "..name..".")
AddedSpeeds[name] = nil
end
local returnState2 = repStorage.Remotes.Functions.mainFunc:InvokeClient(player,"ReturnState")
returnState2.Speed = 16
--check for more speed modifications incase there is some left.
local LastSpeed,LastDuration,LastPriority = 16,50,0;
for i,Table in pairs(AddedSpeeds) do
local foundSpeed, foundDuration, foundPriority = Table.Speed, Table.Duration, Table.Priority;
if foundSpeed<LastSpeed and foundDuration>LastDuration then
LastSpeed,LastDuration = foundSpeed,foundDuration;
end
if foundPriority > LastPriority then
LastSpeed,LastDuration = foundSpeed,foundDuration;
end
end
returnState2.Speed = LastSpeed
repStorage.Remotes.Events.Main:FireClient(player,"SetSpeed",returnState2)--update to new speed
end
end)
Let me know where to improve!