-- Services local Players = game:GetService("Players") local LocalPlayer = Players.LocalPlayer local UserInputService = game:GetService("UserInputService") local TextChatService = game:GetService("TextChatService") -- Script-wide variables local Keybinds = {} local BindingTarget = nil local ScreenGui local SpellButtons = {} -- Audio Feedback (Creates a sound in CoreGui for efficiency) local SoundId = "rbxassetid://6895079853" -- A simple "blip" sound local BindSound = Instance.new("Sound") BindSound.SoundId = SoundId BindSound.Volume = 0.5 BindSound.Parent = game:GetService("CoreGui") local function PlayFeedback() if BindSound then BindSound:Play() end end -- SPELL DATA local Spells = { ["Stunning"] = { "Duro", "Ebublio", "Glacius", "Impedimenta", "Incarcerous", "Levicorpus", "Locomotor Wibbly", "Petrificus Totalus", "Stupefy", "Tarantallegra" }, ["Killing"] = { "Avada Kedavra", "Defodio", "Deletrius", "Sectumsempra" }, ["Damaging"] = { "Alarte Ascendare", "Baubillious", "Bombarda", "Confringo", "Crucio", "Depulso", "Diffindo", "Everte Statum", "Expulso", "Flare", "Incendio", "Reducto", "Tonitro", "Verdimillious" }, ["Utility"] = { "Carpe Retractum", "Confundo", "Expelliarmus", "Flipendo", "Rictusempra", "Obliviate", "Obscuro", "Silencio", "Protego", "Protego Totalum", "Appa", "Ascendio", "Episkey", "Finite Incantatem", "Liberacorpus", "Relashio", "Rennervate", "Vulnera Sanentur", "Aboleo", "Accio", "Calvorio", "Diminuendo", "Engorgio Skullus", "Lumos", "Melofors", "Morsmordre", "Nox" } } -- CHAT FUNCTION local function CastSpell(spellName) if TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then local TextChannels = TextChatService:FindFirstChild("TextChannels") if TextChannels then local RBXGeneral = TextChannels:FindFirstChild("RBXGeneral") if RBXGeneral then RBXGeneral:SendAsync(spellName) return end end end local Chat = game:GetService("ReplicatedStorage"):FindFirstChild("DefaultChatSystemChatEvents") if Chat then local SayMessage = Chat:FindFirstChild("SayMessageRequest") if SayMessage then SayMessage:FireServer(spellName, "All") end end end -- Helper to update button text/color local function UpdateButtonVisuals(SpellName) if not ScreenGui then return end local Btn = SpellButtons[SpellName] if Btn then local bind = Keybinds[SpellName] if BindingTarget == SpellName then Btn.Text = "[KEY?] " .. SpellName Btn.BackgroundColor3 = Color3.fromRGB(200, 50, 50) -- Bright Red when waiting Btn.TextColor3 = Color3.new(1, 1, 1) elseif bind then Btn.Text = "[" .. tostring(bind.Name):sub(6) .. "] " .. SpellName -- Remove "KeyCode." Btn.BackgroundColor3 = Color3.fromRGB(30, 100, 30) -- Green when bound Btn.BackgroundTransparency = 0.2 Btn.TextColor3 = Color3.new(1, 1, 1) else Btn.Text = SpellName Btn.BackgroundColor3 = Color3.fromRGB(20, 20, 20) -- Dark Grey default Btn.BackgroundTransparency = 0.5 Btn.TextColor3 = Color3.new(0.8, 0.8, 0.8) end end end -- SEARCH LOGIC local function UpdateSearch(query) query = string.lower(query) for SpellName, Btn in pairs(SpellButtons) do if string.find(string.lower(SpellName), query) ~= nil then Btn.Visible = true else Btn.Visible = false end end -- Handle Headers for Category, SpellList in pairs(Spells) do local hasVisibleSpell = false for _, SpellName in pairs(SpellList) do local Btn = SpellButtons[SpellName] if Btn and Btn.Visible then hasVisibleSpell = true break end end local Header = ScreenGui.MainFrame.ScrollFrame:FindFirstChild("Header_" .. Category) if Header then Header.Visible = hasVisibleSpell end end end -- UI CREATION local function CreateGUI() if ScreenGui then ScreenGui:Destroy() end ScreenGui = Instance.new("ScreenGui") ScreenGui.Name = "SpellBinderPro" ScreenGui.ResetOnSpawn = false ScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui") -- Main Window (Fixed Bottom-Left for Tactical Visibility) local MainFrame = Instance.new("Frame") MainFrame.Name = "MainFrame" MainFrame.Size = UDim2.new(0, 220, 0, 400) MainFrame.Position = UDim2.new(0, 10, 1, -410) -- Pinned bottom left MainFrame.BackgroundColor3 = Color3.fromRGB(15, 15, 15) MainFrame.BorderSizePixel = 0 MainFrame.Active = false -- Locked position (can't drag to prevent accidental movement) MainFrame.Parent = ScreenGui -- Outline local Stroke = Instance.new("UIStroke") Stroke.Color = Color3.fromRGB(80, 80, 80) Stroke.Thickness = 1 Stroke.Parent = MainFrame local Corner = Instance.new("UICorner") Corner.CornerRadius = UDim.new(0, 4) Corner.Parent = MainFrame -- Title Bar (Top) local Title = Instance.new("TextLabel") Title.Name = "Title" Title.Size = UDim2.new(1, 0, 0, 25) Title.BackgroundColor3 = Color3.fromRGB(30, 30, 30) Title.TextColor3 = Color3.new(1, 1, 1) Title.Text = "SPELL BINDER [F5]" Title.Font = Enum.Font.GothamBold Title.TextSize = 12 Title.Parent = MainFrame local TitleCorner = Instance.new("UICorner") TitleCorner.CornerRadius = UDim.new(0, 4) TitleCorner.Parent = Title -- SEARCH BAR (Moved to top for ergonomics) local SearchBox = Instance.new("TextBox") SearchBox.Name = "SearchBox" SearchBox.Size = UDim2.new(1, -10, 0, 20) SearchBox.Position = UDim2.new(0, 5, 0, 27) SearchBox.BackgroundColor3 = Color3.fromRGB(25, 25, 25) SearchBox.TextColor3 = Color3.new(1, 1, 1) SearchBox.PlaceholderText = "Search..." SearchBox.PlaceholderColor3 = Color3.fromRGB(100, 100, 100) SearchBox.Font = Enum.Font.Gotham SearchBox.TextSize = 11 SearchBox.ClearTextOnFocus = false SearchBox.Parent = MainFrame local SearchCorner = Instance.new("UICorner") SearchCorner.CornerRadius = UDim.new(0, 2) SearchCorner.Parent = SearchBox SearchBox:GetPropertyChangedSignal("Text"):Connect(function() UpdateSearch(SearchBox.Text) end) -- Content Frame (Scrolling) local ScrollFrame = Instance.new("ScrollingFrame") ScrollFrame.Name = "ScrollFrame" ScrollFrame.Size = UDim2.new(1, -5, 1, -55) -- Adjusted for top search ScrollFrame.Position = UDim2.new(0, 0, 0, 50) -- Pushed down below search ScrollFrame.BackgroundTransparency = 1 ScrollFrame.ScrollBarThickness = 3 ScrollFrame.ScrollBarImageColor3 = Color3.new(0.4, 0.4, 0.4) ScrollFrame.Parent = MainFrame local Layout = Instance.new("UIListLayout") Layout.Padding = UDim.new(0, 2) Layout.Parent = ScrollFrame -- Populate UI for Category, SpellList in pairs(Spells) do -- Category Header local CatLabel = Instance.new("TextLabel") CatLabel.Name = "Header_" .. Category CatLabel.Size = UDim2.new(1, 0, 0, 15) CatLabel.BackgroundTransparency = 1 CatLabel.Text = Category CatLabel.TextColor3 = Color3.fromRGB(255, 200, 0) -- Gold headers for visibility CatLabel.TextXAlignment = Enum.TextXAlignment.Left CatLabel.Font = Enum.Font.GothamBold CatLabel.TextSize = 10 CatLabel.Parent = ScrollFrame -- Spells for _, SpellName in pairs(SpellList) do local Btn = Instance.new("TextButton") Btn.Name = SpellName Btn.Size = UDim2.new(1, 0, 0, 18) -- Compact height Btn.BackgroundColor3 = Color3.fromRGB(20, 20, 20) Btn.BackgroundTransparency = 0.5 Btn.TextColor3 = Color3.new(0.8, 0.8, 0.8) Btn.Font = Enum.Font.Gotham Btn.TextSize = 11 Btn.Text = SpellName Btn.TextXAlignment = Enum.TextXAlignment.Left Btn.Parent = ScrollFrame local BtnCorner = Instance.new("UICorner") BtnCorner.CornerRadius = UDim.new(0, 2) BtnCorner.Parent = Btn local BtnPadding = Instance.new("UIPadding") BtnPadding.PaddingLeft = UDim.new(0, 5) BtnPadding.Parent = Btn SpellButtons[SpellName] = Btn -- Left Click: Cast Btn.MouseButton1Click:Connect(function() CastSpell(SpellName) end) -- Right Click: Start Binding Btn.MouseButton2Click:Connect(function() if BindingTarget == SpellName then BindingTarget = nil else BindingTarget = SpellName end -- Refresh all for s, _ in pairs(SpellButtons) do UpdateButtonVisuals(s) end end) end end ScrollFrame.CanvasSize = UDim2.new(0, 0, 0, Layout.AbsoluteContentSize.Y + 5) end -- INPUT HANDLING UserInputService.InputBegan:Connect(function(Input, GameProcessed) if GameProcessed then return end -- Toggle GUI Visibility (F5) if Input.KeyCode == Enum.KeyCode.F5 then ScreenGui.Enabled = not ScreenGui.Enabled return end -- 1. Unbind (Left Control) if Input.KeyCode == Enum.KeyCode.LeftControl and BindingTarget then Keybinds[BindingTarget] = nil UpdateButtonVisuals(BindingTarget) BindingTarget = nil PlayFeedback() return end -- 2. Bind Key if BindingTarget then if Input.KeyCode ~= Enum.KeyCode.Unknown and Input.UserInputType == Enum.UserInputType.Keyboard then local NewKey = Input.KeyCode -- Check for existing bind (One Key = One Spell) local OldSpell = nil for SpellName, Key in pairs(Keybinds) do if Key == NewKey then OldSpell = SpellName break end end if OldSpell then Keybinds[OldSpell] = nil UpdateButtonVisuals(OldSpell) end Keybinds[BindingTarget] = NewKey local BoundSpell = BindingTarget BindingTarget = nil UpdateButtonVisuals(BoundSpell) PlayFeedback() -- Audio confirmation end return end -- 3. Cast via Keybind for SpellName, Key in pairs(Keybinds) do if Input.KeyCode == Key then CastSpell(SpellName) return end end end) -- Start CreateGUI()