Advertisement
Scripting_King

Untitled

Jul 1st, 2025
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.62 KB | Source Code | 0 0
  1. --[[
  2.     Queue System Script by lenovo768
  3.     Discord: the_king_here
  4.     Description: Manages player queueing using Zone module, UI elements, player limits,
  5.     friend-only mode, camera control, and player teleportation after countdown.
  6. --]]
  7.  
  8. --// Services
  9. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  10. local TweenService = game:GetService("TweenService")
  11. local Lighting = game:GetService("Lighting")
  12. local Players = game:GetService("Players")
  13.  
  14. --// Modules
  15. local Zone = require(ReplicatedStorage:WaitForChild("Module"):WaitForChild("Zone"))
  16.  
  17. --// References
  18. local QueuesFolder = workspace:WaitForChild("Queqe"):WaitForChild("QueueStand")
  19. local CameraEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("CameraEvent")
  20. local Blur = Lighting:WaitForChild("BlurForGui")
  21.  
  22. --// Tween Info Constants
  23. local showTweenInfo = TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
  24. local hideTweenInfo = TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.In)
  25.  
  26. --// Settings
  27. local DefaultDuration = 45
  28.  
  29. --// Utility Functions
  30.  
  31. -- Teleports player to a specific position while keeping rotation
  32. local function teleportPlayerOut(player: Player, position: Vector3)
  33.     if not player.Character or not player.Character:FindFirstChild("HumanoidRootPart") then return end
  34.     local root:BasePart = player.Character.HumanoidRootPart
  35.     local rotation = root.CFrame.Rotation -- get's the current rotation
  36.     player.Character:PivotTo(CFrame.new(position) * rotation) -- Teleports the player while keeping their rotation
  37. end
  38.  
  39. -- Clears the player queue UI tiles
  40. local function clearQueueUI(frame: Frame)
  41.     for _, tile in pairs(frame.QueueTiles:GetChildren()) do
  42.         if tile:IsA("ImageButton") then
  43.             tile.ImageLabel.Image = ""
  44.             tile.PlayerName.Value = ""
  45.         end
  46.     end
  47. end
  48.  
  49. -- Main Logic Per Queue Stand
  50. for _, stand in pairs(QueuesFolder:GetChildren()) do
  51.     if not stand:IsA("Model") then continue end
  52.  
  53.     local zonePart = stand:WaitForChild("Circle"):WaitForChild("Zone")
  54.     if not zonePart then continue end
  55.  
  56.     local zone = Zone.new(zonePart)
  57.  
  58.     -- State Variables
  59.     local owner = nil --refrence to the player who first enter in the zone
  60.     local playerCount = 0 --counts the player that are currently in zone
  61.     local duration = DefaultDuration -- Countdown duration
  62.     local queuePlayers = {} --Keeps a live list of players who are currently standing inside the queue zone
  63.     local kickedPlayers = {} --It temporarily mark players who were forcefully removed from the queue zone so the system knows not to handle them like normal leavers
  64.  
  65.     local connections = {} --keeps track of all active connections so that we can disconnect them later
  66.  
  67.     -- Updates the count label on Billboard GUI
  68.     local function updateCountDisplay(frame, allowed)
  69.         stand.PlayerCount.BillboardGui.TextLabel.Text = `${playerCount}/${allowed}` --shows player count and max limit in the UI so player can see it
  70.     end
  71.  
  72.     -- Start countdown timer
  73.     local function startCountdown(frame)
  74.         task.spawn(function()
  75.             while duration > 0 and owner do --if duration/time is greater then 0 and owner is still in the zone then keep countdowning
  76.                 task.wait(1)
  77.                 duration -= 1
  78.                 frame.AutoStartingText.TimeAmountText.Text = duration
  79.             end
  80.  
  81.             if not owner then return end --it stopes the execution of this function immediately if the owner has left
  82.  
  83.             -- Timer ends, teleport all players
  84.             for _, plr in ipairs(queuePlayers) do
  85.                 task.spawn(function()
  86.                     CameraEvent:FireClient(plr, "Cutscene", workspace.Cutscene.Rigs.CameraRig.CameraRoot, nil, plr == owner) --it handles the camera movement of the cutscene
  87.                     task.wait(1.5)
  88.                     teleportPlayerOut(plr, zonePart.CFrame.Position + Vector3.new(25, 0, 0)) --Ejects player from queue to allow others access
  89.                 end)
  90.             end
  91.  
  92.             CameraEvent:FireClient(owner, "PlayAnimation", nil, frame) --it plays curscene animation
  93.             CameraEvent:FireClient(owner, "DecreaseFieldOfView", nil, frame) --it decreases the camera FOV and hides the UI with animation
  94.         end)
  95.     end
  96.  
  97.     -- Handles friend filter toggle
  98.     local function setupFriendToggle(frame)
  99.         local connection = frame.IsOnlyFriendsAllowed.Changed:Connect(function()
  100.             if not owner or not frame.IsOnlyFriendsAllowed.Value then return end --if owner has left or the isonlyfriendallowed button is turned off then it stops the execution of the function
  101.            
  102.             -- kicks the player out if he is not friend of owner (the person who entered first) on roblox
  103.             for i = #queuePlayers, 1, -1 do
  104.                 local queuedPlayer = queuePlayers[i]
  105.                 if queuedPlayer == owner then continue end
  106.  
  107.                 if not owner:IsFriendsWith(queuedPlayer.UserId) then
  108.                     teleportPlayerOut(queuedPlayer, zonePart.CFrame.Position + Vector3.new(25, 0, 0)) --Ejects player from queue to allow others access
  109.                     table.insert(kickedPlayers, queuedPlayer)
  110.                     table.remove(queuePlayers, i)
  111.                     playerCount -= 1
  112.                 end
  113.             end
  114.  
  115.             updateCountDisplay(frame, frame.AllowedPlayers.Value) --updates the count UI to  show the current player count and max limit
  116.             clearQueueUI(frame) --removes the kicked player's presence from the queue display frame
  117.            
  118.             --it updates queue frame that shows current players in the queue
  119.             for index, plr in ipairs(queuePlayers) do
  120.                 local tile = frame.QueueTiles:FindFirstChild("QueueTile" .. index)
  121.                 if tile then
  122.                     tile.ImageLabel.Image = Players:GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420) --it returns the close picture of player's face
  123.                     tile.PlayerName.Value = plr.Name
  124.                 end
  125.             end
  126.         end)
  127.  
  128.         table.insert(connections, connection) --adding the connection to connection table to keep record of it and to disconnect it when needed
  129.     end
  130.  
  131.     -- Kick a player via kick button/player can kick any player he wants by clicking kick button on the queue frame
  132.     local function setupKickButton(frame, targetPlayer)
  133.         for _, tile in pairs(frame.QueueTiles:GetChildren()) do --loop through all childs of queueTitles which actually include all players that are in queue
  134.             if tile:IsA("ImageButton") and tile.PlayerName.Value == targetPlayer.Name then
  135.                 local button = tile:FindFirstChild("KickButton") --button to kick player out of the zone
  136.                 if button then
  137.                     local connection = button.MouseButton1Click:Connect(function()
  138.                         if targetPlayer == owner then return end --if owner tries to kick himself then it will stop execution and do nothing
  139.  
  140.                         teleportPlayerOut(targetPlayer, zonePart.CFrame.Position + Vector3.new(25, 0, 0))--Ejects player from queue to allow others access
  141.                         table.insert(kickedPlayers, targetPlayer) --temporarily add player to kick table to keep record of it
  142.  
  143.                         local index = table.find(queuePlayers, targetPlayer)
  144.                         if index then
  145.                             table.remove(queuePlayers, index)
  146.                             playerCount -= 1
  147.                         end
  148.  
  149.                         updateCountDisplay(frame, frame.AllowedPlayers.Value) --updates the count UI to  show the current player count and max limit
  150.                         clearQueueUI(frame) --removes the kicked player's presence from the queue display frame
  151.                        
  152.                         --it updates queue frame that shows current players in the queue
  153.                         for idx, plr in ipairs(queuePlayers) do
  154.                             local t = frame.QueueTiles:FindFirstChild("QueueTile" .. idx)
  155.                             if t then
  156.                                 t.ImageLabel.Image = Players:GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420) --it returns the close shot of player's face
  157.                                 t.PlayerName.Value = plr.Name
  158.                             end
  159.                         end
  160.                     end)
  161.                     table.insert(connections, connection)
  162.                 end
  163.             end
  164.         end
  165.     end
  166.  
  167.     -- Setup Start and Cancel buttons for owner
  168.     local function setupOwnerButtons(frame)
  169.         local cancelConnection = frame.SelectionUI.CancelButton.MouseButton1Click:Connect(function()
  170.             CameraEvent:FireClient(owner, "DecreaseFieldOfView", nil, frame) --it decreases the camera FOV and hides the UI with animation
  171.         end)
  172.         table.insert(connections, cancelConnection)
  173.  
  174.         local startConnection = frame.StartButton.MouseButton1Click:Connect(function() --if owner clicks start button then it will stop the countdown loop and start the game instantly
  175.             duration = 0
  176.         end)
  177.         table.insert(connections, startConnection)
  178.     end
  179.  
  180.     -- Assign a new owner and begin queue logic
  181.     local function initializeOwner(player)
  182.         owner = player --player who joined first get assigned as a owner
  183.         playerCount = 1 --increases playercount to 1
  184.         duration = DefaultDuration --set the start time duration to default 45 seconds
  185.         queuePlayers = {player} --it adds the owner to the queue player, since this table holds all player that are in zone
  186.         kickedPlayers = {}
  187.  
  188.         local frame = player:WaitForChild("PlayerGui"):WaitForChild("SSimUI"):WaitForChild("Frame") --refrence to the frame that gives different options to the owner
  189.         frame.Position = UDim2.new(0.5, 0, 1.5, 0) --setting the position of the frame to the bottom down of the screen
  190.         frame.Visible = true --make frame visible
  191.         frame.AutoStartingText.TimeAmountText.Text = duration --updating frame text to show current duration
  192.  
  193.         CameraEvent:FireClient(owner, "IncreaseFieldOfView", nil, frame) --function to animate frame position, camera FOV and blur size
  194.  
  195.         local tile = frame.QueueTiles:FindFirstChild("QueueTile1")
  196.         if tile then
  197.             tile.ImageLabel.Image = Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420) --it returns the close shot of player's face
  198.             tile.PlayerName.Value = player.Name
  199.         end
  200.        
  201.         --calling upper functions to make the UI buttons works
  202.         setupFriendToggle(frame)
  203.         setupOwnerButtons(frame)
  204.         startCountdown(frame)
  205.     end
  206.  
  207.     -- Player enters the zone
  208.     zone.playerEntered:Connect(function(player) --it runs whenever any player enters in the region of the zone
  209.         if table.find(queuePlayers, player) then return end
  210.         table.insert(queuePlayers, player) --insert players in queuePlayers, since it holds record of all players that are in zone
  211.  
  212.         local playerGui = player:WaitForChild("PlayerGui")
  213.         local frame = playerGui:WaitForChild("SSimUI"):WaitForChild("Frame")
  214.  
  215.         if not owner then
  216.             initializeOwner(player) --defines owner if not defined yet
  217.             return
  218.         end
  219.  
  220.         local allowed = frame.AllowedPlayers.Value
  221.         if playerCount >= allowed then --checks if the max player count is reached, if it is then it kicks the player out
  222.             teleportPlayerOut(player, zonePart.CFrame.Position + Vector3.new(25, 0, 0))
  223.             table.insert(kickedPlayers, player)
  224.             return
  225.         end
  226.  
  227.         if frame.IsOnlyFriendsAllowed.Value and not owner:IsFriendsWith(player.UserId) then -- it kicks the player out if IsOnlyFriendAllowed setting is turned ON but the player is not a friend of owner
  228.             teleportPlayerOut(player, zonePart.CFrame.Position + Vector3.new(25, 0, 0))
  229.             table.insert(kickedPlayers, player)
  230.             return
  231.         end
  232.  
  233.         playerCount += 1 --updates the playercount
  234.         updateCountDisplay(frame, allowed) --updates the UI that shows the current player count
  235.  
  236.         local tile = frame.QueueTiles:FindFirstChild("QueueTile" .. playerCount)
  237.         if tile then
  238.             tile.ImageLabel.Image = Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
  239.             tile.PlayerName.Value = player.Name
  240.         end
  241.  
  242.         setupKickButton(frame, player)
  243.     end)
  244.  
  245.     -- Player leaves the zone
  246.     zone.playerExited:Connect(function(player) --it runs whenever any player leaves the region of the zone
  247.         local index = table.find(queuePlayers, player)
  248.         if index then
  249.             table.remove(queuePlayers, index) --it removes the player from the queuePlayers table since player is not in zone anymore
  250.             playerCount -= 1
  251.         end
  252.  
  253.         local kickIndex = table.find(kickedPlayers, player)
  254.         if kickIndex then
  255.             table.remove(kickedPlayers, kickIndex) --if player was kicked from the zone that it removes the player from the zone without decreasing playerCount
  256.         end
  257.  
  258.         if player == owner then --if player who exited the zone is the owner then it disconnect all connections and closes the frame
  259.             local frame = player:WaitForChild("PlayerGui"):WaitForChild("SSimUI"):WaitForChild("Frame")
  260.             CameraEvent:FireClient(owner, "DecreaseFieldOfView", nil, frame)
  261.             frame.Visible = false
  262.  
  263.             for _, conn in ipairs(connections) do --Disconnecting all connections
  264.                 if conn and typeof(conn) == "RBXScriptConnection" then
  265.                     conn:Disconnect()
  266.                 end
  267.             end
  268.             table.clear(connections) --clears the connections table, since all connections are disconnected so we don't need to track them anymore
  269.  
  270.             clearQueueUI(frame) --it cleared the frame that shows the presence of players in the queue
  271.  
  272.             for _, plr in ipairs(queuePlayers) do
  273.                 teleportPlayerOut(plr, zonePart.CFrame.Position + Vector3.new(25, 0, 0)) --Ejects player from queue to allow others access
  274.             end
  275.             table.clear(queuePlayers) --it clears the queuePlayers table, since the queue is over
  276.  
  277.             owner = nil --removes the player refrence from the variable owner, since the player has left the queue
  278.             playerCount = 0 --resets the player count
  279.             duration = DefaultDuration --resets the queue duration
  280.         else
  281.             if owner and owner:FindFirstChild("PlayerGui") then -- if the player who left is not a owner and the owner still exist in queue then it clears only that player existance from the queueTitles frame
  282.                 local frame = owner.PlayerGui:FindFirstChild("SSimUI") and owner.PlayerGui.SSimUI:FindFirstChild("Frame")
  283.                 if frame then
  284.                     for _, tile in pairs(frame.QueueTiles:GetChildren()) do
  285.                         if tile:IsA("ImageButton") and tile.PlayerName.Value == player.Name then
  286.                             tile.ImageLabel.Image = ""
  287.                             tile.PlayerName.Value = ""
  288.                         end
  289.                     end
  290.                     updateCountDisplay(frame, frame.AllowedPlayers.Value) --updates the count UI to  show the current player count and max limit
  291.                 end
  292.             end
  293.         end
  294.     end)
  295. end
  296.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement