-- PolishedMegaGUI — Rayfield Version -- LocalScript: place under StarterGui local Rayfield = loadstring(game:HttpGet('https://sirius.menu/rayfield'))() -- Services local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local HttpService = game:GetService("HttpService") local localPlayer = Players.LocalPlayer local playerGui = localPlayer:WaitForChild("PlayerGui") -- Remotes local ProjectileEvent = ReplicatedStorage:FindFirstChild("Projectile_Event") local SpecialSkillEvent = ReplicatedStorage:FindFirstChild("SpecialSkill_Event") local CharacterTransform = ReplicatedStorage:FindFirstChild("CharacterTransform") -- Settings persistence local function saveSetting(key, value) pcall(function() playerGui:SetAttribute("PMG_"..key, HttpService:JSONEncode(value)) end) end local function loadSetting(key, default) local raw = playerGui:GetAttribute("PMG_"..key) if not raw then return default end local ok, res = pcall(function() return HttpService:JSONDecode(raw) end) return ok and res or default end local DEFAULTS = { defaultPreset = "CharaBullet", projectileSpeed = 75, projectileGravity = {0,-7,0}, selectedVIP = "Foxy", vipList = {"Foxy","Nemesis","Zoro"}, charaSpamEnabled = false, charaSpamInterval = 1.0, charaAimAtSelected = false, autofireEnabled = false, autofireRange = 60, autofireGlobalRate = 0.5, autofirePerTargetCooldown = 2.0, autofireMode = "Nearest", autofireIgnoreForceField = true, selfAttack = false, healEnabled = false, healDelay = 1.0, healCount = 10, healTargetMode = "Selected", auraEnabled = false, auraDur = 3, auraVal = 10, } local SETTINGS = loadSetting("settings", DEFAULTS) for k,v in pairs(DEFAULTS) do if SETTINGS[k] == nil then SETTINGS[k] = v end end local VIP_CHARACTERS = {} for i,v in ipairs(SETTINGS.vipList or DEFAULTS.vipList) do VIP_CHARACTERS[i] = v end local PROJECTILE_PRESETS = { ["CharaBullet"] = {DAMAGE=75, PROJECTILE_SPEED=350, GRAVITY=Vector3.new(0,0,0), HIT_TYPE="EXPLOSION", PROJECTILE_MODEL="PROJ_CHARABULLET", BLAST_RADIUS=12, EXPLODE_FX="Chara_Explosion", AURA="BURN", DESC="Chara explosive bullet (high speed)."}, ["TNT Blast"] = {DAMAGE=75, PROJECTILE_SPEED=50, GRAVITY=Vector3.new(0,-7,0), HIT_TYPE="EXPLOSION", PROJECTILE_MODEL="PROJ_TNT", BLAST_RADIUS=14, AURA="BURN", DESC="Big slow explosive."}, ["Machete Throw"] = {DAMAGE=50, PROJECTILE_SPEED=75, GRAVITY=Vector3.new(0,-7,0), HIT_TYPE="NORMAL", PROJECTILE_MODEL="PROJ_MACHETE", BLAST_RADIUS=0, STICK_PROJECTILE=true, AURA=nil, DESC="Thrown blade, sticks to targets."}, ["Chainball"] = {DAMAGE=88, PROJECTILE_SPEED=48, GRAVITY=Vector3.new(0,0,0), HIT_TYPE="PINHEAD_HOOK", PROJECTILE_MODEL="PROJ_CHAINBALL", BLAST_RADIUS=0, AURA=nil, DESC="Heavy chainball/hook behavior."}, } -- Helpers local function parseVecString(s) if not s then return Vector3.new(0,-7,0) end local p = {} for n in string.gmatch(s,"[-%d%.]+") do table.insert(p,tonumber(n)) end if #p >= 3 then return Vector3.new(p[1],p[2],p[3]) end return Vector3.new(0,-7,0) end local function getOriginAndDir() local c = localPlayer.Character local hrp = c and (c.PrimaryPart or c:FindFirstChild("HumanoidRootPart")) if hrp then return hrp.Position + hrp.CFrame.LookVector * 2 + Vector3.new(0,1.5,0), hrp.CFrame.LookVector end return Vector3.new(0,0,1), Vector3.new(0,0,1) end -- Editor state local currentPreset = SETTINGS.defaultPreset or "CharaBullet" local currentStick = false local selectedTarget = nil local editor = { damage = "75", speed = tostring(SETTINGS.projectileSpeed), blast = "12", gravity = table.concat(SETTINGS.projectileGravity or {0,-7,0}, ","), hitType = "EXPLOSION", model = "PROJ_CHARABULLET", } local function loadPresetIntoEditor(name) local t = PROJECTILE_PRESETS[name] if not t then return end editor.damage = tostring(t.DAMAGE or 75) editor.speed = tostring(t.PROJECTILE_SPEED or 75) editor.blast = tostring(t.BLAST_RADIUS or 0) editor.gravity = t.GRAVITY and ("%g,%g,%g"):format(t.GRAVITY.X,t.GRAVITY.Y,t.GRAVITY.Z) or "0,-7,0" editor.hitType = t.HIT_TYPE or "NORMAL" editor.model = t.PROJECTILE_MODEL or "" currentStick = t.STICK_PROJECTILE and true or false end loadPresetIntoEditor(currentPreset) local function buildPayload() local p = PROJECTILE_PRESETS[currentPreset] or {} -- Aura: only attach if toggle is ON and the preset has an aura name local auraData = nil if SETTINGS.auraEnabled and p.AURA then auraData = { NAME = p.AURA, DURATION = SETTINGS.auraDur or 3, VALUE = SETTINGS.auraVal or 10, } end return { DAMAGE = tonumber(editor.damage) or p.DAMAGE or 0, PROJECTILE_SPEED = tonumber(editor.speed) or p.PROJECTILE_SPEED or 75, GRAVITY = parseVecString(editor.gravity) or p.GRAVITY or Vector3.new(0,-7,0), HIT_TYPE = editor.hitType ~= "" and editor.hitType or p.HIT_TYPE or "NORMAL", PROJECTILE_MODEL = editor.model ~= "" and editor.model or p.PROJECTILE_MODEL or "", BLAST_RADIUS = tonumber(editor.blast) or p.BLAST_RADIUS or 0, EXPLODE_FX = p.EXPLODE_FX or "", AURA = auraData, STICK_PROJECTILE = currentStick or p.STICK_PROJECTILE or nil, } end local function fireProjectileAt(targetPlayer) if not ProjectileEvent then return end local origin, dir = getOriginAndDir() if targetPlayer and targetPlayer ~= localPlayer and targetPlayer.Character then local hrp = targetPlayer.Character:FindFirstChild("HumanoidRootPart") if hrp then dir = (hrp.Position - origin).Unit end end pcall(function() ProjectileEvent:FireServer(origin, dir, buildPayload()) end) end -- ===================================================================== -- RAYFIELD WINDOW -- ===================================================================== local Window = Rayfield:CreateWindow({ Name = "PolishedMegaGUI", LoadingTitle = "PolishedMegaGUI", LoadingSubtitle = "Players · Projectiles · Summons · VIP · Heal", Theme = "Default", DisableRayfieldPrompts = false, DisableBuildWarnings = false, ConfigurationSaving = {Enabled = false}, KeySystem = false, }) -- ===================================================================== -- TAB 1 — PLAYERS & PROJECTILES -- ===================================================================== local Tab1 = Window:CreateTab("Players & Projectiles", 4483362458) -- ── Player Selection ────────────────────────────────────────────── Tab1:CreateSection("Player Selection") local function getPlayerNames() local names = {} for _,p in ipairs(Players:GetPlayers()) do if p ~= localPlayer then table.insert(names, p.Name) end end return #names > 0 and names or {"(no players)"} end local PlayerDropdown = Tab1:CreateDropdown({ Name = "Target Player", Options = getPlayerNames(), CurrentOption = {"(no players)"}, Flag = "TargetPlayer", Callback = function(option) local name = type(option) == "table" and option[1] or option for _,p in ipairs(Players:GetPlayers()) do if p.Name == name then selectedTarget = p; break end end end, }) Tab1:CreateButton({ Name = "Refresh Player List", Callback = function() local names = getPlayerNames() PlayerDropdown:Set(names[1]) Rayfield:Notify({Title="Players", Content="List refreshed ("..#names.." found).", Duration=2}) end, }) Tab1:CreateButton({ Name = "Teleport To Selected", Callback = function() if not selectedTarget or not selectedTarget.Character then Rayfield:Notify({Title="Teleport", Content="No target selected.", Duration=2}); return end local hrp = selectedTarget.Character:FindFirstChild("HumanoidRootPart") local me = localPlayer.Character if hrp and me and me:FindFirstChild("HumanoidRootPart") then pcall(function() me.HumanoidRootPart.CFrame = hrp.CFrame * CFrame.new(0,0,-2) end) end end, }) Tab1:CreateToggle({ Name = "Self-Attack Mode", CurrentValue = SETTINGS.selfAttack, Flag = "SelfAttack", Callback = function(v) SETTINGS.selfAttack = v; saveSetting("settings", SETTINGS) end, }) -- ── Preset Selector ─────────────────────────────────────────────── Tab1:CreateSection("Projectile Preset") local presetNames = {} for name in pairs(PROJECTILE_PRESETS) do table.insert(presetNames, name) end table.sort(presetNames, function(a,b) return a:lower() < b:lower() end) Tab1:CreateDropdown({ Name = "Select Preset", Options = presetNames, CurrentOption = {currentPreset}, Flag = "ProjectilePreset", Callback = function(option) currentPreset = type(option) == "table" and option[1] or option SETTINGS.defaultPreset = currentPreset loadPresetIntoEditor(currentPreset) saveSetting("settings", SETTINGS) local t = PROJECTILE_PRESETS[currentPreset] local auraInfo = t and t.AURA and (" | Aura: "..t.AURA) or " | No Aura" Rayfield:Notify({Title="Preset Loaded", Content=(t and t.DESC or currentPreset)..auraInfo, Duration=3, Image=4483362458}) end, }) -- ── Preset Editor ───────────────────────────────────────────────── Tab1:CreateSection("Preset Editor") Tab1:CreateInput({Name="Damage", CurrentValue=editor.damage, PlaceholderText="e.g. 75", RemoveTextAfterFocusLost=false, Flag="ProjDamage", Callback=function(v) editor.damage = v end}) Tab1:CreateInput({Name="Speed", CurrentValue=editor.speed, PlaceholderText="e.g. 350", RemoveTextAfterFocusLost=false, Flag="ProjSpeed", Callback=function(v) editor.speed = v end}) Tab1:CreateInput({Name="Blast Radius", CurrentValue=editor.blast, PlaceholderText="e.g. 12", RemoveTextAfterFocusLost=false, Flag="ProjBlast", Callback=function(v) editor.blast = v end}) Tab1:CreateInput({Name="Gravity (X,Y,Z)", CurrentValue=editor.gravity, PlaceholderText="e.g. 0,-7,0", RemoveTextAfterFocusLost=false, Flag="ProjGravity", Callback=function(v) editor.gravity = v end}) Tab1:CreateInput({Name="Hit Type", CurrentValue=editor.hitType, PlaceholderText="e.g. EXPLOSION", RemoveTextAfterFocusLost=false, Flag="ProjHitType", Callback=function(v) editor.hitType = v end}) Tab1:CreateInput({Name="Projectile Model", CurrentValue=editor.model, PlaceholderText="e.g. PROJ_CHARABULLET", RemoveTextAfterFocusLost=false, Flag="ProjModel", Callback=function(v) editor.model = v end}) Tab1:CreateToggle({ Name = "Stick Projectile", CurrentValue = currentStick, Flag = "ProjStick", Callback = function(v) currentStick = v end, }) Tab1:CreateButton({ Name = "Apply Editor → Current Preset", Callback = function() local tbl = PROJECTILE_PRESETS[currentPreset] or {} tbl.DAMAGE = tonumber(editor.damage) or tbl.DAMAGE tbl.PROJECTILE_SPEED = tonumber(editor.speed) or tbl.PROJECTILE_SPEED tbl.GRAVITY = parseVecString(editor.gravity) tbl.BLAST_RADIUS = tonumber(editor.blast) or tbl.BLAST_RADIUS tbl.PROJECTILE_MODEL = editor.model ~= "" and editor.model or tbl.PROJECTILE_MODEL tbl.HIT_TYPE = editor.hitType ~= "" and editor.hitType or tbl.HIT_TYPE tbl.STICK_PROJECTILE = currentStick or nil PROJECTILE_PRESETS[currentPreset] = tbl Rayfield:Notify({Title="Preset Updated", Content="Saved to: "..currentPreset, Duration=3, Image=4483362458}) end, }) -- ── Aura Settings ───────────────────────────────────────────────── Tab1:CreateSection("Aura Settings") -- Shows which aura the current preset uses (read-only info label via a disabled input) Tab1:CreateLabel("Aura name is taken from the selected preset automatically.") Tab1:CreateToggle({ Name = "Enable Aura", CurrentValue = SETTINGS.auraEnabled, Flag = "AuraEnabled", Callback = function(v) SETTINGS.auraEnabled = v saveSetting("settings", SETTINGS) local p = PROJECTILE_PRESETS[currentPreset] local auraName = p and p.AURA or "none" Rayfield:Notify({ Title = "Aura " .. (v and "Enabled" or "Disabled"), Content = v and ("Using aura: "..auraName) or "No aura will be applied.", Duration= 3, Image = 4483362458, }) end, }) Tab1:CreateInput({ Name = "Aura Duration (s)", CurrentValue = tostring(SETTINGS.auraDur), PlaceholderText = "e.g. 3", RemoveTextAfterFocusLost= false, Flag = "AuraDur", Callback = function(v) local n = tonumber(v) if n and n > 0 then SETTINGS.auraDur = n; saveSetting("settings", SETTINGS) end end, }) Tab1:CreateInput({ Name = "Aura Value / Magnitude", CurrentValue = tostring(SETTINGS.auraVal), PlaceholderText = "e.g. 10", RemoveTextAfterFocusLost= false, Flag = "AuraVal", Callback = function(v) local n = tonumber(v) if n and n > 0 then SETTINGS.auraVal = n; saveSetting("settings", SETTINGS) end end, }) -- ── Fire ────────────────────────────────────────────────────────── Tab1:CreateSection("Fire") Tab1:CreateButton({ Name = "🔥 Fire Projectile at Target [F]", Callback = function() local target = SETTINGS.selfAttack and localPlayer or selectedTarget fireProjectileAt(target) Rayfield:Notify({Title="Fired", Content="Preset: "..currentPreset, Duration=2, Image=4483362458}) end, }) -- ── CharaBullet Spam ────────────────────────────────────────────── Tab1:CreateSection("CharaBullet Spam") Tab1:CreateToggle({ Name = "Aim at Selected Target", CurrentValue = SETTINGS.charaAimAtSelected, Flag = "CharaAim", Callback = function(v) SETTINGS.charaAimAtSelected = v; saveSetting("settings", SETTINGS) end, }) Tab1:CreateInput({ Name = "Spam Interval (s)", CurrentValue = tostring(SETTINGS.charaSpamInterval), PlaceholderText = "e.g. 1.0", RemoveTextAfterFocusLost= false, Flag = "CharaInterval", Callback = function(v) local n = tonumber(v) if n and n > 0 then SETTINGS.charaSpamInterval = n; saveSetting("settings", SETTINGS) end end, }) local charaOrigin = "217.37515258789062,290.6371765136719,264.4747314453125" Tab1:CreateInput({ Name = "Chara Origin (X,Y,Z)", CurrentValue = charaOrigin, PlaceholderText = "X,Y,Z", RemoveTextAfterFocusLost= false, Flag = "CharaPos", Callback = function(v) charaOrigin = v end, }) local function fireCharaOnce() if not ProjectileEvent then return end local coords = {} for n in string.gmatch(charaOrigin,"[-%d%.]+") do table.insert(coords,tonumber(n)) end local pos = #coords >= 3 and Vector3.new(coords[1],coords[2],coords[3]) or getOriginAndDir() local dir = Vector3.new(0.818,-0.573,-0.044) if SETTINGS.charaAimAtSelected and selectedTarget and selectedTarget.Character then local hrp = selectedTarget.Character:FindFirstChild("HumanoidRootPart") if hrp then dir = (hrp.Position - pos).Unit end end local payload = { DAMAGE=75, PROJECTILE_SPEED=350, GRAVITY=Vector3.new(0,0,0), HIT_TYPE="EXPLOSION", PROJECTILE_MODEL="PROJ_CHARABULLET", BLAST_RADIUS=12, EXPLODE_FX="Chara_Explosion", AURA = SETTINGS.auraEnabled and {NAME="BURN", DURATION=SETTINGS.auraDur or 3, VALUE=SETTINGS.auraVal or 10} or nil, } pcall(function() ProjectileEvent:FireServer(pos, dir, payload) end) end local charaSpamConn = nil Tab1:CreateToggle({ Name = "CharaBullet Spam", CurrentValue = SETTINGS.charaSpamEnabled, Flag = "CharaSpam", Callback = function(v) SETTINGS.charaSpamEnabled = v; saveSetting("settings", SETTINGS) if v then if charaSpamConn then charaSpamConn:Disconnect() end local acc = 0 charaSpamConn = RunService.Heartbeat:Connect(function(dt) acc = acc + dt if acc >= (SETTINGS.charaSpamInterval or 1.0) then acc = acc - SETTINGS.charaSpamInterval pcall(fireCharaOnce) end end) else if charaSpamConn then charaSpamConn:Disconnect(); charaSpamConn = nil end end end, }) Tab1:CreateButton({ Name = "Fire CharaBullet Once", Callback = function() pcall(fireCharaOnce) end, }) -- ── Autofire ────────────────────────────────────────────────────── Tab1:CreateSection("Autofire") Tab1:CreateToggle({ Name = "Autofire", CurrentValue = SETTINGS.autofireEnabled, Flag = "Autofire", Callback = function(v) SETTINGS.autofireEnabled = v; saveSetting("settings", SETTINGS) end, }) Tab1:CreateInput({ Name = "Autofire Range (studs)", CurrentValue = tostring(SETTINGS.autofireRange), PlaceholderText = "e.g. 60", RemoveTextAfterFocusLost= false, Flag = "AutoRange", Callback = function(v) local n = tonumber(v) if n and n > 0 then SETTINGS.autofireRange = n; saveSetting("settings", SETTINGS) end end, }) Tab1:CreateInput({ Name = "Autofire Delay (s) ← lower = faster", CurrentValue = tostring(SETTINGS.autofireGlobalRate), PlaceholderText = "e.g. 0.05 (0 = max speed)", RemoveTextAfterFocusLost= false, Flag = "AutoDelay", Callback = function(v) local n = tonumber(v) if n and n >= 0 then SETTINGS.autofireGlobalRate = n; saveSetting("settings", SETTINGS) end end, }) Tab1:CreateInput({ Name = "Per-Target Cooldown (s)", CurrentValue = tostring(SETTINGS.autofirePerTargetCooldown), PlaceholderText = "e.g. 0.1", RemoveTextAfterFocusLost= false, Flag = "AutoCooldown", Callback = function(v) local n = tonumber(v) if n and n >= 0 then SETTINGS.autofirePerTargetCooldown = n; saveSetting("settings", SETTINGS) end end, }) Tab1:CreateDropdown({ Name = "Autofire Mode", Options = {"Nearest","All"}, CurrentOption = {SETTINGS.autofireMode or "Nearest"}, Flag = "AutoMode", Callback = function(option) SETTINGS.autofireMode = type(option)=="table" and option[1] or option saveSetting("settings", SETTINGS) end, }) -- Autofire heartbeat local perTargetCooldowns = {} local lastGlobalFire = 0 local function isValidAutoTarget(plr) if not plr or not plr.Character then return false end local hrp = plr.Character:FindFirstChild("HumanoidRootPart") local hum = plr.Character:FindFirstChild("Humanoid") return hrp and hum and hum.Health > 0 end RunService.Heartbeat:Connect(function() if not SETTINGS.autofireEnabled then return end local now = tick() if now - lastGlobalFire < (SETTINGS.autofireGlobalRate or 0.5) then return end local me = localPlayer.Character if not me or not me:FindFirstChild("HumanoidRootPart") then return end local myPos = me.HumanoidRootPart.Position local candidates = {} for _,plr in ipairs(Players:GetPlayers()) do if plr ~= localPlayer and isValidAutoTarget(plr) then local hrp = plr.Character:FindFirstChild("HumanoidRootPart") if hrp then local d = (hrp.Position - myPos).Magnitude if d <= (SETTINGS.autofireRange or 60) then table.insert(candidates,{plr=plr,dist=d}) end end end end if #candidates == 0 then return end if SETTINGS.autofireMode == "Nearest" then table.sort(candidates, function(a,b) return a.dist < b.dist end) local chosen = candidates[1].plr if now >= (perTargetCooldowns[chosen] or 0) then fireProjectileAt(chosen) perTargetCooldowns[chosen] = now + (SETTINGS.autofirePerTargetCooldown or 2.0) lastGlobalFire = now end else for _,entry in ipairs(candidates) do local pl = entry.plr if now >= (perTargetCooldowns[pl] or 0) and now - lastGlobalFire >= (SETTINGS.autofireGlobalRate or 0.5) then fireProjectileAt(pl) perTargetCooldowns[pl] = now + (SETTINGS.autofirePerTargetCooldown or 2.0) lastGlobalFire = now break end end end end) -- ===================================================================== -- TAB 2 — SUMMONS -- ===================================================================== local Tab2 = Window:CreateTab("Summons", 4483362458) Tab2:CreateSection("NPC Configuration") local summonName = "GRANDPA_NPC" local summonAmount = 1 local summonDuration = 10 local statH, statD, statSp, statAg = nil, nil, nil, nil Tab2:CreateInput({Name="NPC Name", CurrentValue=summonName, PlaceholderText="e.g. GRANDPA_NPC", RemoveTextAfterFocusLost=false, Flag="SummonName", Callback=function(v) summonName = v end}) Tab2:CreateInput({Name="Amount", CurrentValue=tostring(summonAmount), PlaceholderText="e.g. 1", RemoveTextAfterFocusLost=false, Flag="SummonAmount", Callback=function(v) summonAmount = tonumber(v) or 1 end}) Tab2:CreateInput({Name="Duration (s)",CurrentValue=tostring(summonDuration),PlaceholderText="e.g. 10", RemoveTextAfterFocusLost=false, Flag="SummonDuration", Callback=function(v) summonDuration = tonumber(v) or 10 end}) Tab2:CreateSection("NPC Stats (Optional)") Tab2:CreateInput({Name="Health", CurrentValue="", PlaceholderText="e.g. 500", RemoveTextAfterFocusLost=false, Flag="StatH", Callback=function(v) statH = tonumber(v) end}) Tab2:CreateInput({Name="Damage", CurrentValue="", PlaceholderText="e.g. 25", RemoveTextAfterFocusLost=false, Flag="StatD", Callback=function(v) statD = tonumber(v) end}) Tab2:CreateInput({Name="Speed", CurrentValue="", PlaceholderText="e.g. 16", RemoveTextAfterFocusLost=false, Flag="StatSp", Callback=function(v) statSp = tonumber(v) end}) Tab2:CreateInput({Name="Aggro Range", CurrentValue="", PlaceholderText="e.g. 50", RemoveTextAfterFocusLost=false, Flag="StatAg", Callback=function(v) statAg = tonumber(v) end}) local function doSummon(name, amount, duration) if not SpecialSkillEvent then Rayfield:Notify({Title="Error", Content="SpecialSkill_Event not found.", Duration=3}); return end local stats = {} if statH then stats.HEALTH = statH end if statD then stats.DAMAGE = statD end if statSp then stats.SPEED = statSp end if statAg then stats.AGGRO_RANGE = statAg end local payload = {"INVOKE_NPC", {DURATION=duration, HOW_MANY=amount, NPC_NAME=name, STATS=next(stats) and stats or nil}} pcall(function() SpecialSkillEvent:FireServer(unpack(payload)) end) Rayfield:Notify({Title="Summoned", Content=("%dx %s for %ds"):format(amount, name, duration), Duration=3, Image=4483362458}) end Tab2:CreateButton({Name="✅ Apply Stats & Summon", Callback=function() doSummon(summonName, summonAmount, summonDuration) end}) Tab2:CreateSection("Quick Summons") Tab2:CreateButton({Name="MiniHuggy ×1", Callback=function() doSummon("MINIHUGGY_NPC", 1, 10) end}) Tab2:CreateButton({Name="Grandpa ×1", Callback=function() doSummon("GRANDPA_NPC", 1, 12) end}) Tab2:CreateButton({Name="Principal ×1", Callback=function() doSummon("PRINCIPAL_NPC", 1, 5) end}) Tab2:CreateButton({Name="Skeletons ×3", Callback=function() doSummon("SKELETON_NPC", 3, 10) end}) -- ===================================================================== -- TAB 3 — VIP -- ===================================================================== local Tab3 = Window:CreateTab("VIP", 4483362458) Tab3:CreateSection("Character Transform") Tab3:CreateDropdown({ Name = "VIP Character", Options = VIP_CHARACTERS, CurrentOption = {SETTINGS.selectedVIP or VIP_CHARACTERS[1]}, Flag = "VIPChar", Callback = function(option) SETTINGS.selectedVIP = type(option)=="table" and option[1] or option saveSetting("settings", SETTINGS) end, }) Tab3:CreateButton({ Name = "Transform [T]", Callback = function() if not CharacterTransform then Rayfield:Notify({Title="Error", Content="CharacterTransform not found.", Duration=3}); return end local name = SETTINGS.selectedVIP or VIP_CHARACTERS[1] pcall(function() CharacterTransform:FireServer(name) end) Rayfield:Notify({Title="Transform", Content="→ "..name, Duration=3, Image=4483362458}) end, }) -- ===================================================================== -- TAB 4 — LOOP HEAL -- ===================================================================== local Tab4 = Window:CreateTab("Loop Heal", 4483362458) Tab4:CreateSection("Heal Configuration") Tab4:CreateDropdown({ Name = "Target Mode", Options = {"Selected","Self"}, CurrentOption = {SETTINGS.healTargetMode or "Selected"}, Flag = "HealMode", Callback = function(option) SETTINGS.healTargetMode = type(option)=="table" and option[1] or option saveSetting("settings", SETTINGS) end, }) Tab4:CreateInput({ Name="Heal Delay (s)", CurrentValue=tostring(SETTINGS.healDelay), PlaceholderText="e.g. 1.0", RemoveTextAfterFocusLost=false, Flag="HealDelay", Callback=function(v) local n=tonumber(v); if n and n>0 then SETTINGS.healDelay=n; saveSetting("settings",SETTINGS) end end, }) Tab4:CreateInput({ Name="Heal Count", CurrentValue=tostring(SETTINGS.healCount), PlaceholderText="e.g. 10", RemoveTextAfterFocusLost=false, Flag="HealCount", Callback=function(v) local n=tonumber(v); if n and n>0 then SETTINGS.healCount=n; saveSetting("settings",SETTINGS) end end, }) local function fireHealOnce() if not SpecialSkillEvent then return end pcall(function() SpecialSkillEvent:FireServer("HHH_TARGETKILL") end) end Tab4:CreateButton({ Name = "One-Shot Heal", Callback = function() fireHealOnce() Rayfield:Notify({Title="Heal", Content="Fired 1 heal cycle.", Duration=2, Image=4483362458}) end, }) local healConn = nil Tab4:CreateToggle({ Name = "Loop Heal", CurrentValue = SETTINGS.healEnabled, Flag = "LoopHeal", Callback = function(v) SETTINGS.healEnabled = v; saveSetting("settings", SETTINGS) if v then if healConn then healConn:Disconnect(); healConn = nil end local acc, remaining = 0, SETTINGS.healCount or 10 healConn = RunService.Heartbeat:Connect(function(dt) acc = acc + dt if acc >= (SETTINGS.healDelay or 1.0) then acc = acc - SETTINGS.healDelay fireHealOnce() remaining = remaining - 1 if remaining <= 0 then SETTINGS.healEnabled = false; saveSetting("settings", SETTINGS) if healConn then healConn:Disconnect(); healConn = nil end Rayfield:Notify({Title="Loop Heal", Content="All cycles complete.", Duration=3}) end end end) Rayfield:Notify({Title="Loop Heal", Content=("Running %d heals at %.1fs interval"):format(SETTINGS.healCount, SETTINGS.healDelay), Duration=3, Image=4483362458}) else if healConn then healConn:Disconnect(); healConn = nil end Rayfield:Notify({Title="Loop Heal", Content="Stopped.", Duration=2}) end end, }) -- ===================================================================== -- HOTKEYS -- ===================================================================== UserInputService.InputBegan:Connect(function(input, processed) if processed then return end if input.KeyCode == Enum.KeyCode.F then fireProjectileAt(SETTINGS.selfAttack and localPlayer or selectedTarget) end if input.KeyCode == Enum.KeyCode.T and CharacterTransform then pcall(function() CharacterTransform:FireServer(SETTINGS.selectedVIP or VIP_CHARACTERS[1]) end) end end) -- ===================================================================== -- DONE -- ===================================================================== saveSetting("settings", SETTINGS) Rayfield:Notify({ Title = "PolishedMegaGUI Ready", Content = "F = Fire Projectile | T = VIP Transform", Duration= 5, Image = 4483362458, })