I’m facing challenges within a codebase while trying to integrate a cooldown period while also executing the rest of the code simultaneously.
Here’s the intended objective:
When a command is entered, such as ‘/tryout 1md 6’, a UI should appear and repeat itself three times. However, I want to prevent a new UI activation for 30 seconds after the initial command, even if the user attempts to re-enter ‘/tryout 1md 6’.
Moreover, if the player does re-enter ‘/tryout 1md 6’, I want the remaining time to be displayed in the console (this feature is already functional). However, I’m currently struggling to implement the cooldown while ensuring the rest of the code continues to execute.
If I omit the cooldown, the code works perfectly. At the moment, I’m unsure of the best way to implement that cooldown.
-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Visual configurations for notifications
local notificationStyle = {
BackgroundTransparency = 0.3,
BackgroundColor = Color3.fromRGB(0, 0, 0),
ContentTransparency = 0,
ContentColor = Color3.fromRGB(255, 255, 255)
}
-- Module and Remotes
local GameSettings = require(script.Parent)
local NotificationModule = require(ReplicatedStorage.BannerNotification_Storage.BannerNotificationModule)
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local Announcement = Remotes.Announcement
local cooldownActive = false
local cooldownDuration = 30 -- Cooldown time in seconds
local lastCommandTime = tick()
local function startCooldown()
cooldownActive = true
lastCommandTime = tick()
task.wait(cooldownDuration)
cooldownActive = false
end
local function PlayerRank(player)
local Rank = player:GetRoleInGroup(GameSettings.new().mainGroupID)
return Rank and (Rank:match("%b[]") or not Rank:find("%[.-%]") and "[" .. Rank .. "]") or (warn("Player rank is nil for player", player.Name) and nil)
end
local function getDivisionDetails(player, divisionKey, padValue)
local settings = GameSettings.new()
for groupId, groupData in pairs(settings.divisions) do
local requiredGroupRank = groupData.RequiredGroupRank
for key, divisionData in pairs(groupData) do
if type(divisionData) == "table" and key:lower() == divisionKey:lower() then
if player:IsInGroup(groupId) and player:GetRankInGroup(groupId) and player:GetRankInGroup(groupId) >= requiredGroupRank then
local success, formattedText = pcall(string.format, divisionData.description, player.Name, padValue, "[" .. settings.announcementCounter .. "/" .. settings.maxAnnouncements .. "]")
if success then
local playerAbbreviation = PlayerRank(player)
return { divisionKey, formattedText:gsub(player.Name, string.format("<b>%s %s:</b>", playerAbbreviation, player.Name), 1), divisionData.Icon, divisionData.Header }
else
warn("Error formatting text for division " .. divisionKey)
end
else
warn("User is not in the group or does not have the required group rank")
end
end
end
end
warn("No division with the name " .. divisionKey)
end
local function handleCommand(playerEvent, args)
local currentTime = tick()
local timeSinceLastCommand = currentTime - lastCommandTime
local remainingCooldown = math.max(0, cooldownDuration - timeSinceLastCommand)
if cooldownActive and timeSinceLastCommand < cooldownDuration then
print("Command is on cooldown. Remaining time:", math.floor(remainingCooldown), "seconds")
return
end
if not playerEvent or not args or type(args) ~= "table" or #args < 3 then
warn("Invalid parameters for the onServer function.")
return
end
local divisionKey = tostring(args[2]):lower()
local tryoutPads = workspace.Pads.Tryout_Pads:GetDescendants()
local dynamicPadAmount = math.min(#tryoutPads, GameSettings.new().maxPadAmount)
local modelName = args[3]:lower()
local isValidModelName = false
for _, descendant in ipairs(tryoutPads) do
if descendant:IsA("Model") and descendant.Name:lower() == modelName then
isValidModelName = true
break
end
end
if not isValidModelName then
warn("Provided name does not match any model name in Tryout_Pads.")
return
end
local numericValue = tonumber(args[3])
local padValue = numericValue and math.min(numericValue, dynamicPadAmount) or args[3]
if not divisionKey then
warn("Invalid divisionKey.")
return
end
local result = getDivisionDetails(playerEvent, divisionKey, padValue)
if result then
local _, formattedText, iconUrl, headerText = unpack(result)
local settings = GameSettings.new()
local newAnnouncements = settings.announcementCounter
local maxAnnouncements = settings.maxAnnouncements
while newAnnouncements < settings.maxAnnouncements do
newAnnouncements = newAnnouncements + 1
formattedText = formattedText:gsub("%[%d/3%]", "[" .. newAnnouncements .. "/3]")
local success, errorOrPlayerList = pcall(function()
local Players = game:GetService("Players")
for _, player in pairs(Players:GetPlayers()) do
local playerRank = player:GetRoleInGroup(settings.mainGroupID)
local richTextPlayerName = string.format("<b>%s %s:</b>", playerRank, player.Name)
local escapedPlayerName = player.Name:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%1")
local pattern = escapedPlayerName .. "%]%]"
local fullText = formattedText:gsub(pattern, richTextPlayerName, 1)
NotificationModule:Notify(headerText, fullText, iconUrl, settings.waitTimeInSeconds, notificationStyle, player)
startCooldown() -- THIS PART
end
end)
if not success then
warn("Error during notification: " .. tostring(errorOrPlayerList))
return
end
task.wait(settings.waitTimeInSeconds)
end
end
end
Announcement.OnServerEvent:Connect(handleCommand)