local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Workspace = game:GetService("Workspace")
local RaceFolder = ReplicatedStorage:WaitForChild("Race")
local RaceMapsFolder = ServerStorage:WaitForChild("RaceMaps")
local RaceMaps = RaceMapsFolder:GetChildren()
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local Bindables = ReplicatedStorage:WaitForChild("Bindables")
local RaceGUI = RaceFolder:WaitForChild("Race")
local WinGUI = RaceFolder:WaitForChild("Winner")
local RaceConfig = require(ReplicatedStorage:WaitForChild("Configs"):WaitForChild("Races"))
local ChosenMap = nil
local GuiShown = false
local GuiClones = {}
local NotDecided = {}
local FinishedPlayers = {}
local function SpawnGui()
for _, Player: Player in pairs(Players:GetPlayers()) do
local GuiClone = RaceGUI:Clone()
GuiClone.Parent = Player.PlayerGui
table.insert(GuiClones, GuiClone)
table.insert(NotDecided, Player)
end
end
local function SpawnWinnerGui()
for _, Player in pairs(Players:GetPlayers()) do
local GuiClone = WinGUI:Clone()
if #FinishedPlayers >= 3 then
GuiClone.Frame.First.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[1].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
GuiClone.Frame.First.Title.Text = FinishedPlayers[1].Name
GuiClone.Frame.Second.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[2].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
GuiClone.Frame.Second.Title.Text = FinishedPlayers[2].Name
GuiClone.Frame.Third.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[3].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
GuiClone.Frame.Third.Title.Text = FinishedPlayers[3].Name
elseif #FinishedPlayers == 2 then
GuiClone.Frame.First.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[1].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
GuiClone.Frame.First.Title.Text = FinishedPlayers[1].Name
GuiClone.Frame.Second.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[2].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
GuiClone.Frame.Second.Title.Text = FinishedPlayers[2].Name
GuiClone.Frame.Third:Destroy()
elseif #FinishedPlayers == 1 then
GuiClone.Frame.First.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[1].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
GuiClone.Frame.First.Title.Text = FinishedPlayers[1].Name
GuiClone.Frame.Second:Destroy()
GuiClone.Frame.Third:Destroy()
end
GuiClone.Parent = Player.PlayerGui
if #FinishedPlayers == 0 then
GuiClone:Destroy()
end
end
end
local function DestroyGui(RemoveAll: boolean)
if RemoveAll == false then
for i, v in pairs(NotDecided) do
local Index = table.find(GuiClones, v.PlayerGui.Race)
if Index then
table.remove(NotDecided, table.find(NotDecided, v))
table.remove(GuiClones, Index)
v.PlayerGui.Race:Destroy()
end
end
for i, v in pairs(GuiClones) do
v.Parent:WaitForChild("Top"):WaitForChild("RaceStatus").Text = `Race ending in`
end
else
for i, v in pairs(GuiClones) do
v:Destroy()
end
GuiClones = {}
end
end
local function DestroyWinGui()
for _, Player in pairs(Players:GetPlayers()) do
if Player.PlayerGui:FindFirstChild("Winner") then
Player.PlayerGui.Winner:Destroy()
end
end
end
local function UpdateGuiTimer(RaceInProgress: boolean)
if RaceInProgress == false then
for i, v in pairs(GuiClones) do
if v.Parent:WaitForChild("Top"):WaitForChild("RaceStatus") and v:WaitForChild("Prompt") then
v.Parent.Top.RaceStatus.Text = `Race starts in {string.format("%02i:%02i", RaceConfig.Timer / 60, RaceConfig.Timer % 60)}`
v.Prompt.Title.Text = `A race is starting, want to join? ({RaceConfig.Timer})`
end
end
else
for i, v in pairs(GuiClones) do
if v.Parent:WaitForChild("Top"):WaitForChild("RaceStatus") and v:WaitForChild("Prompt") then
v.Parent.Top.RaceStatus.Text = `Race ends in {string.format("%02i:%02i", RaceConfig.InProgressTimer / 60, RaceConfig.InProgressTimer % 60)}`
end
end
end
end
local function StartRace()
FinishedPlayers = {}
NotDecided = {}
GuiShown = false
ChosenMap.Wall.CanCollide = true
local StartTimer = coroutine.create(RaceConfig.StartTimer)
coroutine.resume(StartTimer)
end
Remotes.TeleportPlayer.OnServerEvent:Connect(function(Player: Player)
if Player.Character then
local Spawns = ChosenMap.SpawnParts:GetChildren()
local Index = math.random(#Spawns)
Player.Character:PivotTo(Spawns[Index].CFrame + Vector3.new(0, 2, 0))
local TableIndex = table.find(NotDecided, Player)
if TableIndex then
table.remove(NotDecided, TableIndex)
end
end
end)
Remotes.DismissRace.OnServerEvent:Connect(function(Player: Player, GUI: ScreenGui)
local Index = table.find(GuiClones, GUI)
if Index then
table.remove(NotDecided, table.find(NotDecided, Player))
table.remove(GuiClones, Index)
GUI:Destroy()
end
end)
Bindables.StartRace.Event:Connect(function()
DestroyGui(false)
local RaceInProgress = coroutine.create(RaceConfig.RaceInProgress)
coroutine.resume(RaceInProgress)
local Wall = ChosenMap:WaitForChild("Wall")
Wall.CanCollide = false
end)
Bindables.FinishRace.Event:Connect(function()
DestroyGui(true)
ChosenMap.Parent = RaceFolder
for _, Player: Player in pairs(Players:GetPlayers()) do
if Player.PlayerGui:WaitForChild("Top"):WaitForChild("RaceStatus") then
Player.PlayerGui.Top.RaceStatus.Text = ``
end
end
SpawnWinnerGui()
if #FinishedPlayers >= 3 then
FinishedPlayers[1]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
FinishedPlayers[1]:WaitForChild("Gems").Value += 500
FinishedPlayers[2]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
FinishedPlayers[2]:WaitForChild("Gems").Value += 250
FinishedPlayers[3]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
FinishedPlayers[3]:WaitForChild("Gems").Value += 100
elseif #FinishedPlayers == 2 then
FinishedPlayers[1]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
FinishedPlayers[1]:WaitForChild("Gems").Value += 500
FinishedPlayers[2]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
FinishedPlayers[2]:WaitForChild("Gems").Value += 250
elseif #FinishedPlayers == 1 then
FinishedPlayers[1]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
FinishedPlayers[1]:WaitForChild("Gems").Value += 500
end
local Intermission = coroutine.create(RaceConfig.Intermission)
coroutine.resume(Intermission)
end)
local function RandomMap()
local ChosenMapIndex = math.random(#RaceMaps)
RaceMaps[ChosenMapIndex].Parent = Workspace
ChosenMap = RaceMaps[ChosenMapIndex]
end
local function LoadFirstRace()
RandomMap()
StartRace()
end
LoadFirstRace()
while task.wait(1) do
if RaceConfig.Timer > 0 then
if #RaceMapsFolder:GetChildren() == #RaceMaps then
RandomMap()
end
if GuiShown == false then
GuiShown = true
SpawnGui()
end
UpdateGuiTimer(false)
else
UpdateGuiTimer(true)
ChosenMap.FinishArea.Touched:Connect(function(Hit: BasePart)
if Hit.Parent then
local Player = Players:GetPlayerFromCharacter(Hit.Parent)
if Player then
if table.find(FinishedPlayers, Player) then
return
end
table.insert(FinishedPlayers, Player)
if Player.Character then
Player.Character:PivotTo(Workspace.SpawnLocation.CFrame + Vector3.new(0, 2, 0))
end
end
end
end)
end
if RaceConfig.Timer <= 0 and RaceConfig.InProgressTimer <= 0 then
task.wait(5)
DestroyWinGui()
if RaceConfig.IntermissionTimer <= 0 then
StartRace()
end
end
end