Cakey3101

Races Server

Sep 22nd, 2025
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.88 KB | Source Code | 0 0
  1. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  2. local Players = game:GetService("Players")
  3. local ServerStorage = game:GetService("ServerStorage")
  4. local Workspace = game:GetService("Workspace")
  5.  
  6. local RaceFolder = ReplicatedStorage:WaitForChild("Race")
  7.  
  8. local RaceMapsFolder = ServerStorage:WaitForChild("RaceMaps")
  9. local RaceMaps = RaceMapsFolder:GetChildren()
  10.  
  11. local Remotes = ReplicatedStorage:WaitForChild("Remotes")
  12. local Bindables = ReplicatedStorage:WaitForChild("Bindables")
  13.  
  14. local RaceGUI = RaceFolder:WaitForChild("Race")
  15. local WinGUI = RaceFolder:WaitForChild("Winner")
  16.  
  17. local RaceConfig = require(ReplicatedStorage:WaitForChild("Configs"):WaitForChild("Races"))
  18.  
  19. local ChosenMap = nil
  20.  
  21. local GuiShown = false
  22.  
  23. local GuiClones = {}
  24. local NotDecided = {}
  25. local FinishedPlayers = {}
  26.  
  27. local function SpawnGui()
  28.     for _, Player: Player in pairs(Players:GetPlayers()) do
  29.         local GuiClone = RaceGUI:Clone()
  30.         GuiClone.Parent = Player.PlayerGui
  31.         table.insert(GuiClones, GuiClone)
  32.         table.insert(NotDecided, Player)
  33.     end
  34. end
  35.  
  36. local function SpawnWinnerGui()
  37.     for _, Player in pairs(Players:GetPlayers()) do
  38.         local GuiClone = WinGUI:Clone()
  39.  
  40.         if #FinishedPlayers >= 3 then
  41.             GuiClone.Frame.First.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[1].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
  42.             GuiClone.Frame.First.Title.Text = FinishedPlayers[1].Name
  43.  
  44.             GuiClone.Frame.Second.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[2].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
  45.             GuiClone.Frame.Second.Title.Text = FinishedPlayers[2].Name
  46.  
  47.             GuiClone.Frame.Third.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[3].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
  48.             GuiClone.Frame.Third.Title.Text = FinishedPlayers[3].Name
  49.         elseif #FinishedPlayers == 2 then
  50.             GuiClone.Frame.First.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[1].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
  51.             GuiClone.Frame.First.Title.Text = FinishedPlayers[1].Name
  52.  
  53.             GuiClone.Frame.Second.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[2].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
  54.             GuiClone.Frame.Second.Title.Text = FinishedPlayers[2].Name
  55.  
  56.             GuiClone.Frame.Third:Destroy()
  57.         elseif #FinishedPlayers == 1 then
  58.             GuiClone.Frame.First.Icon.Image = Players:GetUserThumbnailAsync(FinishedPlayers[1].UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
  59.             GuiClone.Frame.First.Title.Text = FinishedPlayers[1].Name
  60.  
  61.             GuiClone.Frame.Second:Destroy()
  62.             GuiClone.Frame.Third:Destroy()
  63.         end
  64.  
  65.         GuiClone.Parent = Player.PlayerGui
  66.  
  67.         if #FinishedPlayers == 0 then
  68.             GuiClone:Destroy()
  69.         end
  70.     end
  71. end
  72.  
  73. local function DestroyGui(RemoveAll: boolean)
  74.     if RemoveAll == false then
  75.         for i, v in pairs(NotDecided) do
  76.             local Index = table.find(GuiClones, v.PlayerGui.Race)
  77.             if Index then
  78.                 table.remove(NotDecided, table.find(NotDecided, v))
  79.                 table.remove(GuiClones, Index)
  80.                 v.PlayerGui.Race:Destroy()
  81.             end
  82.         end
  83.  
  84.         for i, v in pairs(GuiClones) do
  85.             v.Parent:WaitForChild("Top"):WaitForChild("RaceStatus").Text = `Race ending in`
  86.         end
  87.     else
  88.         for i, v in pairs(GuiClones) do
  89.             v:Destroy()
  90.         end
  91.  
  92.         GuiClones = {}
  93.     end
  94. end
  95.  
  96. local function DestroyWinGui()
  97.     for _, Player in pairs(Players:GetPlayers()) do
  98.         if Player.PlayerGui:FindFirstChild("Winner") then
  99.             Player.PlayerGui.Winner:Destroy()
  100.         end
  101.     end
  102. end
  103.  
  104. local function UpdateGuiTimer(RaceInProgress: boolean)
  105.     if RaceInProgress == false then
  106.         for i, v in pairs(GuiClones) do
  107.             if v.Parent:WaitForChild("Top"):WaitForChild("RaceStatus") and v:WaitForChild("Prompt") then
  108.                 v.Parent.Top.RaceStatus.Text = `Race starts in {string.format("%02i:%02i", RaceConfig.Timer / 60, RaceConfig.Timer % 60)}`
  109.                 v.Prompt.Title.Text = `A race is starting, want to join? ({RaceConfig.Timer})`
  110.             end
  111.         end
  112.     else
  113.         for i, v in pairs(GuiClones) do
  114.             if v.Parent:WaitForChild("Top"):WaitForChild("RaceStatus") and v:WaitForChild("Prompt") then
  115.                 v.Parent.Top.RaceStatus.Text = `Race ends in {string.format("%02i:%02i", RaceConfig.InProgressTimer / 60, RaceConfig.InProgressTimer % 60)}`
  116.             end
  117.         end
  118.     end
  119. end
  120.  
  121. local function StartRace()
  122.     FinishedPlayers = {}
  123.     NotDecided = {}
  124.     GuiShown = false
  125.     ChosenMap.Wall.CanCollide = true
  126.    
  127.     local StartTimer = coroutine.create(RaceConfig.StartTimer)
  128.     coroutine.resume(StartTimer)
  129. end
  130.  
  131. Remotes.TeleportPlayer.OnServerEvent:Connect(function(Player: Player)
  132.     if Player.Character then
  133.         local Spawns = ChosenMap.SpawnParts:GetChildren()
  134.         local Index = math.random(#Spawns)
  135.  
  136.         Player.Character:PivotTo(Spawns[Index].CFrame + Vector3.new(0, 2, 0))
  137.  
  138.         local TableIndex = table.find(NotDecided, Player)
  139.         if TableIndex then
  140.             table.remove(NotDecided, TableIndex)
  141.         end
  142.     end
  143. end)
  144.  
  145. Remotes.DismissRace.OnServerEvent:Connect(function(Player: Player, GUI: ScreenGui)
  146.     local Index = table.find(GuiClones, GUI)
  147.     if Index then
  148.         table.remove(NotDecided, table.find(NotDecided, Player))
  149.         table.remove(GuiClones, Index)
  150.         GUI:Destroy()
  151.     end
  152. end)
  153.  
  154. Bindables.StartRace.Event:Connect(function()
  155.     DestroyGui(false)
  156.  
  157.     local RaceInProgress = coroutine.create(RaceConfig.RaceInProgress)
  158.     coroutine.resume(RaceInProgress)
  159.  
  160.     local Wall = ChosenMap:WaitForChild("Wall")
  161.     Wall.CanCollide = false
  162. end)
  163.  
  164. Bindables.FinishRace.Event:Connect(function()
  165.     DestroyGui(true)
  166.  
  167.     ChosenMap.Parent = RaceFolder
  168.  
  169.     for _, Player: Player in pairs(Players:GetPlayers()) do
  170.         if Player.PlayerGui:WaitForChild("Top"):WaitForChild("RaceStatus") then
  171.             Player.PlayerGui.Top.RaceStatus.Text = ``
  172.         end
  173.     end
  174.  
  175.     SpawnWinnerGui()
  176.  
  177.     if #FinishedPlayers >= 3 then
  178.         FinishedPlayers[1]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
  179.         FinishedPlayers[1]:WaitForChild("Gems").Value += 500
  180.  
  181.         FinishedPlayers[2]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
  182.         FinishedPlayers[2]:WaitForChild("Gems").Value += 250
  183.  
  184.         FinishedPlayers[3]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
  185.         FinishedPlayers[3]:WaitForChild("Gems").Value += 100
  186.     elseif #FinishedPlayers == 2 then
  187.         FinishedPlayers[1]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
  188.         FinishedPlayers[1]:WaitForChild("Gems").Value += 500
  189.  
  190.         FinishedPlayers[2]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
  191.         FinishedPlayers[2]:WaitForChild("Gems").Value += 250
  192.     elseif #FinishedPlayers == 1 then
  193.         FinishedPlayers[1]:WaitForChild("leaderstats"):WaitForChild("Races").Value += 1
  194.         FinishedPlayers[1]:WaitForChild("Gems").Value += 500
  195.     end
  196.    
  197.     local Intermission = coroutine.create(RaceConfig.Intermission)
  198.     coroutine.resume(Intermission)
  199. end)
  200.  
  201. local function RandomMap()
  202.     local ChosenMapIndex = math.random(#RaceMaps)
  203.     RaceMaps[ChosenMapIndex].Parent = Workspace
  204.     ChosenMap = RaceMaps[ChosenMapIndex]
  205. end
  206.  
  207. local function LoadFirstRace()
  208.     RandomMap()
  209.     StartRace()
  210. end
  211.  
  212. LoadFirstRace()
  213.  
  214. while task.wait(1) do
  215.     if RaceConfig.Timer > 0 then
  216.         if #RaceMapsFolder:GetChildren() == #RaceMaps then
  217.             RandomMap()
  218.         end
  219.  
  220.         if GuiShown == false then
  221.             GuiShown = true
  222.             SpawnGui()
  223.         end
  224.  
  225.         UpdateGuiTimer(false)
  226.     else
  227.         UpdateGuiTimer(true)
  228.        
  229.         ChosenMap.FinishArea.Touched:Connect(function(Hit: BasePart)
  230.             if Hit.Parent then
  231.                 local Player = Players:GetPlayerFromCharacter(Hit.Parent)
  232.                 if Player then
  233.                     if table.find(FinishedPlayers, Player) then
  234.                         return
  235.                     end
  236.                    
  237.                     table.insert(FinishedPlayers, Player)
  238.                    
  239.                     if Player.Character then
  240.                         Player.Character:PivotTo(Workspace.SpawnLocation.CFrame + Vector3.new(0, 2, 0))
  241.                     end
  242.                 end
  243.             end
  244.         end)
  245.     end
  246.  
  247.     if RaceConfig.Timer <= 0 and RaceConfig.InProgressTimer <= 0 then
  248.         task.wait(5)
  249.         DestroyWinGui()
  250.        
  251.         if RaceConfig.IntermissionTimer <= 0 then
  252.             StartRace()
  253.         end
  254.     end
  255. end
Advertisement
Add Comment
Please, Sign In to add comment