Advertisement
Scripting_King

Untitled

Jul 8th, 2025
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 30.70 KB | Source Code | 0 0
  1. --[[
  2. Squid Game User Interface Controller
  3. Handles shop UI, reward UI, tool activation, gamepasses, animations, and GUI interaction logic using Knit framework.
  4. ]]
  5. --by the_king_here
  6. --//SERVICES
  7. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  8. local Knit = require(ReplicatedStorage.Packages.Knit)
  9. local TweenService = game:GetService("TweenService")
  10. local runService = game:GetService("RunService")
  11. local MPS = game:GetService("MarketplaceService")
  12. local LightningService = game:GetService("Lighting")
  13. local SoundService = game:GetService("SoundService")
  14.  
  15.  
  16. --TweenInfo config for UI transitions (0.3s, Back Out easing)
  17. local tweenInfoUI = TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.Out, 0)
  18.  
  19. -- Creating a Knit Controller
  20. local UserInterfaceController = Knit.CreateController{
  21.     Name = "UserInterface",
  22. }
  23.  
  24. -- Will store reference to the server side service later
  25. local MapHandlerService
  26.  
  27. -- Reference to the local player
  28. local player = game.Players.LocalPlayer
  29.  
  30. -- Control module to disable movement during certain actions
  31. local Controls = require(player.PlayerScripts.PlayerModule):GetControls()
  32.  
  33. -- UI References in PlayerGui
  34. local TrollUI = player.PlayerGui:WaitForChild("Troll")
  35. local PushUI = player.PlayerGui:WaitForChild("PushUI")
  36. local SettingsUI = player.PlayerGui:WaitForChild("Settings")
  37. local ShopUI = player.PlayerGui:WaitForChild("Shop")
  38. local InventoryUI = player.PlayerGui:WaitForChild("Inventory")
  39. local RewardUI = player.PlayerGui:WaitForChild("Reward")
  40.  
  41. -- Music References
  42. local BackgroundMusic = SoundService:WaitForChild("LobbyMusic")
  43. local SquidMusic = SoundService:WaitForChild("Music")
  44.  
  45. -- Developer product IDs
  46. local Products = {
  47.     EliminatePlayers = 3312415657,
  48.     SpeedTroll = 3312416017,
  49.     KillRandomPersonTroll = 3312444642,
  50.     TakeCoinsTroll = 3312417586,
  51. }
  52.  
  53. -- Push upgrades (more force or quantity)
  54. local PushProducts = {
  55.     Push1 = 3313283431,
  56.     Push2 = 3313283430,
  57.     Push5 = 3313283433,
  58.     Push7 = 3313283424,
  59.     Push10 = 3313286623,
  60. }
  61.  
  62. -- Tweening for background music transitions
  63. local tweenInfoForMusic = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0)
  64.  
  65. -- Reference to the camera for FOV changes
  66. local camera = workspace.CurrentCamera
  67.  
  68. -- Blur effect (GUI background blur)
  69. local Blur = LightningService:FindFirstChild("BlurForGui")
  70. local UIStroke
  71.  
  72. -- For rope animation disconnecting later
  73. local RopeAnimationConnection
  74.  
  75. -- Countdown before round starts (e.g., "3, 2, 1... Run!")
  76. function UserInterfaceController:BackTimer(StartTime, EndTime, UIToShowTime)
  77.     for i = StartTime, EndTime, -1 do
  78.         task.wait(1)
  79.         player.PlayerGui:WaitForChild("Timer").TextLabel.Visible = true
  80.         player.PlayerGui.Timer.TextLabel.Text = i --Displays time on textlabel
  81.         player.PlayerGui.Timer.TextLabel.TimerSound:Play() --plays timer sound every second
  82.         if i ~= 0 then continue end
  83.         task.wait(1)
  84.         player.PlayerGui.Timer.TextLabel.Text = "Run!" -- Final message
  85.         task.wait(1)
  86.         player.PlayerGui.Timer.TextLabel.Visible = false
  87.     end
  88. end
  89.  
  90. function UserInterfaceController:HandleUIStroke(argunent, Parent)
  91.     if argunent == "Add" then
  92.         if not UIStroke then  --UIStroke logic, it creates new UI stroke and add it to the button if there is no before and if there already exist then it just change the parent of existing stroke to the new button
  93.             UIStroke = Instance.new("UIStroke")
  94.             UIStroke.Parent = Parent
  95.             UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
  96.             UIStroke.Color = Color3.fromRGB(126, 36, 233)
  97.             UIStroke.Thickness = 2
  98.         else
  99.             UIStroke.Parent = Parent
  100.         end
  101.     elseif argunent == "Remove" then
  102.         UIStroke.Parent = nil
  103.     end
  104. end
  105.  
  106. -- Displays a short message on screen (centered label) for 3 seconds
  107. function UserInterfaceController:ShowMessage(Message)
  108.     player.PlayerGui:WaitForChild("Timer").TextLabel.Visible = true
  109.     player.PlayerGui.Timer.TextLabel.Text = Message
  110.     task.delay(3, function()
  111.         player.PlayerGui.Timer.TextLabel.Visible = false
  112.     end)
  113. end
  114.  
  115. local Rope -- rope part reference (used in Easy or Hard maps)
  116.  
  117. local maxSpeed -- max angular speed in radians/sec
  118. local accelTime = 3 -- how long to accelerate (ease in) in seconds
  119. local animationStarted = false -- variable to check if animation has started
  120. local animationStartTime = nil  -- server-synced time when animation begins
  121.  
  122. local initialCFrame -- store original rope CFrame
  123.  
  124. function UserInterfaceController:HandleAnimation(IsEnabledControls)
  125.     local now = workspace:GetServerTimeNow() --get current time
  126.     -- Wait until server-synced animation time
  127.     if not animationStarted and now >= animationStartTime then
  128.         animationStarted = true
  129.     end
  130.     if not animationStarted then return end
  131.  
  132.     -- Enable player controls 1 second after rope starts
  133.     if not IsEnabledControls then IsEnabledControls = true; Controls:Enable() end
  134.  
  135.     local elapsed = now - animationStartTime -- how long since animation began
  136.     local rotation --Stores rotation value
  137.  
  138.     -- Accelerate with cubic easing for first 3 seconds
  139.     if elapsed < accelTime then
  140.         local progress = elapsed / accelTime
  141.         rotation = 0.33 * maxSpeed * (progress ^ 3) * accelTime
  142.     else
  143.         -- Maintain constant speed after acceleration phase
  144.         local constantTime = elapsed - accelTime
  145.         rotation = 0.33 * maxSpeed * accelTime + maxSpeed * constantTime
  146.     end
  147.  
  148.     -- Rotate rope by X-axis only
  149.     local newCFrame = initialCFrame * CFrame.Angles(rotation, 0, 0)
  150.     Rope:PivotTo(newCFrame)
  151. end
  152.  
  153. -- Begins rope rotation animation based on server time
  154. function UserInterfaceController:startAnimationWhenReady(serverStartTime, Mode)
  155.     -- Decide map + speed based on mode
  156.     if Mode == "Easy" then
  157.         maxSpeed = math.rad(210) -- degrees to radians
  158.         Rope = workspace.Maps.EasyRopemap:WaitForChild("rope")
  159.     else
  160.         maxSpeed = math.rad(250)
  161.         Rope = workspace.Maps.HadRopeMap:WaitForChild("rope")
  162.     end
  163.     local primary = Rope.PrimaryPart --Stores refrence to rope primaryPart
  164.     initialCFrame = primary.CFrame -- store starting position
  165.     animationStartTime = serverStartTime
  166.     animationStarted = false
  167.     Controls:Disable() -- Disable player movement during pre rope animation
  168.  
  169.     -- If player has LessGravity effect, set gravity to 70
  170.     local LessGravity = player:FindFirstChild("LessGravity")
  171.     if LessGravity.Value > 0 then
  172.         MapHandlerService:LessGravity("DecreaseGravityValue")
  173.         workspace.Gravity = 70
  174.     end
  175.  
  176.  
  177.     local IsEnabledControls = false --keep track whether controls of player has been restored or not
  178.     -- Connect to RenderStepped to animate rope every frame
  179.     RopeAnimationConnection = runService.RenderStepped:Connect(function()
  180.         self:HandleAnimation(IsEnabledControls)
  181.     end)
  182. end
  183.  
  184. --returns name after removing text "button" from name if name contains text "Button"
  185. function UserInterfaceController:getNameAfterRemovingButton(name)
  186.     local suffix = "Button"
  187.     if name:sub(-#suffix) == suffix then
  188.         return name:sub(1, -#suffix - 1)
  189.     else
  190.         return name
  191.     end
  192. end
  193.  
  194. local originalRotation = 0 --Stoers default rotation, which is usually 0
  195.  
  196. -- function to scale UDim2 (used to make buttons shrink or grow)
  197. function UserInterfaceController:scaleSize(size: UDim2, scale: number): UDim2
  198.     return UDim2.new(
  199.         size.X.Scale * scale, size.X.Offset * scale,
  200.         size.Y.Scale * scale, size.Y.Offset * scale
  201.     )
  202. end
  203.  
  204. -- When mouse enters button (hover), enlarge slightly + rotate
  205. function UserInterfaceController:onHover(button, originalSize)
  206.     local hoverTween = TweenService:Create(button, TweenInfo.new(0.1), {
  207.         Size = self:scaleSize(originalSize, 1.1),
  208.         Rotation = 5,
  209.     })
  210.     hoverTween:Play()
  211. end
  212.  
  213. -- When mouse leaves button, restore size and rotation
  214. function UserInterfaceController:onUnhover(button, originalSize)
  215.     local unhoverTween = TweenService:Create(button, TweenInfo.new(0.1), {
  216.         Size = originalSize,
  217.         Rotation = originalRotation,
  218.     })
  219.     unhoverTween:Play()
  220. end
  221.  
  222. -- When button is clicked, shrink quickly then bounce back
  223. function UserInterfaceController:onClick(button, originalSize)
  224.     local shrinkTween = TweenService:Create(button, TweenInfo.new(0.05), {
  225.         Size = self:scaleSize(originalSize, 0.8),
  226.     })
  227.     local restoreTween = TweenService:Create(button, TweenInfo.new(0.1), {
  228.         Size = originalSize,
  229.     })
  230.  
  231.     shrinkTween:Play()
  232.     shrinkTween.Completed:Connect(function()
  233.         restoreTween:Play()
  234.     end)
  235. end
  236.  
  237. local OpenedUI -- Tracks which UI is currently open
  238.  
  239. function UserInterfaceController:tweenOpen(Canavs) --Function to open UI with tween/animation
  240.     Canavs.Visible = true
  241.     Canavs.Position = UDim2.new(0.5, 0, 1.5, 0)
  242.     Canavs:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 0.3) --Animating the position of the UI
  243.     TweenService:Create(camera, tweenInfoUI, {FieldOfView = 100}):Play() --Increasing FOV with animation to give overall animation better look
  244.     TweenService:Create(Blur, tweenInfoUI, {Size = 20}):Play() --Applying blur with animation
  245. end
  246.  
  247. function UserInterfaceController:tweenClose(Canavs) --function to close UI with tween/animation
  248.     Canavs:TweenPosition(UDim2.new(0.5, 0, 1.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 0.3)
  249.     TweenService:Create(camera, tweenInfoUI, {FieldOfView = 70}):Play()
  250.     TweenService:Create(Blur, tweenInfoUI, {Size = 0}):Play()
  251. end
  252.  
  253. function UserInterfaceController:handleUIState(Canavs)
  254.     if not OpenedUI then -- No UI open yet
  255.         OpenedUI = Canavs --Defines the current open UI
  256.         self:tweenOpen(Canavs)
  257.     elseif OpenedUI and OpenedUI ~= Canavs then-- Switching from one UI to another
  258.         self:tweenClose(OpenedUI)
  259.         OpenedUI = Canavs
  260.         self:tweenOpen(Canavs)
  261.     elseif OpenedUI == Canavs then -- UI is already open, so close it
  262.         OpenedUI = nil --closed opened UI so now no UI opened so make OpenedUI variable nil
  263.         self:tweenClose(Canavs)
  264.     end
  265. end
  266.  
  267. -- Applies hover/click effcts and manages showing/hiding UIs like Shop, Inventory, etc.
  268. function UserInterfaceController:AnimateUIs()
  269.     local UIButtons = player:WaitForChild("PlayerGui"):WaitForChild("Buttons")
  270.  
  271.     local Debounce = false -- Prevents spam clicking
  272.  
  273.     for i, button in pairs(UIButtons:GetChildren()) do
  274.         if not button:IsA("Frame") then continue end
  275.  
  276.         local Button = button:FindFirstChildOfClass("TextButton") -- Find the clickable button
  277.         if not Button then continue end
  278.  
  279.         local originalSize = button.Size
  280.         local FrameName = self:getNameAfterRemovingButton(button.Name) -- Remove "Button" suffix
  281.         local Frame = player.PlayerGui:FindFirstChild(FrameName) --get the frame with the given value after removing "Button" suffix
  282.         if not Frame then continue end
  283.  
  284.         local isModes = Frame.Name == "Modes"
  285.         local Canavs = Frame:FindFirstChild(isModes and "Frame" or "Canvas")
  286.         local CloseButton = isModes and Frame.Frame:FindFirstChild("Close") or (Canavs and Canavs:FindFirstChild("Container") and Canavs.Container:FindFirstChild("Main") and Canavs.Container.Main:FindFirstChild("Close"))
  287.  
  288.         if not Canavs or not CloseButton then continue end
  289.  
  290.         -- Hover event
  291.         button.MouseEnter:Connect(function()
  292.             self:onHover(button, originalSize)
  293.         end)
  294.  
  295.         -- Unhover event
  296.         button.MouseLeave:Connect(function()
  297.             self:onUnhover(button, originalSize)
  298.         end)
  299.  
  300.         -- Button click (open/close logic)
  301.         Button.MouseButton1Click:Connect(function()
  302.             if Debounce then return end
  303.             Debounce = true
  304.             self:onClick(button, originalSize)
  305.             self:handleUIState(Canavs)
  306.             task.delay(0.3, function()
  307.                 Debounce = false
  308.             end)
  309.         end)
  310.  
  311.         -- Close button logic/closes the opened UI
  312.         CloseButton.MouseButton1Click:Connect(function()
  313.             if Debounce then return end
  314.             Debounce = true
  315.             OpenedUI = nil
  316.             --Closes UI with tween
  317.             self:tweenClose(Canavs)
  318.             -- Reset camera FOV and continblur
  319.             task.delay(0.3, function()
  320.                 Debounce = false
  321.             end)
  322.         end)
  323.     end
  324. end
  325.  
  326. function UserInterfaceController:PromptPurchase(ClickedButtonName)
  327.     if ClickedButtonName == "EliminatePlayers" then
  328.         MPS:PromptProductPurchase(player, Products.EliminatePlayers)
  329.     elseif ClickedButtonName == "SpeedTroll" then
  330.         MPS:PromptProductPurchase(player, Products.SpeedTroll)
  331.     elseif ClickedButtonName == "KillRandomPersonTroll" then
  332.         MPS:PromptProductPurchase(player, Products.KillRandomPersonTroll)
  333.     elseif ClickedButtonName == "TakeCoinsTroll" then
  334.         MPS:PromptProductPurchase(player, Products.TakeCoinsTroll)
  335.     elseif ClickedButtonName == "Push1" then
  336.         MPS:PromptProductPurchase(player, PushProducts.Push1)
  337.     elseif ClickedButtonName == "Push2" then
  338.         MPS:PromptProductPurchase(player, PushProducts.Push2)
  339.     elseif ClickedButtonName == "Push5" then
  340.         MPS:PromptProductPurchase(player, PushProducts.Push5)
  341.     elseif ClickedButtonName == "Push7" then
  342.         MPS:PromptProductPurchase(player, PushProducts.Push7)
  343.     elseif ClickedButtonName == "Push10" then
  344.         MPS:PromptProductPurchase(player, PushProducts.Push10)
  345.     end
  346. end
  347.  
  348. --Handles working of troll UI
  349. function UserInterfaceController:TrollUI()
  350.     -- Loop through each troll button (ImageButton inside Main Container)
  351.     for i, trolls in pairs(TrollUI.Canvas.Container.Main.Container:GetChildren()) do
  352.         if not trolls:IsA("ImageButton") then return end
  353.         trolls.MouseEnter:Connect(function() -- When hovered, add purple UIStroke around "Default" image
  354.             self:HandleUIStroke("Add", trolls:FindFirstChild("Default"))
  355.         end)
  356.  
  357.         -- Remove stroke on mouse leave
  358.         trolls.MouseLeave:Connect(function()
  359.             self:HandleUIStroke("Remove")
  360.         end)
  361.  
  362.         -- Refrence to the buy button inside Equipped or Default
  363.         local BuyButton:ImageButton = trolls.Equipped:FindFirstChild("Buy") or trolls.Default:FindFirstChild("Buy")
  364.  
  365.         -- When clicked, trigger Marketplace purchase for selected troll type
  366.         BuyButton.MouseButton1Click:Connect(function()
  367.             local ClickedTrollName = BuyButton.Parent.Parent.Name
  368.             self:PromptPurchase(ClickedTrollName)
  369.         end)
  370.     end
  371. end
  372.  
  373.  
  374.  
  375. function UserInterfaceController:PushIUI()
  376.  
  377.     -- Loop through each push product (Push1, Push2, etc.)
  378.     for i, button in pairs(PushUI.Canvas.Container.Main.Container:GetChildren()) do
  379.         if not button:IsA("ImageButton") then return end
  380.         button.MouseEnter:Connect(function()-- Same hover stroke logic as TrollUI
  381.             self:HandleUIStroke("Add", button:FindFirstChild("Default"))
  382.         end)
  383.  
  384.         button.MouseLeave:Connect(function()
  385.             self:HandleUIStroke("Remove")
  386.         end)
  387.  
  388.         -- Find Buy button
  389.         local BuyButton:ImageButton = button.Equipped:FindFirstChild("Buy") or button.Default:FindFirstChild("Buy")
  390.  
  391.         -- Trigger MarketplaceService purchase when clickedcont
  392.         BuyButton.MouseButton1Click:Connect(function()
  393.             local ClickedButtonName = BuyButton.Parent.Parent.Name
  394.             self:PromptPurchase(ClickedButtonName)
  395.         end)
  396.     end
  397. end
  398.  
  399. function UserInterfaceController:applyTabStyle(activeBtn, inactive1, inactive2) --Function to switch between tabs
  400.     activeBtn.BackgroundColor3 = Color3.fromRGB(255, 255, 255) --Changing the current selected tab button color to white
  401.     activeBtn:FindFirstChild("UIGradient").Enabled = true  --Appling UIGradient to the selected tab button
  402.     activeBtn.Text.TextColor3 = Color3.new(255, 255, 255) --Changing the current selected tab text color to white
  403.  
  404.     inactive1.BackgroundColor3 = Color3.fromRGB(31, 31, 31) --Changing the inactive/non-selected tab button color to black
  405.     inactive1:FindFirstChild("UIGradient").Enabled = false --Removing UIGradient effect from the non-selected tab button
  406.     inactive1.Text.TextColor3 = Color3.new(113, 113, 113) --Changing the non-selected tab text color to white
  407.  
  408.     inactive2.BackgroundColor3 = Color3.fromRGB(31, 31, 31) --Changing the inactive/non-selected tab button color to black
  409.     inactive2:FindFirstChild("UIGradient").Enabled = false --Removing UIGradient effect from the non-selected tab button
  410.     inactive2.Text.TextColor3 = Color3.new(113, 113, 113) --Changing the non-selected tab text color to white
  411. end
  412.  
  413. function UserInterfaceController:applyHoverEffect(button) --it appies effect to the template whenever mouse hover over and remove effect whenever mouse leave the button
  414.     button.MouseEnter:Connect(function()
  415.         self:HandleUIStroke("Add", button:FindFirstChild("Default"))
  416.     end)
  417.  
  418.     button.MouseLeave:Connect(function()
  419.         self:HandleUIStroke("Remove")
  420.     end)
  421. end
  422.  
  423. function UserInterfaceController:handleGamepassBuy(button) --Function to guess which gamepass prompt should popup
  424.     local name = button.Parent.Parent.Name
  425.     if name == "Coins2x" then
  426.         MPS:PromptGamePassPurchase(player, 1272744022)
  427.     elseif name == "Sprint" then
  428.         MPS:PromptGamePassPurchase(player, 1273130340)
  429.     elseif name == "RainbowNameTag" then
  430.         MPS:PromptGamePassPurchase(player, 1274510513)
  431.     end
  432. end
  433.  
  434. function UserInterfaceController:handleProductBuy(button) --Function to prompt product purchase
  435.     local name = button.Parent.Parent.Name
  436.     local ids = {
  437.         Coins50 = 3314212399,
  438.         Coins100 = 3314212620,
  439.         Coins300 = 3314213085,
  440.         Coins500 = 3314213295,
  441.         Coins1000 = 3314214142,
  442.     }
  443.     if ids[name] then
  444.         MPS:PromptProductPurchase(player, ids[name])
  445.     end
  446. end
  447.  
  448. --Defines a reusable function to process items inside a container e.g gamepass or product UI elements
  449. function UserInterfaceController:processContainer(container, handlerFunc)
  450.     for _, item in pairs(container:GetChildren()) do
  451.         if not item:IsA("ImageButton") then return end
  452.         self:applyHoverEffect(item) ---- Apply the hover effect logic
  453.         local BuyButton:ImageButton = item.Equipped:FindFirstChild("Buy") or item.Default:FindFirstChild("Buy") --Trying to find the 'Buy' button either inside Equipped or Default frame
  454.  
  455.         if BuyButton then --Condition to check If a valid BuyButton is found
  456.             handlerFunc(BuyButton) -- Execute the handler function/purchase logic depending on tab
  457.         end
  458.     end
  459. end
  460.  
  461. function UserInterfaceController:handleRobuxBuy(itemName) --if player don't have enough ingame money to buy specific gamepass/product then he can pay robux to buy it
  462.     local ids = {
  463.         ExtraLifes = 3314996213,
  464.         LessGravity = 3314996574,
  465.         NameTags = 3314996930,
  466.     }
  467.     if ids[itemName] then
  468.         MPS:PromptProductPurchase(player, ids[itemName])
  469.     end
  470. end
  471.  
  472.  
  473. local ClonedPopupUI
  474.  
  475. function UserInterfaceController:handleNotEnoughCoins(textLabel)
  476.     textLabel.Text = "Not Enough Coins!"
  477.     task.delay(2, function()
  478.         textLabel.Text = "Buy"
  479.     end)
  480. end
  481.  
  482. -- Function to handle NameTag purchase
  483. function UserInterfaceController:handleNameTagPurchase()
  484.     local NameTag = ReplicatedStorage.Assets:FindFirstChild("nametagui"):Clone()
  485.     MapHandlerService:GiveNameTags(player.PlayerGui.ColourWheelGui.ColourDisplay.BackgroundColor3)
  486.     player.PlayerGui.ColourWheelGui.Enabled = false
  487. end
  488.  
  489. -- Function to handle general item purchase
  490. function UserInterfaceController:handleItemPurchase(button)
  491.     local CloneTemplate = button.Parent.Parent:Clone()
  492.     CloneTemplate.Parent = InventoryUI.Canvas.Container.Main.Container
  493.     CloneTemplate.Default.Buy:Destroy()
  494. end
  495.  
  496. function UserInterfaceController:onYesButtonClick(button) --if player click yes and have enough money as well then it procceed with the purchase
  497.     local PlayerCoins = player:FindFirstChild("leaderstats"):WaitForChild("Coins")
  498.     if PlayerCoins and PlayerCoins.Value >= button.Cost.Value then
  499.         PlayerCoins.Value -= button.Cost.Value --deduct the cost of the purchase from player's coins
  500.  
  501.         if button.Parent.Parent.Name == "NameTags" then
  502.             self:handleNameTagPurchase()
  503.         else
  504.             self:handleItemPurchase(button)
  505.         end
  506.  
  507.         ClonedPopupUI:Destroy()
  508.     else
  509.         self:handleNotEnoughCoins()
  510.     end
  511. end
  512.  
  513. function UserInterfaceController:handlePopupBuy(button) --function to show popup UI whenever player clicks buy button so he can buy stuff cancel the purchase or buy it with robux
  514.     local PopupUI = player.PlayerGui.Popup -- Refrence to popup UI
  515.     ClonedPopupUI = PopupUI:Clone()
  516.     ClonedPopupUI.Parent = player.PlayerGui
  517.     ClonedPopupUI.Canvas.Visible = true
  518.  
  519.     if button.Parent.Parent.Name == "NameTags" then
  520.         player.PlayerGui.ColourWheelGui.Enabled = true
  521.     end
  522.  
  523.     ClonedPopupUI.Canvas.Main.YesButton.MouseButton1Click:Connect(function()
  524.         self:onYesButtonClick(button)
  525.     end)
  526.  
  527.     ClonedPopupUI.Canvas.Main.Closebutton.MouseButton1Click:Connect(function()
  528.         ClonedPopupUI:Destroy() --remove cloned popupUI uplon clicking the close button
  529.     end)
  530.  
  531.     ClonedPopupUI.Canvas.Main.Close.MouseButton1Click:Connect(function()
  532.         ClonedPopupUI:Destroy() --remove cloned popupUI uplon clicking the cancel button
  533.     end)
  534.  
  535.     ClonedPopupUI.Canvas.Main.BuyWithRobux.MouseButton1Click:Connect(function()
  536.         self:handleRobuxBuy(button.Parent.Parent.Name) --if player don't have enough in game coins then by clicking BuyWithRobux button player can purchase items with robux instead
  537.         ClonedPopupUI:Destroy()
  538.     end)
  539. end
  540.  
  541. function UserInterfaceController:ShopeUI()
  542.     local NavigationList = ShopUI.Canvas.Container.Navigation.List
  543.  
  544.     local GamepassButton = NavigationList.Gamepass
  545.     local DeveloperProductsButton = NavigationList.DeveloperProducts
  546.     local StoreButton = NavigationList.Store
  547.  
  548.     local Container1 = ShopUI.Canvas.Container.Main.Container1 -- Gamepasses Tab
  549.     local Container2 = ShopUI.Canvas.Container.Main.Container2 -- Dev Products Tab
  550.     local Container3 = ShopUI.Canvas.Container.Main.Container3 -- Store Items Tab
  551.  
  552.  
  553.     -- Gamepass tab button logic
  554.     GamepassButton.MouseButton1Click:Connect(function()
  555.         if Container2.Visible or Container3.Visible then
  556.             Container2.Visible = false -- Hide other tabs
  557.             Container3.Visible = false
  558.             Container1.Visible = true  -- Show gamepasses Tab
  559.             self:applyTabStyle(GamepassButton, DeveloperProductsButton, StoreButton)
  560.         end
  561.     end)
  562.  
  563.     --Developer Products tab Button logic
  564.     DeveloperProductsButton.MouseButton1Click:Connect(function()
  565.         if Container1.Visible or Container3.Visible then
  566.             Container1.Visible = false
  567.             Container3.Visible = false
  568.             Container2.Visible = true
  569.             self:applyTabStyle(DeveloperProductsButton, GamepassButton, StoreButton)
  570.         end
  571.     end)
  572.  
  573.     -- Store tab button logic
  574.     StoreButton.MouseButton1Click:Connect(function()
  575.         if Container1.Visible or Container2.Visible then
  576.             Container1.Visible = false
  577.             Container2.Visible = false
  578.             Container3.Visible = true
  579.             self:applyTabStyle(StoreButton, GamepassButton, DeveloperProductsButton)
  580.         end
  581.     end)
  582.  
  583.     self:processContainer(Container1, function(BuyButton) --Process all gamepass UI items in Container1 and attach gamepass buying logic to Buy button
  584.         BuyButton.MouseButton1Click:Connect(function() --Connecting the MouseButton1Click event to call the handleGamepassBuy function for gamepass purchase
  585.             self:handleGamepassBuy(BuyButton) --Calls the function that prompts the player to buy the associated gamepass
  586.         end)
  587.     end)
  588.  
  589.  
  590.     self:processContainer(Container2, function(BuyButton) --Process all developer product UI items in Container2 and attach product purchase logic to Buy button
  591.         BuyButton.MouseButton1Click:Connect(function() --Connecting the MouseButton1Click event to call the handleGamepassBuy function for product purchase
  592.             self:handleProductBuy(BuyButton) -- Calls the function that prompts the player to buy the associated developer product
  593.         end)
  594.     end)
  595.  
  596.     self:processContainer(Container3, function(BuyButton) --Process all store item UI elements in Container3 and attach custom popup handling to Buy button
  597.         BuyButton.MouseButton1Click:Connect(function() --Connecting the MouseButton1Click event to call the handleGamepassBuy function for store purchases
  598.             self:handlePopupBuy(BuyButton)--Calls the function that prompts the player to buy the associated item
  599.         end)
  600.     end)
  601. end
  602.  
  603. function UserInterfaceController:OnUseButtonClicked(SidePanel, SelectedChild)
  604.     if SidePanel.ItemName.Text == "ExtraLifes" then
  605.         MapHandlerService:ExtraLifes() --Calls "ExtraLifes" function from MapHandlerService (server) to give player extra lifes
  606.         SelectedChild:Destroy() -- Consume/Remove item
  607.         SidePanel.ImageLabel.Image = ""
  608.         SidePanel.ItemName.Text = "ItemName"
  609.         SidePanel.ItemDescription.Text = "ItemDescription"
  610.     elseif SidePanel.ItemName.Text == "LessGravity" then
  611.         MapHandlerService:LessGravity("IncreaseGravityValue") --Calls "LessGravity" function
  612.     end
  613. end
  614.  
  615. function UserInterfaceController:UpdateSidePanel(SelectedChild, child, SidePanel)
  616.     if SelectedChild or SelectedChild == child then return end
  617.     SelectedChild = child
  618.     UIStroke.Parent = child:FindFirstChild("Default")
  619.     -- Update side panel
  620.     SidePanel.ItemName.Text = child.Name
  621.     SidePanel.ImageLabel.Image = child.Default.ImageLabel.Image
  622.     SidePanel.ItemDescription.Text = child.Default.TextLabel.Text
  623. end
  624.  
  625. function UserInterfaceController:InventoryHandler()
  626.     local Container = InventoryUI.Canvas.Container.Main.Container -- refrence to hte frame that holds item buttons
  627.     local SidePanel = InventoryUI.Canvas.Container.Main.SidePanel -- refrence to the frame that shows selected item details
  628.  
  629.     local SelectedChild = nil -- Currently selected item
  630.  
  631.     -- Setup UIStroke for selection outline
  632.     local UIStroke = Instance.new("UIStroke")
  633.     UIStroke.Parent = nil
  634.     UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
  635.     UIStroke.Color = Color3.fromRGB(126, 36, 233)
  636.     UIStroke.Thickness = 2
  637.  
  638.     -- Use button logic
  639.     SidePanel.Use.MouseButton1Click:Connect(function()
  640.         self:OnUseButtonClicked(SidePanel, SelectedChild, SidePanel)
  641.     end)
  642.  
  643.     -- When new item added to inventory
  644.     Container.ChildAdded:Connect(function(child:ImageButton)
  645.         child.MouseButton1Click:Connect(function()
  646.             self:UpdateSidePanel(SelectedChild, child)
  647.         end)
  648.     end)
  649. end
  650.  
  651. -- Format seconds into MM:SS format
  652. function UserInterfaceController:FormatTime(seconds)
  653.     seconds = math.max(0, math.floor(seconds))
  654.  
  655.     local minutes = math.floor(seconds / 60)
  656.     local secs = seconds % 60
  657.  
  658.     return string.format("%02d:%02d", minutes, secs)
  659. end
  660.  
  661. -- Unlock times for rewards (in seconds)
  662. local TimeToUnlock = {
  663.     Reward1 = 5 * 60,
  664.     Reward2 = 10 * 60,
  665.     Reward3 = 15 * 60,
  666.     Reward4 = 20 * 60,
  667.     Reward5 = 25 * 60,
  668.     Reward6 = 30 * 60,
  669.     Reward7 = 35 * 60,
  670. }
  671.  
  672. function UserInterfaceController:UpdateRewardTimer(StartTime)
  673.     for _, rewards in pairs(RewardUI.Canvas.Container.Main.Container:GetChildren()) do
  674.         if not rewards:IsA("ImageButton") then continue end
  675.  
  676.         if rewards.Equipped.TextLabel.Text == "Unlock in: 00:00" then continue end -- if timer is already 0 then it prevents running the below code without disturbing the loop
  677.  
  678.         rewards.Equipped.TextLabel.Text = "Unlock in: " .. self:FormatTime(TimeToUnlock[rewards.Name] - (tick() - StartTime)) --Update the rewards time after formating seconds into MM:SS format
  679.  
  680.         if rewards.Equipped.TextLabel.Text ~= "Unlock in: 00:00" then continue end --if timer is reached 0 sec it changes rewards button text to equip
  681.         rewards.Equipped.Buy.Backing.Text.Text = "Equip"
  682.     end
  683. end
  684.  
  685. function UserInterfaceController:OnEquipButtonClicK(EquipButton, Rewards)
  686.     if EquipButton.Backing.Text.Text == "Locked yet!" then return end --if item is currently lock then stop execution of event immediately
  687.  
  688.     --if player has already equipped item then unEquip it
  689.     if EquipButton.Backing.Text.Text == "Unequip" then
  690.         local Success, errorMessage = MapHandlerService:WearBrainRot(Rewards:FindFirstChild("AssetId").Value, Rewards) --Fires server to make put brainrot on player sure after putting brainrot on player it is visible to everyone
  691.         if not Success then return end --if everything goes well then it changes button text to Equip
  692.         EquipButton.Backing.Text.Text = "Equip"
  693.         return
  694.     end
  695.  
  696.     --if player has not equipped item then equip it
  697.     local Success, errorMessage = MapHandlerService:WearBrainRot(Rewards:FindFirstChild("AssetId").Value, "Wear", Rewards)
  698.     if not Success then return end
  699.     EquipButton.Backing.Text.Text = "Unequip"
  700. end
  701.  
  702. function UserInterfaceController:RewardUI()
  703.  
  704.     local StartTime = tick() --returns the number of seconds since January 1st, 1970 UTC, useful for time elapsed calculations
  705.  
  706.     -- Update timer every second
  707.     while task.wait(1) do
  708.         task.spawn(self:UpdateRewardTimer(StartTime))
  709.     end
  710.  
  711.     --loop through all the rewards available in reward UI container/scrolling Frame
  712.     for _, Rewards in pairs(RewardUI.Canvas.Container.Main.Container:GetChildren()) do
  713.         if not Rewards:IsA("ImageButton") then continue end
  714.  
  715.         Rewards.MouseEnter:Connect(function() --apply Hover effect whenever mouse hovers over the button
  716.             self:HandleUIStroke("Add", Rewards:FindFirstChild("Default"))
  717.         end)
  718.  
  719.         --remove UIStroke after player mouse leaves the button
  720.         Rewards.MouseLeave:Connect(function()
  721.             self:HandleUIStroke("Remove")
  722.         end)
  723.  
  724.         local EquipButton:ImageButton = Rewards.Equipped:FindFirstChild("Buy") or Rewards.Default:FindFirstChild("Buy") --refrence to buy button
  725.  
  726.         local EquippedHat --last equipped Hat accessory
  727.         local EquippedNeck --Last equipped neck accessory
  728.         local EquippedFace --last equipped fconace accessory
  729.  
  730.         --handles equip button logic
  731.         EquipButton.MouseButton1Click:Connect(function()
  732.             self:OnEquipButtonClicK(EquipButton, Rewards)
  733.         end)
  734.     end
  735. end
  736.  
  737. function UserInterfaceController:HideGivenCharacter(char, turningOff)
  738.     for _, child in pairs(char:GetDescendants()) do
  739.         --This condition will only execute if the child is a type of "BasePart" Or "MeshPart" or "Decal"
  740.         if not (child:IsA("MeshPart") or child:IsA("BasePart") or child:IsA("Decal")) then continue end
  741.         if child.Name == "HumanoidRootPart" then continue end
  742.  
  743.         child.Transparency = turningOff and 0 or 1 -- Hide or show the bodyparts of player character
  744.     end
  745. end
  746.  
  747. function UserInterfaceController:ManagePlayersInvisiblity(turningOff)
  748.     -- Loop through all other players
  749.     for _, Player in pairs(game.Players:GetPlayers()) do
  750.         if Player == player then continue end
  751.  
  752.         local char = Player.Character
  753.         if not char then continue end
  754.         self:HideGivenCharacter(char, turningOff)
  755.     end
  756. end
  757.  
  758. --handles logics of setting UI
  759. function UserInterfaceController:SettignsUI()
  760.     for _, Settings in pairs(SettingsUI.Canvas.Container.Main.Container:GetChildren()) do
  761.         if not Settings:IsA("ImageLabel") then continue end
  762.  
  763.         local ToggleButton = Settings:FindFirstChild("ToggleButton")
  764.         if not ToggleButton then continue end
  765.  
  766.  
  767.         ToggleButton.MouseButton1Click:Connect(function() --Event which runs upon toggle button is clicked using left mouse button
  768.             -- Determine toggle state
  769.             local turningOff = Settings.Background.Toggle.ActiveFrame.Visible == true
  770.  
  771.             Settings.Background.Toggle.ActiveFrame.Visible = not turningOff
  772.             Settings.Background.Toggle.InactiveFrame.Visible = turningOff
  773.  
  774.             self:ManagePlayersInvisiblity(turningOff)
  775.         end)
  776.     end
  777. end
  778.  
  779.  
  780.  
  781.  
  782. function UserInterfaceController:KnitInit()
  783.     MapHandlerService = Knit.GetService("MapHandlerService") -- Fetch server-side service
  784.  
  785.     -- Init all UI features
  786.     self:TrollUI()
  787.     self:PushIUI()
  788.     self:AnimateUIs()
  789.     self:SettignsUI()
  790.     self:ShopeUI()
  791.     self:RewardUI()
  792.     self:InventoryHandler()
  793.  
  794.     -- Show round countdown
  795.     MapHandlerService.Timer:Connect(function()
  796.         self:BackTimer()
  797.     end)
  798.  
  799.     -- Display a center-screen message from the server
  800.     MapHandlerService.Message:Connect(function(Message)
  801.         self:ShowMessage(Message)
  802.     end)
  803.  
  804.     -- Rope animation controller from server
  805.     MapHandlerService.AnimateRopes:Connect(function(serverStartTime, Mode)
  806.         self:startAnimationWhenReady(serverStartTime, Mode)
  807.     end)
  808. end
  809.  
  810. return UserInterfaceController
Tags: #apply
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement