Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Squid Game User Interface Controller
- Handles shop UI, reward UI, tool activation, gamepasses, animations, and GUI interaction logic using Knit framework.
- ]]
- --by the_king_here
- --//SERVICES
- local ReplicatedStorage = game:GetService("ReplicatedStorage")
- local Knit = require(ReplicatedStorage.Packages.Knit)
- local TweenService = game:GetService("TweenService")
- local runService = game:GetService("RunService")
- local MPS = game:GetService("MarketplaceService")
- local LightningService = game:GetService("Lighting")
- local SoundService = game:GetService("SoundService")
- --TweenInfo config for UI transitions (0.3s, Back Out easing)
- local tweenInfoUI = TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.Out, 0)
- -- Creating a Knit Controller
- local UserInterfaceController = Knit.CreateController{
- Name = "UserInterface",
- }
- -- Will store reference to the server side service later
- local MapHandlerService
- -- Reference to the local player
- local player = game.Players.LocalPlayer
- -- Control module to disable movement during certain actions
- local Controls = require(player.PlayerScripts.PlayerModule):GetControls()
- -- UI References in PlayerGui
- local TrollUI = player.PlayerGui:WaitForChild("Troll")
- local PushUI = player.PlayerGui:WaitForChild("PushUI")
- local SettingsUI = player.PlayerGui:WaitForChild("Settings")
- local ShopUI = player.PlayerGui:WaitForChild("Shop")
- local InventoryUI = player.PlayerGui:WaitForChild("Inventory")
- local RewardUI = player.PlayerGui:WaitForChild("Reward")
- -- Music References
- local BackgroundMusic = SoundService:WaitForChild("LobbyMusic")
- local SquidMusic = SoundService:WaitForChild("Music")
- -- Developer product IDs
- local Products = {
- EliminatePlayers = 3312415657,
- SpeedTroll = 3312416017,
- KillRandomPersonTroll = 3312444642,
- TakeCoinsTroll = 3312417586,
- }
- -- Push upgrades (more force or quantity)
- local PushProducts = {
- Push1 = 3313283431,
- Push2 = 3313283430,
- Push5 = 3313283433,
- Push7 = 3313283424,
- Push10 = 3313286623,
- }
- -- Tweening for background music transitions
- local tweenInfoForMusic = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0)
- -- Reference to the camera for FOV changes
- local camera = workspace.CurrentCamera
- -- Blur effect (GUI background blur)
- local Blur = LightningService:FindFirstChild("BlurForGui")
- -- For rope animation disconnecting later
- local RopeAnimationConnection
- -- Countdown before round starts (e.g., "3, 2, 1... Run!")
- function UserInterfaceController:BackTimer(StartTime, EndTime, UIToShowTime)
- for i = StartTime, EndTime, -1 do
- wait(1)
- player.PlayerGui:WaitForChild("Timer").TextLabel.Visible = true
- player.PlayerGui.Timer.TextLabel.Text = i --Displays time on textlabel
- player.PlayerGui.Timer.TextLabel.TimerSound:Play() --plays timer sound every second
- if i == 0 then
- wait(1)
- player.PlayerGui.Timer.TextLabel.Text = "Run!" -- Final message
- task.delay(1.5, function()
- player.PlayerGui.Timer.TextLabel.Visible = false
- end)
- end
- end
- end
- -- Displays a short message on screen (centered label) for 3 seconds
- function UserInterfaceController:ShowMessage(Message)
- player.PlayerGui:WaitForChild("Timer").TextLabel.Visible = true
- player.PlayerGui.Timer.TextLabel.Text = Message
- task.delay(3, function()
- player.PlayerGui.Timer.TextLabel.Visible = false
- end)
- end
- local Rope -- rope part reference (used in Easy or Hard maps)
- local maxSpeed -- max angular speed in radians/sec
- local accelTime = 3 -- how long to accelerate (ease in) in seconds
- local animationStarted = false -- variable to check if animation has started
- local animationStartTime = nil -- server-synced time when animation begins
- local initialCFrame -- store original rope CFrame
- -- Begins rope rotation animation based on server time
- function UserInterfaceController:startAnimationWhenReady(serverStartTime, Mode)
- -- Decide map + speed based on mode
- if Mode == "Easy" then
- maxSpeed = math.rad(210) -- degrees to radians
- Rope = workspace.Maps.EasyRopemap:WaitForChild("rope")
- else
- maxSpeed = math.rad(250)
- Rope = workspace.Maps.HadRopeMap:WaitForChild("rope")
- end
- local primary = Rope.PrimaryPart --Stores refrence to rope primaryPart
- initialCFrame = primary.CFrame -- store starting position
- animationStartTime = serverStartTime
- animationStarted = false
- Controls:Disable() -- Disable player movement during pre rope animation
- -- If player has LessGravity effect, set gravity to 70
- local LessGravity = player:FindFirstChild("LessGravity")
- if LessGravity.Value > 0 then
- MapHandlerService:LessGravity("DecreaseGravityValue")
- workspace.Gravity = 70
- end
- local IsEnabledControls = false --keep track whether controls of player has been restored or not
- -- Connect to RenderStepped to animate rope every frame
- RopeAnimationConnection = runService.RenderStepped:Connect(function()
- local now = workspace:GetServerTimeNow() --get current time
- -- Wait until server-synced animation time
- if not animationStarted and now >= animationStartTime then
- animationStarted = true
- end
- if not animationStarted then return end
- -- Enable player controls 1 second after rope starts
- if not IsEnabledControls then
- IsEnabledControls = true
- task.delay(1, function()
- Controls:Enable()
- end)
- end
- local elapsed = now - animationStartTime -- how long since animation began
- local rotation --Stores rotation value
- -- Accelerate with cubic easing for first 3 seconds
- if elapsed < accelTime then
- local progress = elapsed / accelTime
- rotation = 0.33 * maxSpeed * (progress ^ 3) * accelTime
- else
- -- Maintain constant speed after acceleration phase
- local constantTime = elapsed - accelTime
- rotation = 0.33 * maxSpeed * accelTime + maxSpeed * constantTime
- end
- -- Rotate rope by X-axis only
- local newCFrame = initialCFrame * CFrame.Angles(rotation, 0, 0)
- Rope:PivotTo(newCFrame)
- end)
- end
- --returns name after removing text "button" from name if name contains text "Button"
- function UserInterfaceController:getNameAfterRemovingButton(name)
- local suffix = "Button"
- if name:sub(-#suffix) == suffix then
- return name:sub(1, -#suffix - 1)
- else
- return name
- end
- end
- local originalRotation = 0 --Stoers default rotation, which is usually 0
- -- function to scale UDim2 (used to make buttons shrink or grow)
- function UserInterfaceController:scaleSize(size: UDim2, scale: number): UDim2
- return UDim2.new(
- size.X.Scale * scale, size.X.Offset * scale,
- size.Y.Scale * scale, size.Y.Offset * scale
- )
- end
- -- When mouse enters button (hover), enlarge slightly + rotate
- function UserInterfaceController:onHover(button, originalSize)
- local hoverTween = TweenService:Create(button, TweenInfo.new(0.1), {
- Size = self:scaleSize(originalSize, 1.1),
- Rotation = 5,
- })
- hoverTween:Play()
- end
- -- When mouse leaves button, restore size and rotation
- function UserInterfaceController:onUnhover(button, originalSize)
- local unhoverTween = TweenService:Create(button, TweenInfo.new(0.1), {
- Size = originalSize,
- Rotation = originalRotation,
- })
- unhoverTween:Play()
- end
- -- When button is clicked, shrink quickly then bounce back
- function UserInterfaceController:onClick(button, originalSize)
- local shrinkTween = TweenService:Create(button, TweenInfo.new(0.05), {
- Size = self:scaleSize(originalSize, 0.8),
- })
- local restoreTween = TweenService:Create(button, TweenInfo.new(0.1), {
- Size = originalSize,
- })
- shrinkTween:Play()
- shrinkTween.Completed:Connect(function()
- restoreTween:Play()
- end)
- end
- local OpenedUI -- Tracks which UI is currently open
- -- Applies hover/click effcts and manages showing/hiding UIs like Shop, Inventory, etc.
- function UserInterfaceController:AnimateUIs()
- local UIButtons = player:WaitForChild("PlayerGui"):WaitForChild("Buttons")
- local Debounce = false -- Prevents spam clicking
- local function tweenOpen(Canavs) --Function to open UI with tween/animation
- Canavs.Visible = true
- Canavs.Position = UDim2.new(0.5, 0, 1.5, 0)
- Canavs:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 0.3) --Animating the position of the UI
- TweenService:Create(camera, tweenInfoUI, {FieldOfView = 100}):Play() --Increasing FOV with animation to give overall animation better look
- TweenService:Create(Blur, tweenInfoUI, {Size = 20}):Play() --Applying blur with animation
- end
- local function tweenClose(Canavs) --function to close UI with tween/animation
- Canavs:TweenPosition(UDim2.new(0.5, 0, 1.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 0.3)
- TweenService:Create(camera, tweenInfoUI, {FieldOfView = 70}):Play()
- TweenService:Create(Blur, tweenInfoUI, {Size = 0}):Play()
- end
- local function handleUIState(Canavs)
- if not OpenedUI then -- No UI open yet
- OpenedUI = Canavs --Defines the current open UI
- tweenOpen(Canavs)
- elseif OpenedUI and OpenedUI ~= Canavs then-- Switching from one UI to another
- tweenClose(OpenedUI)
- OpenedUI = Canavs
- tweenOpen(Canavs)
- elseif OpenedUI == Canavs then -- UI is already open, so close it
- OpenedUI = nil --closed opened UI so now no UI opened so make OpenedUI variable nil
- tweenClose(Canavs)
- end
- task.delay(0.3, function()
- Debounce = false
- end)
- end
- for i, button in pairs(UIButtons:GetChildren()) do
- if not button:IsA("Frame") then continue end
- local Button = button:FindFirstChildOfClass("TextButton") -- Find the clickable button
- if not Button then continue end
- local originalSize = button.Size
- local FrameName = self:getNameAfterRemovingButton(button.Name) -- Remove "Button" suffix
- local Frame = player.PlayerGui:FindFirstChild(FrameName) --get the frame with the given value after removing "Button" suffix
- if not Frame then continue end
- local isModes = Frame.Name == "Modes"
- local Canavs = Frame:FindFirstChild(isModes and "Frame" or "Canvas")
- 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"))
- if not Canavs or not CloseButton then continue end
- -- Hover event
- button.MouseEnter:Connect(function()
- self:onHover(button, originalSize)
- end)
- -- Unhover event
- button.MouseLeave:Connect(function()
- self:onUnhover(button, originalSize)
- end)
- -- Button click (open/close logic)
- Button.MouseButton1Click:Connect(function()
- if Debounce then return end
- Debounce = true
- self:onClick(button, originalSize)
- handleUIState(Canavs)
- end)
- -- Close button logic/closes the opened UI
- CloseButton.MouseButton1Click:Connect(function()
- if Debounce then return end
- Debounce = true
- OpenedUI = nil
- --Closes UI with tween
- tweenClose(Canavs)
- -- Reset camera FOV and continblur
- task.delay(0.3, function()
- Debounce = false
- end)
- end)
- end
- end
- --Handles working of troll UI
- function UserInterfaceController:TrollUI()
- local UIStroke
- -- Loop through each troll button (ImageButton inside Main Container)
- for i, trolls in pairs(TrollUI.Canvas.Container.Main.Container:GetChildren()) do
- if not trolls:IsA("ImageButton") then return end
- trolls.MouseEnter:Connect(function() -- When hovered, add purple UIStroke around "Default" image
- if not UIStroke then
- UIStroke = Instance.new("UIStroke")
- UIStroke.Parent = trolls:FindFirstChild("Default")
- UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
- UIStroke.Color = Color3.fromRGB(126, 36, 233)
- UIStroke.Thickness = 2
- else
- UIStroke.Parent = trolls:FindFirstChild("Default")
- end
- end)
- -- Remove stroke on mouse leave
- trolls.MouseLeave:Connect(function()
- UIStroke.Parent = nil
- end)
- -- Refrence to the buy button inside Equipped or Default
- local BuyButton:ImageButton = trolls.Equipped:FindFirstChild("Buy") or trolls.Default:FindFirstChild("Buy")
- -- When clicked, trigger Marketplace purchase for selected troll type
- BuyButton.MouseButton1Click:Connect(function()
- local ClickedTrollName = BuyButton.Parent.Parent.Name
- if ClickedTrollName == "EliminatePlayers" then
- MPS:PromptProductPurchase(player, Products.EliminatePlayers)
- elseif ClickedTrollName == "SpeedTroll" then
- MPS:PromptProductPurchase(player, Products.SpeedTroll)
- elseif ClickedTrollName == "KillRandomPersonTroll" then
- MPS:PromptProductPurchase(player, Products.KillRandomPersonTroll)
- elseif ClickedTrollName == "TakeCoinsTroll" then
- MPS:PromptProductPurchase(player, Products.TakeCoinsTroll)
- end
- end)
- end
- end
- function UserInterfaceController:PushIUI()
- local UIStroke
- -- Loop through each push product (Push1, Push2, etc.)
- for i, trolls in pairs(PushUI.Canvas.Container.Main.Container:GetChildren()) do
- if not trolls:IsA("ImageButton") then return end
- trolls.MouseEnter:Connect(function()-- Same hover stroke logic as TrollUI
- if not UIStroke then
- UIStroke = Instance.new("UIStroke")
- UIStroke.Parent = trolls:FindFirstChild("Default")
- UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
- UIStroke.Color = Color3.fromRGB(126, 36, 233)
- UIStroke.Thickness = 2
- else
- UIStroke.Parent = trolls:FindFirstChild("Default")
- end
- end)
- trolls.MouseLeave:Connect(function()
- UIStroke.Parent = nil
- end)
- -- Find Buy button
- local BuyButton:ImageButton = trolls.Equipped:FindFirstChild("Buy") or trolls.Default:FindFirstChild("Buy")
- -- Trigger MarketplaceService purchase when clickedcont
- BuyButton.MouseButton1Click:Connect(function()
- local ClickedButtonName = BuyButton.Parent.Parent.Name
- if ClickedButtonName == "Push1" then
- MPS:PromptProductPurchase(player, PushProducts.Push1)
- elseif ClickedButtonName == "Push2" then
- MPS:PromptProductPurchase(player, PushProducts.Push2)
- elseif ClickedButtonName == "Push5" then
- MPS:PromptProductPurchase(player, PushProducts.Push5)
- elseif ClickedButtonName == "Push7" then
- MPS:PromptProductPurchase(player, PushProducts.Push7)
- elseif ClickedButtonName == "Push10" then
- MPS:PromptProductPurchase(player, PushProducts.Push10)
- end
- end)
- end
- end
- local ClonedPopupUI
- function UserInterfaceController:ShopeUI()
- local UIStroke
- local NavigationList = ShopUI.Canvas.Container.Navigation.List
- local PopupUI = player.PlayerGui.Popup -- Refrence to popup UI
- local GamepassButton = NavigationList.Gamepass
- local DeveloperProductsButton = NavigationList.DeveloperProducts
- local StoreButton = NavigationList.Store
- local Container1 = ShopUI.Canvas.Container.Main.Container1 -- Gamepasses Tab
- local Container2 = ShopUI.Canvas.Container.Main.Container2 -- Dev Products Tab
- local Container3 = ShopUI.Canvas.Container.Main.Container3 -- Store Items Tab
- local function applyTabStyle(activeBtn, inactive1, inactive2) --Function to switch between tabs
- activeBtn.BackgroundColor3 = Color3.fromRGB(255, 255, 255) --Changing the current selected tab button color to white
- activeBtn:FindFirstChild("UIGradient").Enabled = true --Appling UIGradient to the selected tab button
- activeBtn.Text.TextColor3 = Color3.new(255, 255, 255) --Changing the current selected tab text color to white
- inactive1.BackgroundColor3 = Color3.fromRGB(31, 31, 31) --Changing the inactive/non-selected tab button color to black
- inactive1:FindFirstChild("UIGradient").Enabled = false --Removing UIGradient effect from the non-selected tab button
- inactive1.Text.TextColor3 = Color3.new(113, 113, 113) --Changing the non-selected tab text color to white
- inactive2.BackgroundColor3 = Color3.fromRGB(31, 31, 31) --Changing the inactive/non-selected tab button color to black
- inactive2:FindFirstChild("UIGradient").Enabled = false --Removing UIGradient effect from the non-selected tab button
- inactive2.Text.TextColor3 = Color3.new(113, 113, 113) --Changing the non-selected tab text color to white
- end
- local function applyHoverEffect(button) --it appies effect to the template whenever mouse hover over and remove effect whenever mouse leave the button
- button.MouseEnter:Connect(function()
- if not UIStroke then
- UIStroke = Instance.new("UIStroke")
- UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
- UIStroke.Color = Color3.fromRGB(126, 36, 233)
- UIStroke.Thickness = 2
- end
- UIStroke.Parent = button:FindFirstChild("Default")
- end)
- button.MouseLeave:Connect(function()
- UIStroke.Parent = nil
- end)
- end
- local function handleGamepassBuy(button) --Function to guess which gamepass prompt should popup
- local name = button.Parent.Parent.Name
- if name == "Coins2x" then
- MPS:PromptGamePassPurchase(player, 1272744022)
- elseif name == "Sprint" then
- MPS:PromptGamePassPurchase(player, 1273130340)
- elseif name == "RainbowNameTag" then
- MPS:PromptGamePassPurchase(player, 1274510513)
- end
- end
- local function handleProductBuy(button) --Function to prompt product purchase
- local name = button.Parent.Parent.Name
- local ids = {
- Coins50 = 3314212399,
- Coins100 = 3314212620,
- Coins300 = 3314213085,
- Coins500 = 3314213295,
- Coins1000 = 3314214142,
- }
- if ids[name] then
- MPS:PromptProductPurchase(player, ids[name])
- end
- end
- local function handleRobuxBuy(itemName) --if player don't have enough ingame money to buy specific gamepass/product then he can pay robux to buy it
- local ids = {
- ExtraLifes = 3314996213,
- LessGravity = 3314996574,
- NameTags = 3314996930,
- }
- if ids[itemName] then
- MPS:PromptProductPurchase(player, ids[itemName])
- end
- end
- local function 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
- ClonedPopupUI = PopupUI:Clone()
- ClonedPopupUI.Parent = player.PlayerGui
- ClonedPopupUI.Canvas.Visible = true
- if button.Parent.Parent.Name == "NameTags" then
- player.PlayerGui.ColourWheelGui.Enabled = true
- end
- ClonedPopupUI.Canvas.Main.YesButton.MouseButton1Click:Connect(function()
- local PlayerCoins = player:FindFirstChild("leaderstats"):WaitForChild("Coins")
- if PlayerCoins and PlayerCoins.Value >= button.Cost.Value then
- PlayerCoins.Value -= button.Cost.Value
- if button.Parent.Parent.Name == "NameTags" then
- local NameTag = ReplicatedStorage.Assets:FindFirstChild("nametagui"):Clone()
- MapHandlerService:GiveNameTags(player.PlayerGui.ColourWheelGui.ColourDisplay.BackgroundColor3)
- player.PlayerGui.ColourWheelGui.Enabled = false
- else
- local CloneTemplate = button.Parent.Parent:Clone()
- CloneTemplate.Parent = InventoryUI.Canvas.Container.Main.Container
- CloneTemplate.Default.Buy:Destroy()
- end
- ClonedPopupUI:Destroy()
- else
- ClonedPopupUI.Canvas.Main.YesButton.Main.TextLabel.Text = "Not Enough Coins!"
- task.delay(2, function()
- ClonedPopupUI.Canvas.Main.YesButton.Main.TextLabel.Text = "Buy"
- end)
- end
- end)
- ClonedPopupUI.Canvas.Main.Closebutton.MouseButton1Click:Connect(function()
- ClonedPopupUI:Destroy()
- end)
- ClonedPopupUI.Canvas.Main.Close.MouseButton1Click:Connect(function()
- ClonedPopupUI:Destroy()
- end)
- ClonedPopupUI.Canvas.Main.BuyWithRobux.MouseButton1Click:Connect(function()
- handleRobuxBuy(button.Parent.Parent.Name)
- end)
- end
- -- Gamepass tab button logic
- GamepassButton.MouseButton1Click:Connect(function()
- if Container2.Visible or Container3.Visible then
- Container2.Visible = false -- Hide other tabs
- Container3.Visible = false
- Container1.Visible = true -- Show gamepasses Tab
- applyTabStyle(GamepassButton, DeveloperProductsButton, StoreButton)
- end
- end)
- --Developer Products tab Button logic
- DeveloperProductsButton.MouseButton1Click:Connect(function()
- if Container1.Visible or Container3.Visible then
- Container1.Visible = false
- Container3.Visible = false
- Container2.Visible = true
- applyTabStyle(DeveloperProductsButton, GamepassButton, StoreButton)
- end
- end)
- -- Store tab button logic
- StoreButton.MouseButton1Click:Connect(function()
- if Container1.Visible or Container2.Visible then
- Container1.Visible = false
- Container2.Visible = false
- Container3.Visible = true
- applyTabStyle(StoreButton, GamepassButton, DeveloperProductsButton)
- end
- end)
- --Defines a reusable function to process items inside a container e.g gamepass or product UI elements
- local function processContainer(container, handlerFunc)
- for _, item in pairs(container:GetChildren()) do
- if not item:IsA("ImageButton") then return end
- applyHoverEffect(item) ---- Apply the hover effect logic
- local BuyButton:ImageButton = item.Equipped:FindFirstChild("Buy") or item.Default:FindFirstChild("Buy") --Trying to find the 'Buy' button either inside Equipped or Default frame
- if BuyButton then --Condition to check If a valid BuyButton is found
- handlerFunc(BuyButton) -- Execute the handler function/purchase logic depending on tab
- end
- end
- end
- processContainer(Container1, function(BuyButton) --Process all gamepass UI items in Container1 and attach gamepass buying logic to Buy button
- BuyButton.MouseButton1Click:Connect(function() --Connecting the MouseButton1Click event to call the handleGamepassBuy function for gamepass purchase
- handleGamepassBuy(BuyButton) --Calls the function that prompts the player to buy the associated gamepass
- end)
- end)
- processContainer(Container2, function(BuyButton) --Process all developer product UI items in Container2 and attach product purchase logic to Buy button
- BuyButton.MouseButton1Click:Connect(function() --Connecting the MouseButton1Click event to call the handleGamepassBuy function for product purchase
- handleProductBuy(BuyButton) -- Calls the function that prompts the player to buy the associated developer product
- end)
- end)
- processContainer(Container3, function(BuyButton) --Process all store item UI elements in Container3 and attach custom popup handling to Buy button
- BuyButton.MouseButton1Click:Connect(function() --Connecting the MouseButton1Click event to call the handleGamepassBuy function for store purchases
- handlePopupBuy(BuyButton)--Calls the function that prompts the player to buy the associated item
- end)
- end)
- end
- function UserInterfaceController:InventoryHandler()
- local Container = InventoryUI.Canvas.Container.Main.Container -- refrence to hte frame that holds item buttons
- local SidePanel = InventoryUI.Canvas.Container.Main.SidePanel -- refrence to the frame that shows selected item details
- local SelectedChild -- Currently selected item
- -- Setup UIStroke for selection outline
- local UIStroke = Instance.new("UIStroke")
- UIStroke.Parent = nil
- UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
- UIStroke.Color = Color3.fromRGB(126, 36, 233)
- UIStroke.Thickness = 2
- -- Use button logic
- SidePanel.Use.MouseButton1Click:Connect(function()
- if SidePanel.ItemName.Text == "ExtraLifes" then
- MapHandlerService:ExtraLifes() --Calls "ExtraLifes" function from MapHandlerService (server) to give player extra lifes
- SelectedChild:Destroy() -- Consume/Remove item
- SidePanel.ImageLabel.Image = ""
- SidePanel.ItemName.Text = "ItemName"
- SidePanel.ItemDescription.Text = "ItemDescription"
- elseif SidePanel.ItemName.Text == "LessGravity" then
- MapHandlerService:LessGravity("IncreaseGravityValue") --Calls "LessGravity" function
- end
- end)
- -- When new item added to inventory
- Container.ChildAdded:Connect(function(child:ImageButton)
- child.MouseButton1Click:Connect(function()
- if SelectedChild or SelectedChild == child then return end
- SelectedChild = child
- UIStroke.Parent = child:FindFirstChild("Default")
- -- Update side panel
- SidePanel.ItemName.Text = child.Name
- SidePanel.ImageLabel.Image = child.Default.ImageLabel.Image
- SidePanel.ItemDescription.Text = child.Default.TextLabel.Text
- end)
- end)
- end
- -- Format seconds into MM:SS format
- function UserInterfaceController:FormatTime(seconds)
- seconds = math.max(0, math.floor(seconds))
- local minutes = math.floor(seconds / 60)
- local secs = seconds % 60
- return string.format("%02d:%02d", minutes, secs)
- end
- -- Unlock times for rewards (in seconds)
- local TimeToUnlock = {
- Reward1 = 5 * 60,
- Reward2 = 10 * 60,
- Reward3 = 15 * 60,
- Reward4 = 20 * 60,
- Reward5 = 25 * 60,
- Reward6 = 30 * 60,
- Reward7 = 35 * 60,
- }
- function UserInterfaceController:RewardUI()
- local UIStroke
- local StartTime = tick() --returns the number of seconds since January 1st, 1970 UTC, useful for time elapsed calculations
- -- Update timer every second
- spawn(function()
- while wait(1) do
- for _, rewards in pairs(RewardUI.Canvas.Container.Main.Container:GetChildren()) do
- if not rewards:IsA("ImageButton") then continue end
- 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
- rewards.Equipped.TextLabel.Text = "Unlock in: " .. self:FormatTime(TimeToUnlock[rewards.Name] - (tick() - StartTime)) --Update the rewards time after formating seconds into MM:SS format
- if rewards.Equipped.TextLabel.Text == "Unlock in: 00:00" then --if timer is reached 0 sec it changes rewards button text to equip
- rewards.Equipped.Buy.Backing.Text.Text = "Equip"
- end
- end
- end
- end)
- --loop through all the rewards available in reward UI container/scrolling Frame
- for _, Rewards in pairs(RewardUI.Canvas.Container.Main.Container:GetChildren()) do
- if not Rewards:IsA("ImageButton") then continue end
- Rewards.MouseEnter:Connect(function() --apply Hover effect whenever mouse hovers over the button
- if not UIStroke then --same UIStroke logic
- UIStroke = Instance.new("UIStroke")
- UIStroke.Parent = Rewards:FindFirstChild("Default")
- UIStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
- UIStroke.Color = Color3.fromRGB(126, 36, 233)
- UIStroke.Thickness = 2
- else
- UIStroke.Parent = Rewards:FindFirstChild("Default")
- end
- end)
- --remove UIStroke after player mouse leaves the button
- Rewards.MouseLeave:Connect(function()
- UIStroke.Parent = nil
- end)
- local EquipButton:ImageButton = Rewards.Equipped:FindFirstChild("Buy") or Rewards.Default:FindFirstChild("Buy") --refrence to buy button
- local EquippedHat --last equipped Hat accessory
- local EquippedNeck --Last equipped neck accessory
- local EquippedFace --last equipped fconace accessory
- --handles equip button logic
- EquipButton.MouseButton1Click:Connect(function()
- if EquipButton.Backing.Text.Text == "Locked yet!" then return end --if item is currently lock then stop execution of event immediately
- --if player has already equipped item then unEquip it
- if EquipButton.Backing.Text.Text == "Unequip" then
- 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
- if Success then --if everything goes well then it changes button text to Equip
- EquipButton.Backing.Text.Text = "Equip"
- end
- return
- end
- --if player has not equipped item then equip it
- local Success, errorMessage = MapHandlerService:WearBrainRot(Rewards:FindFirstChild("AssetId").Value, "Wear", Rewards)
- if Success then
- EquipButton.Backing.Text.Text = "Unequip"
- end
- end)
- end
- end
- --handles logics of setting UI
- function UserInterfaceController:SettignsUI()
- for _, Settings in pairs(SettingsUI.Canvas.Container.Main.Container:GetChildren()) do
- if not Settings:IsA("ImageLabel") then continue end
- local ToggleButton = Settings:FindFirstChild("ToggleButton")
- if not ToggleButton then continue end
- ToggleButton.MouseButton1Click:Connect(function() --Event which runs upon toggle button is clicked using left mouse button
- -- Determine toggle state
- local turningOff = Settings.Background.Toggle.ActiveFrame.Visible == true
- Settings.Background.Toggle.ActiveFrame.Visible = not turningOff
- Settings.Background.Toggle.InactiveFrame.Visible = turningOff
- -- Loop through all other players
- for _, Player in pairs(game.Players:GetPlayers()) do
- if Player == player then continue end
- local char = Player.Character
- if not char then continue end
- for _, child in pairs(char:GetDescendants()) do
- --This condition will only execute if the child is a type of "BasePart" Or "MeshPart" or "Decal"
- if not (child:IsA("MeshPart") or child:IsA("BasePart") or child:IsA("Decal")) then continue end
- if child.Name == "HumanoidRootPart" then continue end
- child.Transparency = turningOff and 0 or 1 -- Hide or show the bodyparts of player character
- end
- end
- end)
- end
- end
- function UserInterfaceController:KnitInit()
- MapHandlerService = Knit.GetService("MapHandlerService") -- Fetch server-side service
- -- Init all UI features
- self:TrollUI()
- self:PushIUI()
- self:AnimateUIs()
- self:SettignsUI()
- self:ShopeUI()
- self:RewardUI()
- self:InventoryHandler()
- -- Show round countdown
- MapHandlerService.Timer:Connect(function()
- self:BackTimer()
- end)
- -- Display a center-screen message from the server
- MapHandlerService.Message:Connect(function(Message)
- self:ShowMessage(Message)
- end)
- -- Rope animation controller from server
- MapHandlerService.AnimateRopes:Connect(function(serverStartTime, Mode)
- self:startAnimationWhenReady(serverStartTime, Mode)
- end)
- end
- return UserInterfaceController
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement