Nevzyn

Untitled

Mar 9th, 2026
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 68.13 KB | None | 0 0
  1. --[[
  2. ╔══════════════════════════════════════════════════════════════════════╗
  3. ║ Save Locate (NickZ) - V5.2 ║
  4. ║ ║
  5. ║ Alterações V5.2: ║
  6. ║ 1. Botão ≡ substitui estrela + menu antigo ║
  7. ║ 2. Painel lateral de ações (principal/nomear/mover/excluir) ║
  8. ║ 3. Botão voltar no painel lateral ║
  9. ║ 4. Interface sem emojis - ícones profissionais ║
  10. ╚══════════════════════════════════════════════════════════════════════╝
  11. ]]
  12.  
  13. -- ============================================================
  14. -- SEÇÃO 1 ► AGUARDAR CARREGAMENTO DO JOGO
  15. -- ============================================================
  16.  
  17. if not game:IsLoaded() then
  18. game.Loaded:Wait()
  19. end
  20.  
  21. -- ============================================================
  22. -- SEÇÃO 2 ► SERVIÇOS
  23. -- ============================================================
  24.  
  25. local Players = game:GetService("Players")
  26. local HttpService = game:GetService("HttpService")
  27. local TweenService = game:GetService("TweenService")
  28. local UserInputService = game:GetService("UserInputService")
  29. local RunService = game:GetService("RunService")
  30. local CoreGui = game:GetService("CoreGui")
  31.  
  32. -- ============================================================
  33. -- SEÇÃO 3 ► REFERÊNCIAS DO JOGADOR
  34. -- ============================================================
  35.  
  36. local plr = Players.LocalPlayer
  37. local chr = plr.Character or plr.CharacterAdded:Wait()
  38. local root = chr:WaitForChild("HumanoidRootPart")
  39.  
  40. -- ============================================================
  41. -- SEÇÃO 4 ► CONSTANTES DE CONFIGURAÇÃO
  42. -- ============================================================
  43.  
  44. local CFG = {
  45. MAX_SAVES = 50,
  46. SLOTS_PER_PAGE = 10,
  47. MAX_PAGES = 5,
  48. SAVE_DIR = "SaveLocate_NickZ",
  49. VERSION = "5.2",
  50. TWEEN_FAST = TweenInfo.new(0.18, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
  51. TWEEN_MED = TweenInfo.new(0.28, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
  52. TWEEN_SLOW = TweenInfo.new(0.45, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
  53. }
  54.  
  55. -- Paleta de cores centralizada
  56. local CLR = {
  57. BG_DARK = Color3.fromRGB(14, 12, 22),
  58. BG_MID = Color3.fromRGB(22, 19, 35),
  59. BG_LIGHT = Color3.fromRGB(32, 28, 50),
  60. BG_CARD = Color3.fromRGB(28, 25, 42),
  61. BG_CARD_HOV = Color3.fromRGB(38, 34, 58),
  62. ACCENT = Color3.fromRGB(110, 80, 255),
  63. ACCENT_HOV = Color3.fromRGB(135, 105, 255),
  64. ACCENT_DIM = Color3.fromRGB(70, 55, 160),
  65. SUCCESS = Color3.fromRGB(60, 200, 110),
  66. SUCCESS_HOV = Color3.fromRGB(80, 225, 130),
  67. DANGER = Color3.fromRGB(220, 70, 70),
  68. DANGER_HOV = Color3.fromRGB(240, 95, 95),
  69. WARNING = Color3.fromRGB(220, 160, 40),
  70. INFO = Color3.fromRGB(70, 150, 230),
  71. INFO_HOV = Color3.fromRGB(90, 170, 250),
  72. TEXT_PRI = Color3.fromRGB(240, 238, 255),
  73. TEXT_SEC = Color3.fromRGB(170, 165, 200),
  74. TEXT_DIM = Color3.fromRGB(110, 105, 140),
  75. TEXT_MUTED = Color3.fromRGB(75, 70, 100),
  76. SLOT_NUM = Color3.fromRGB(110, 80, 255),
  77. GOLD = Color3.fromRGB(255, 210, 60),
  78. STROKE = Color3.fromRGB(80, 65, 160),
  79. STROKE_BRIGHT= Color3.fromRGB(120, 95, 255),
  80. OVERLAY = Color3.fromRGB(5, 4, 10),
  81. WHITE = Color3.new(1, 1, 1),
  82. }
  83.  
  84. -- ============================================================
  85. -- SEÇÃO 5 ► SISTEMA DE FILESYSTEM
  86. -- ============================================================
  87.  
  88. local FS = {}
  89. do
  90. FS.canWrite = type(writefile) == "function"
  91. FS.canRead = type(readfile) == "function"
  92. FS.canFolder = type(isfolder) == "function" and type(makefolder) == "function"
  93. FS.canIsFile = type(isfile) == "function"
  94. FS.canDelete = type(delfile) == "function"
  95. FS.active = FS.canWrite and FS.canRead
  96.  
  97. local GAME_ID = tostring(game.PlaceId)
  98. local USER_ID = tostring(plr.UserId)
  99. local BASE_DIR = CFG.SAVE_DIR .. "/" .. GAME_ID
  100.  
  101. if FS.canFolder then
  102. if not isfolder(CFG.SAVE_DIR) then pcall(makefolder, CFG.SAVE_DIR) end
  103. if not isfolder(BASE_DIR) then pcall(makefolder, BASE_DIR) end
  104. end
  105.  
  106. if FS.canFolder then
  107. FS.SAVE_FILE = BASE_DIR .. "/Saves_" .. USER_ID .. ".json"
  108. FS.SAVE_BAK = BASE_DIR .. "/Saves_" .. USER_ID .. ".bak"
  109. FS.MAIN_FILE = BASE_DIR .. "/MainPos_" .. USER_ID .. ".json"
  110. FS.MAIN_BAK = BASE_DIR .. "/MainPos_" .. USER_ID .. ".bak"
  111. else
  112. local prefix = string.format("%s_%s_%s", CFG.SAVE_DIR, GAME_ID, USER_ID)
  113. FS.SAVE_FILE = prefix .. "_Saves.json"
  114. FS.SAVE_BAK = prefix .. "_Saves.bak"
  115. FS.MAIN_FILE = prefix .. "_Main.json"
  116. FS.MAIN_BAK = prefix .. "_Main.bak"
  117. end
  118.  
  119. FS.LEGACY_PATHS_SAVES = {
  120. string.format("SkyTP/Saves_%s_%s.json", game.PlaceId, plr.UserId),
  121. string.format("SkyTP/Saves_%s_%s.bak", game.PlaceId, plr.UserId),
  122. string.format("Saves_%s_%s.json", game.PlaceId, plr.UserId),
  123. string.format("Saves_%s_%s.bak", game.PlaceId, plr.UserId),
  124. }
  125. FS.LEGACY_PATHS_MAIN = {
  126. string.format("SkyTP/MainPos_%s_%s.json", game.PlaceId, plr.UserId),
  127. string.format("SkyTP/MainPos_%s_%s.bak", game.PlaceId, plr.UserId),
  128. string.format("MainPos_%s_%s.json", game.PlaceId, plr.UserId),
  129. string.format("MainPos_%s_%s.bak", game.PlaceId, plr.UserId),
  130. }
  131.  
  132. function FS.read(path)
  133. if not FS.active or type(path) ~= "string" then return nil end
  134. local ok, content = pcall(readfile, path)
  135. if ok and type(content) == "string" and #content > 2 then return content end
  136. return nil
  137. end
  138.  
  139. function FS.readFirst(paths)
  140. for _, p in ipairs(paths) do
  141. local content = FS.read(p)
  142. if content then return content, p end
  143. end
  144. return nil, nil
  145. end
  146.  
  147. function FS.writeSafe(primary, backup, content)
  148. if not FS.active then return false end
  149. local ok1 = pcall(writefile, primary, content)
  150. local ok2 = pcall(writefile, backup, content)
  151. return ok1 or ok2
  152. end
  153.  
  154. function FS.delete(path)
  155. if FS.active and FS.canDelete and type(path) == "string" then
  156. pcall(delfile, path)
  157. end
  158. end
  159. end
  160.  
  161. -- ============================================================
  162. -- SEÇÃO 6 ► CODIFICADOR DE CFRAME
  163. -- ============================================================
  164.  
  165. local Codec = {}
  166. do
  167. function Codec.encode(cf)
  168. if typeof(cf) ~= "CFrame" then return nil end
  169. local x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22 = cf:GetComponents()
  170. return { x=x, y=y, z=z, m={r00,r01,r02,r10,r11,r12,r20,r21,r22} }
  171. end
  172.  
  173. function Codec.decode(t)
  174. if type(t) ~= "table" then return nil end
  175. if t.R00 ~= nil then
  176. return CFrame.new(t.x,t.y,t.z,
  177. t.R00,t.R01,t.R02,t.R10,t.R11,t.R12,t.R20,t.R21,t.R22)
  178. end
  179. if t.x and t.m and #t.m == 9 then
  180. local m = t.m
  181. return CFrame.new(t.x,t.y,t.z,m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9])
  182. end
  183. return nil
  184. end
  185.  
  186. function Codec.jsonEncode(data)
  187. local ok, result = pcall(function() return HttpService:JSONEncode(data) end)
  188. return ok and result or nil
  189. end
  190.  
  191. function Codec.jsonDecode(str)
  192. if type(str) ~= "string" or #str < 2 then return nil end
  193. local ok, result = pcall(function() return HttpService:JSONDecode(str) end)
  194. return ok and result or nil
  195. end
  196. end
  197.  
  198. -- ============================================================
  199. -- SEÇÃO 7 ► ESTADO GLOBAL
  200. -- ============================================================
  201.  
  202. local State = {
  203. saves = {},
  204. mainPos = nil,
  205. currentPage = 1,
  206. saveSlot = 1,
  207. isDirty = false,
  208. connections = {},
  209. optionFrames = {},
  210. }
  211.  
  212. -- ============================================================
  213. -- SEÇÃO 8 ► PERSISTÊNCIA
  214. -- ============================================================
  215.  
  216. local Persist = {}
  217. do
  218. function Persist.buildSavePayload()
  219. local positions = {}
  220. for slot, data in pairs(State.saves) do
  221. if type(slot) == "number" and slot >= 1 and slot <= CFG.MAX_SAVES
  222. and typeof(data.position) == "CFrame" then
  223. positions[tostring(slot)] = {
  224. name = data.name or ("Slot " .. slot),
  225. timestamp = data.timestamp or os.date("%Y-%m-%d %H:%M:%S"),
  226. position = Codec.encode(data.position),
  227. }
  228. end
  229. end
  230. return {
  231. version = CFG.VERSION,
  232. gameId = game.PlaceId,
  233. gameName = game.Name,
  234. userId = plr.UserId,
  235. userName = plr.Name,
  236. savedAt = os.date("%Y-%m-%d %H:%M:%S"),
  237. positions = positions,
  238. }
  239. end
  240.  
  241. function Persist.save()
  242. if not FS.active then return end
  243. local payload = Codec.jsonEncode(Persist.buildSavePayload())
  244. if payload then FS.writeSafe(FS.SAVE_FILE, FS.SAVE_BAK, payload) end
  245. if State.mainPos then
  246. local mainPayload = Codec.jsonEncode({
  247. version = CFG.VERSION,
  248. gameId = game.PlaceId,
  249. gameName = game.Name,
  250. name = State.mainPos.name,
  251. timestamp = State.mainPos.timestamp,
  252. position = Codec.encode(State.mainPos.position),
  253. })
  254. if mainPayload then FS.writeSafe(FS.MAIN_FILE, FS.MAIN_BAK, mainPayload) end
  255. end
  256. State.isDirty = false
  257. end
  258.  
  259. function Persist.load()
  260. if not FS.active then return end
  261. local candidates = {FS.SAVE_FILE, FS.SAVE_BAK}
  262. for _, p in ipairs(FS.LEGACY_PATHS_SAVES) do table.insert(candidates, p) end
  263. local content, usedPath = FS.readFirst(candidates)
  264. if content then
  265. local data = Codec.jsonDecode(content)
  266. if data and type(data) == "table" then
  267. if not data.gameId or data.gameId == game.PlaceId then
  268. local positions = data.positions or data
  269. for k, v in pairs(positions) do
  270. local slot = tonumber(k)
  271. if slot and slot >= 1 and slot <= CFG.MAX_SAVES and type(v) == "table" then
  272. local cf = Codec.decode(v.position)
  273. if cf then
  274. State.saves[slot] = {
  275. position = cf,
  276. name = v.name or ("Slot " .. slot),
  277. timestamp = v.timestamp or os.date("%Y-%m-%d %H:%M:%S"),
  278. }
  279. end
  280. end
  281. end
  282. if usedPath ~= FS.SAVE_FILE then Persist.save() end
  283. end
  284. end
  285. end
  286. local mainCandidates = {FS.MAIN_FILE, FS.MAIN_BAK}
  287. for _, p in ipairs(FS.LEGACY_PATHS_MAIN) do table.insert(mainCandidates, p) end
  288. local mainContent, mainUsedPath = FS.readFirst(mainCandidates)
  289. if mainContent then
  290. local data = Codec.jsonDecode(mainContent)
  291. if data and type(data) == "table" then
  292. if not data.gameId or data.gameId == game.PlaceId then
  293. local cf = Codec.decode(data.position)
  294. if cf then
  295. State.mainPos = {
  296. position = cf,
  297. name = data.name or "Posicao Principal",
  298. timestamp = data.timestamp or os.date("%Y-%m-%d %H:%M:%S"),
  299. }
  300. if mainUsedPath ~= FS.MAIN_FILE then Persist.save() end
  301. end
  302. end
  303. end
  304. end
  305. end
  306.  
  307. local saveDebounce = false
  308. function Persist.scheduleSave()
  309. State.isDirty = true
  310. if saveDebounce then return end
  311. saveDebounce = true
  312. task.delay(0.5, function()
  313. if State.isDirty then Persist.save() end
  314. saveDebounce = false
  315. end)
  316. end
  317.  
  318. function Persist.deleteMain()
  319. FS.delete(FS.MAIN_FILE)
  320. FS.delete(FS.MAIN_BAK)
  321. end
  322. end
  323.  
  324. -- ============================================================
  325. -- SEÇÃO 9 ► TELEPORTE ANTI-BUG
  326. -- ============================================================
  327.  
  328. local Teleport = {}
  329. do
  330. function Teleport.refreshCharacter()
  331. chr = plr.Character
  332. root = chr and chr:FindFirstChild("HumanoidRootPart")
  333. end
  334.  
  335. function Teleport.to(targetCFrame)
  336. if not targetCFrame then return false end
  337. if not chr or not chr.Parent then Teleport.refreshCharacter() end
  338. if not root then return false end
  339. local hum = chr:FindFirstChildWhichIsA("Humanoid")
  340. if hum and hum.SeatPart then hum.Sit = false; task.wait(0.05) end
  341. local wasAnchored = root.Anchored
  342. root.Anchored = true
  343. if root:IsA("BasePart") then
  344. root.AssemblyLinearVelocity = Vector3.zero
  345. root.AssemblyAngularVelocity = Vector3.zero
  346. end
  347. root.CFrame = targetCFrame
  348. RunService.Heartbeat:Wait()
  349. root.CFrame = targetCFrame
  350. root.Anchored = wasAnchored
  351. return true
  352. end
  353. end
  354.  
  355. -- ============================================================
  356. -- SEÇÃO 10 ► UTILITÁRIOS DE UI
  357. -- ============================================================
  358.  
  359. local UI = {}
  360. do
  361. function UI.corner(parent, radius)
  362. local c = Instance.new("UICorner")
  363. c.CornerRadius = UDim.new(0, radius or 8)
  364. c.Parent = parent
  365. return c
  366. end
  367.  
  368. function UI.stroke(parent, color, thickness)
  369. local s = Instance.new("UIStroke")
  370. s.Color = color or CLR.STROKE
  371. s.Thickness = thickness or 1.5
  372. s.Parent = parent
  373. return s
  374. end
  375.  
  376. function UI.gradient(parent, colorA, colorB, rotation)
  377. local g = Instance.new("UIGradient")
  378. g.Color = ColorSequence.new({
  379. ColorSequenceKeypoint.new(0, colorA),
  380. ColorSequenceKeypoint.new(1, colorB),
  381. })
  382. g.Rotation = rotation or 90
  383. g.Parent = parent
  384. return g
  385. end
  386.  
  387. function UI.hoverBG(button, hoverColor, baseColor)
  388. button.MouseEnter:Connect(function()
  389. TweenService:Create(button, CFG.TWEEN_FAST, {BackgroundColor3 = hoverColor}):Play()
  390. end)
  391. button.MouseLeave:Connect(function()
  392. TweenService:Create(button, CFG.TWEEN_FAST, {BackgroundColor3 = baseColor}):Play()
  393. end)
  394. end
  395.  
  396. function UI.closeAllOptionMenus(except)
  397. for _, frame in pairs(State.optionFrames) do
  398. if frame ~= except and frame and frame.Parent then
  399. frame.Visible = false
  400. end
  401. end
  402. end
  403.  
  404. function UI.label(parent, props)
  405. local l = Instance.new("TextLabel")
  406. l.BackgroundTransparency = 1
  407. l.Font = props.font or Enum.Font.Gotham
  408. l.TextSize = props.size or 14
  409. l.TextColor3 = props.color or CLR.TEXT_PRI
  410. l.Text = props.text or ""
  411. l.TextXAlignment = props.align or Enum.TextXAlignment.Left
  412. l.TextWrapped = props.wrap or false
  413. l.TextTruncate = props.truncate or Enum.TextTruncate.None
  414. l.Size = props.sz or UDim2.new(1, 0, 1, 0)
  415. l.Position = props.pos or UDim2.new(0, 0, 0, 0)
  416. l.TextStrokeTransparency = 1
  417. l.Parent = parent
  418. return l
  419. end
  420.  
  421. function UI.button(parent, props)
  422. local b = Instance.new("TextButton")
  423. b.Font = props.font or Enum.Font.GothamSemibold
  424. b.TextSize = props.size or 14
  425. b.TextColor3 = props.textColor or CLR.WHITE
  426. b.Text = props.text or ""
  427. b.BackgroundColor3 = props.bgColor or CLR.ACCENT
  428. b.Size = props.sz or UDim2.new(0, 80, 0, 30)
  429. b.Position = props.pos or UDim2.new(0, 0, 0, 0)
  430. b.AutoButtonColor = false
  431. b.BorderSizePixel = 0
  432. b.TextStrokeTransparency = 1
  433. b.Parent = parent
  434. UI.corner(b, props.radius or 7)
  435. if props.hoverColor then
  436. UI.hoverBG(b, props.hoverColor, props.bgColor)
  437. end
  438. return b
  439. end
  440. end
  441.  
  442. -- ============================================================
  443. -- SEÇÃO 11 ► CONSTRUÇÃO DA GUI
  444. -- ============================================================
  445.  
  446. do
  447. local old = CoreGui:FindFirstChild("SaveLocate_NickZ_V5")
  448. if old then old:Destroy() end
  449. end
  450.  
  451. local ScreenGui = Instance.new("ScreenGui")
  452. ScreenGui.Name = "SaveLocate_NickZ_V5"
  453. ScreenGui.DisplayOrder = 999
  454. ScreenGui.ResetOnSpawn = false
  455. ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
  456. ScreenGui.IgnoreGuiInset = true
  457. ScreenGui.Parent = CoreGui
  458.  
  459. -- ────────────────────────────────────────────────
  460. -- 11.1 ► JANELA PRINCIPAL
  461. -- ────────────────────────────────────────────────
  462.  
  463. local MainFrame = Instance.new("Frame")
  464. MainFrame.Name = "MainFrame"
  465. MainFrame.Size = UDim2.new(0, 590, 0, 470)
  466. MainFrame.Position = UDim2.new(0.5, -295, 0.5, -235)
  467. MainFrame.BackgroundColor3 = CLR.BG_DARK
  468. MainFrame.BorderSizePixel = 0
  469. MainFrame.Active = true
  470. MainFrame.Draggable = true
  471. MainFrame.ClipsDescendants = true
  472. MainFrame.Parent = ScreenGui
  473.  
  474. UI.corner(MainFrame, 10)
  475. UI.stroke(MainFrame, CLR.STROKE_BRIGHT, 1.5)
  476. UI.gradient(MainFrame, CLR.BG_MID, CLR.BG_DARK, 135)
  477.  
  478. -- ────────────────────────────────────────────────
  479. -- 11.2 ► BARRA DE TITULO
  480. -- ────────────────────────────────────────────────
  481.  
  482. local TitleBar = Instance.new("Frame")
  483. TitleBar.Name = "TitleBar"
  484. TitleBar.Size = UDim2.new(1, 0, 0, 44)
  485. TitleBar.BackgroundColor3 = CLR.BG_MID
  486. TitleBar.BorderSizePixel = 0
  487. TitleBar.Parent = MainFrame
  488. UI.corner(TitleBar, 10)
  489.  
  490. local TitleDivider = Instance.new("Frame")
  491. TitleDivider.Size = UDim2.new(1, 0, 0, 1)
  492. TitleDivider.Position = UDim2.new(0, 0, 1, -1)
  493. TitleDivider.BackgroundColor3 = CLR.STROKE
  494. TitleDivider.BorderSizePixel = 0
  495. TitleDivider.Parent = TitleBar
  496.  
  497. -- Icone decorativo (sem emoji - caractere unicode limpo)
  498. UI.label(TitleBar, {
  499. text = "+",
  500. sz = UDim2.new(0, 30, 1, 0),
  501. pos = UDim2.new(0, 12, 0, 0),
  502. size = 20,
  503. color = CLR.ACCENT,
  504. font = Enum.Font.GothamBold,
  505. align = Enum.TextXAlignment.Center,
  506. })
  507.  
  508. UI.label(TitleBar, {
  509. text = "Save Locate / NickZ",
  510. sz = UDim2.new(1, -150, 1, 0),
  511. pos = UDim2.new(0, 46, 0, 0),
  512. size = 16,
  513. color = CLR.TEXT_PRI,
  514. font = Enum.Font.GothamBold,
  515. align = Enum.TextXAlignment.Left,
  516. })
  517.  
  518. local VersionBadge = Instance.new("Frame")
  519. VersionBadge.Size = UDim2.new(0, 42, 0, 20)
  520. VersionBadge.Position = UDim2.new(1, -122, 0.5, -10)
  521. VersionBadge.BackgroundColor3 = CLR.ACCENT_DIM
  522. VersionBadge.Parent = TitleBar
  523. UI.corner(VersionBadge, 5)
  524. UI.label(VersionBadge, {
  525. text = "V 5.2",
  526. size = 10,
  527. color = CLR.TEXT_PRI,
  528. font = Enum.Font.GothamBold,
  529. align = Enum.TextXAlignment.Center,
  530. })
  531.  
  532. -- Botao fechar totalmente (icone de power sem emoji)
  533. local DestroyBtn = UI.button(TitleBar, {
  534. text = "O",
  535. sz = UDim2.new(0, 28, 0, 28),
  536. pos = UDim2.new(1, -68, 0.5, -14),
  537. bgColor = CLR.BG_LIGHT,
  538. hoverColor = Color3.fromRGB(160, 60, 60),
  539. textColor = CLR.TEXT_DIM,
  540. font = Enum.Font.GothamBold,
  541. size = 13,
  542. radius = 7,
  543. })
  544.  
  545. -- Botao minimizar (X)
  546. local CloseBtn = UI.button(TitleBar, {
  547. text = "X",
  548. sz = UDim2.new(0, 28, 0, 28),
  549. pos = UDim2.new(1, -36, 0.5, -14),
  550. bgColor = CLR.BG_LIGHT,
  551. hoverColor = CLR.DANGER,
  552. textColor = CLR.TEXT_SEC,
  553. font = Enum.Font.GothamBold,
  554. size = 13,
  555. radius = 7,
  556. })
  557.  
  558. -- ────────────────────────────────────────────────
  559. -- 11.3 ► CONTROLES (Salvar / Nome / Slot)
  560. -- ────────────────────────────────────────────────
  561.  
  562. local CtrlFrame = Instance.new("Frame")
  563. CtrlFrame.Name = "Controls"
  564. CtrlFrame.Size = UDim2.new(1, -20, 0, 96)
  565. CtrlFrame.Position = UDim2.new(0, 10, 0, 50)
  566. CtrlFrame.BackgroundColor3 = CLR.BG_MID
  567. CtrlFrame.BorderSizePixel = 0
  568. CtrlFrame.Parent = MainFrame
  569. UI.corner(CtrlFrame, 8)
  570. UI.stroke(CtrlFrame, CLR.STROKE, 1)
  571.  
  572. local SaveBtn = UI.button(CtrlFrame, {
  573. text = "+ Salvar Posicao",
  574. sz = UDim2.new(0, 175, 0, 36),
  575. pos = UDim2.new(0, 10, 0, 10),
  576. bgColor = CLR.SUCCESS,
  577. hoverColor = CLR.SUCCESS_HOV,
  578. textColor = CLR.WHITE,
  579. font = Enum.Font.GothamBold,
  580. size = 14,
  581. radius = 7,
  582. })
  583.  
  584. local NameBox = Instance.new("TextBox")
  585. NameBox.Name = "NameBox"
  586. NameBox.PlaceholderText = " Nome da posicao..."
  587. NameBox.Size = UDim2.new(1, -200, 0, 36)
  588. NameBox.Position = UDim2.new(0, 10, 0, 50)
  589. NameBox.BackgroundColor3 = CLR.BG_DARK
  590. NameBox.TextColor3 = CLR.TEXT_PRI
  591. NameBox.PlaceholderColor3 = CLR.TEXT_MUTED
  592. NameBox.Font = Enum.Font.Gotham
  593. NameBox.TextSize = 13
  594. NameBox.ClearTextOnFocus = false
  595. NameBox.TextXAlignment = Enum.TextXAlignment.Left
  596. NameBox.Parent = CtrlFrame
  597. UI.corner(NameBox, 7)
  598. UI.stroke(NameBox, CLR.STROKE, 1)
  599.  
  600. local SlotPanel = Instance.new("Frame")
  601. SlotPanel.Name = "SlotPanel"
  602. SlotPanel.Size = UDim2.new(0, 175, 0, 76)
  603. SlotPanel.Position = UDim2.new(1, -185, 0, 10)
  604. SlotPanel.BackgroundColor3 = CLR.BG_DARK
  605. SlotPanel.BorderSizePixel = 0
  606. SlotPanel.Parent = CtrlFrame
  607. UI.corner(SlotPanel, 7)
  608. UI.stroke(SlotPanel, CLR.STROKE, 1)
  609.  
  610. UI.label(SlotPanel, {
  611. text = "SLOT DE DESTINO",
  612. sz = UDim2.new(1, 0, 0, 20),
  613. pos = UDim2.new(0, 0, 0, 4),
  614. size = 9,
  615. color = CLR.TEXT_DIM,
  616. font = Enum.Font.GothamBold,
  617. align = Enum.TextXAlignment.Center,
  618. })
  619.  
  620. local SlotValueLbl = UI.label(SlotPanel, {
  621. text = "01",
  622. sz = UDim2.new(0, 50, 0, 30),
  623. pos = UDim2.new(0.5, -25, 0, 22),
  624. size = 22,
  625. color = CLR.ACCENT,
  626. font = Enum.Font.GothamBold,
  627. align = Enum.TextXAlignment.Center,
  628. })
  629.  
  630. local SlotPrevBtn = UI.button(SlotPanel, {
  631. text = "<",
  632. sz = UDim2.new(0, 32, 0, 28),
  633. pos = UDim2.new(0, 6, 0, 24),
  634. bgColor = CLR.ACCENT_DIM,
  635. hoverColor = CLR.ACCENT,
  636. size = 16,
  637. radius = 6,
  638. })
  639.  
  640. local SlotNextBtn = UI.button(SlotPanel, {
  641. text = ">",
  642. sz = UDim2.new(0, 32, 0, 28),
  643. pos = UDim2.new(1, -38, 0, 24),
  644. bgColor = CLR.ACCENT_DIM,
  645. hoverColor = CLR.ACCENT,
  646. size = 16,
  647. radius = 6,
  648. })
  649.  
  650. local SlotStatusLbl = UI.label(SlotPanel, {
  651. text = "livre",
  652. sz = UDim2.new(1, 0, 0, 14),
  653. pos = UDim2.new(0, 0, 1, -16),
  654. size = 9,
  655. color = CLR.SUCCESS,
  656. font = Enum.Font.GothamSemibold,
  657. align = Enum.TextXAlignment.Center,
  658. })
  659.  
  660. -- ────────────────────────────────────────────────
  661. -- 11.4 ► BARRA DE PAGINACAO
  662. -- ────────────────────────────────────────────────
  663.  
  664. local PageBar = Instance.new("Frame")
  665. PageBar.Name = "PageBar"
  666. PageBar.Size = UDim2.new(1, -20, 0, 34)
  667. PageBar.Position = UDim2.new(0, 10, 0, 152)
  668. PageBar.BackgroundColor3 = CLR.BG_MID
  669. PageBar.BorderSizePixel = 0
  670. PageBar.Parent = MainFrame
  671. UI.corner(PageBar, 7)
  672. UI.stroke(PageBar, CLR.STROKE, 1)
  673.  
  674. local PagePrevBtn = UI.button(PageBar, {
  675. text = "<<",
  676. sz = UDim2.new(0, 70, 0, 26),
  677. pos = UDim2.new(0, 4, 0.5, -13),
  678. bgColor = CLR.BG_LIGHT,
  679. hoverColor = CLR.ACCENT_DIM,
  680. size = 11,
  681. radius = 6,
  682. })
  683.  
  684. local PageLabel = UI.label(PageBar, {
  685. text = "PAGINA 1 / 5",
  686. sz = UDim2.new(1, -160, 1, 0),
  687. pos = UDim2.new(0, 80, 0, 0),
  688. size = 12,
  689. color = CLR.TEXT_SEC,
  690. font = Enum.Font.GothamBold,
  691. align = Enum.TextXAlignment.Center,
  692. })
  693.  
  694. local PageDotsFrame = Instance.new("Frame")
  695. PageDotsFrame.Size = UDim2.new(0, 70, 0, 10)
  696. PageDotsFrame.Position = UDim2.new(0.5, -35, 1, -13)
  697. PageDotsFrame.BackgroundTransparency = 1
  698. PageDotsFrame.Parent = PageBar
  699.  
  700. local PageDotLayout = Instance.new("UIListLayout")
  701. PageDotLayout.FillDirection = Enum.FillDirection.Horizontal
  702. PageDotLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
  703. PageDotLayout.Padding = UDim.new(0, 6)
  704. PageDotLayout.Parent = PageDotsFrame
  705.  
  706. local PageDots = {}
  707. for i = 1, CFG.MAX_PAGES do
  708. local dot = Instance.new("Frame")
  709. dot.Size = UDim2.new(0, 7, 0, 7)
  710. dot.BackgroundColor3 = (i == 1) and CLR.ACCENT or CLR.TEXT_MUTED
  711. dot.Parent = PageDotsFrame
  712. UI.corner(dot, 4)
  713. PageDots[i] = dot
  714. end
  715.  
  716. local PageNextBtn = UI.button(PageBar, {
  717. text = ">>",
  718. sz = UDim2.new(0, 70, 0, 26),
  719. pos = UDim2.new(1, -74, 0.5, -13),
  720. bgColor = CLR.BG_LIGHT,
  721. hoverColor = CLR.ACCENT_DIM,
  722. size = 11,
  723. radius = 6,
  724. })
  725.  
  726. -- ────────────────────────────────────────────────
  727. -- 11.5 ► GRID DE SLOTS
  728. -- ────────────────────────────────────────────────
  729.  
  730. local SlotsFrame = Instance.new("Frame")
  731. SlotsFrame.Name = "Slots"
  732. SlotsFrame.Size = UDim2.new(1, -20, 1, -198)
  733. SlotsFrame.Position = UDim2.new(0, 10, 0, 194)
  734. SlotsFrame.BackgroundTransparency = 1
  735. SlotsFrame.Parent = MainFrame
  736.  
  737. local GridLayout = Instance.new("UIGridLayout")
  738. GridLayout.CellPadding = UDim2.new(0, 7, 0, 7)
  739. GridLayout.CellSize = UDim2.new(0.5, -4, 0, 48)
  740. GridLayout.FillDirection = Enum.FillDirection.Horizontal
  741. GridLayout.SortOrder = Enum.SortOrder.LayoutOrder
  742. GridLayout.Parent = SlotsFrame
  743.  
  744. -- ────────────────────────────────────────────────
  745. -- 11.6 ► BOTAO FLUTUANTE
  746. -- ────────────────────────────────────────────────
  747.  
  748. local FloatContainer = Instance.new("Frame")
  749. FloatContainer.Name = "FloatBtn"
  750. FloatContainer.Size = UDim2.new(0, 46, 0, 46)
  751. FloatContainer.Position = UDim2.new(0, 16, 0.5, -23)
  752. FloatContainer.BackgroundTransparency = 1
  753. FloatContainer.Active = true
  754. FloatContainer.Draggable = true
  755. FloatContainer.Visible = false
  756. FloatContainer.Parent = ScreenGui
  757.  
  758. local FloatBtn = UI.button(FloatContainer, {
  759. text = "SL",
  760. sz = UDim2.new(1, 0, 1, 0),
  761. bgColor = CLR.BG_MID,
  762. hoverColor = CLR.BG_LIGHT,
  763. textColor = CLR.ACCENT,
  764. font = Enum.Font.GothamBold,
  765. size = 14,
  766. radius = 10,
  767. })
  768. UI.stroke(FloatBtn, CLR.STROKE_BRIGHT, 1.5)
  769.  
  770. -- ────────────────────────────────────────────────
  771. -- 11.7 ► BOTAO POSICAO PRINCIPAL (flutuante)
  772. -- ────────────────────────────────────────────────
  773.  
  774. local MainPosContainer = Instance.new("Frame")
  775. MainPosContainer.Name = "MainPosBtn"
  776. MainPosContainer.Size = UDim2.new(0, 50, 0, 50)
  777. MainPosContainer.Position = UDim2.new(1, -64, 0, 14)
  778. MainPosContainer.BackgroundTransparency = 1
  779. MainPosContainer.Active = true
  780. MainPosContainer.Draggable = true
  781. MainPosContainer.Visible = false
  782. MainPosContainer.Parent = ScreenGui
  783.  
  784. local MainPosBtn = UI.button(MainPosContainer, {
  785. text = ">>",
  786. sz = UDim2.new(1, 0, 1, 0),
  787. bgColor = CLR.BG_MID,
  788. hoverColor = CLR.BG_LIGHT,
  789. textColor = CLR.ACCENT,
  790. font = Enum.Font.GothamBold,
  791. size = 14,
  792. radius = 25,
  793. })
  794. local MainPosStroke = UI.stroke(MainPosBtn, CLR.ACCENT, 2)
  795.  
  796. local MainPosTooltip = Instance.new("Frame")
  797. MainPosTooltip.Name = "Tooltip"
  798. MainPosTooltip.Size = UDim2.new(0, 160, 0, 32)
  799. MainPosTooltip.Position = UDim2.new(-3.4, 0, 0.5, -16)
  800. MainPosTooltip.BackgroundColor3 = CLR.BG_MID
  801. MainPosTooltip.BackgroundTransparency = 0.05
  802. MainPosTooltip.Visible = false
  803. MainPosTooltip.ZIndex = 5
  804. MainPosTooltip.Parent = MainPosBtn
  805. UI.corner(MainPosTooltip, 7)
  806. UI.stroke(MainPosTooltip, CLR.ACCENT, 1)
  807.  
  808. local TooltipLabel = UI.label(MainPosTooltip, {
  809. text = "",
  810. sz = UDim2.new(1, -8, 1, 0),
  811. pos = UDim2.new(0, 4, 0, 0),
  812. size = 11,
  813. color = CLR.TEXT_PRI,
  814. font = Enum.Font.GothamSemibold,
  815. align = Enum.TextXAlignment.Center,
  816. wrap = true,
  817. })
  818. TooltipLabel.ZIndex = 6
  819.  
  820. local MainPosRemoveBtn = UI.button(MainPosBtn, {
  821. text = "X",
  822. sz = UDim2.new(0, 18, 0, 18),
  823. pos = UDim2.new(1, -4, 0, -4),
  824. bgColor = CLR.DANGER,
  825. hoverColor = CLR.DANGER_HOV,
  826. textColor = CLR.WHITE,
  827. size = 10,
  828. radius = 9,
  829. })
  830. MainPosRemoveBtn.Visible = false
  831. MainPosRemoveBtn.ZIndex = 6
  832.  
  833. -- ────────────────────────────────────────────────
  834. -- 11.8 ► TOAST DE NOTIFICACAO
  835. -- ────────────────────────────────────────────────
  836.  
  837. local ToastFrame = Instance.new("Frame")
  838. ToastFrame.Name = "Toast"
  839. ToastFrame.Size = UDim2.new(0, 260, 0, 38)
  840. ToastFrame.Position = UDim2.new(0.5, -130, 0, -50)
  841. ToastFrame.BackgroundColor3 = CLR.BG_MID
  842. ToastFrame.BackgroundTransparency = 0.05
  843. ToastFrame.Visible = false
  844. ToastFrame.ZIndex = 99
  845. ToastFrame.Parent = ScreenGui
  846. UI.corner(ToastFrame, 8)
  847. local ToastStroke = UI.stroke(ToastFrame, CLR.SUCCESS, 1.5)
  848.  
  849. local ToastLabel = UI.label(ToastFrame, {
  850. text = "",
  851. sz = UDim2.new(1, -16, 1, 0),
  852. pos = UDim2.new(0, 8, 0, 0),
  853. size = 13,
  854. color = CLR.TEXT_PRI,
  855. font = Enum.Font.GothamSemibold,
  856. align = Enum.TextXAlignment.Center,
  857. })
  858. ToastLabel.ZIndex = 100
  859.  
  860. local toastActive = false
  861. local function showToast(message, toastType)
  862. local colorMap = {
  863. success = CLR.SUCCESS,
  864. error = CLR.DANGER,
  865. info = CLR.INFO,
  866. warning = CLR.WARNING,
  867. }
  868. local color = colorMap[toastType] or CLR.SUCCESS
  869. ToastStroke.Color = color
  870. ToastLabel.Text = message
  871. ToastLabel.TextColor3 = color
  872. ToastFrame.Visible = true
  873. toastActive = true
  874. TweenService:Create(ToastFrame, CFG.TWEEN_MED,
  875. {Position = UDim2.new(0.5, -130, 0, 12)}):Play()
  876. task.delay(2.2, function()
  877. if toastActive then
  878. TweenService:Create(ToastFrame, CFG.TWEEN_MED,
  879. {Position = UDim2.new(0.5, -130, 0, -50)}):Play()
  880. task.wait(0.35)
  881. ToastFrame.Visible = false
  882. toastActive = false
  883. end
  884. end)
  885. end
  886.  
  887. -- ────────────────────────────────────────────────
  888. -- 11.9 ► MODAIS (Confirmação / Renomear / Mover)
  889. -- ────────────────────────────────────────────────
  890.  
  891. local function createOverlay(parent, zIndex)
  892. local overlay = Instance.new("Frame")
  893. overlay.Size = UDim2.new(1, 0, 1, 0)
  894. overlay.BackgroundColor3 = CLR.OVERLAY
  895. overlay.BackgroundTransparency = 0.5
  896. overlay.Visible = false
  897. overlay.ZIndex = zIndex
  898. overlay.Parent = parent
  899. return overlay
  900. end
  901.  
  902. local function createModalFrame(parent, w, h, zIndex)
  903. local frame = Instance.new("Frame")
  904. frame.Size = UDim2.new(0, w, 0, h)
  905. frame.Position = UDim2.new(0.5, -w/2, 0.5, -h/2)
  906. frame.BackgroundColor3 = CLR.BG_MID
  907. frame.BorderSizePixel = 0
  908. frame.ZIndex = zIndex
  909. frame.Parent = parent
  910. UI.corner(frame, 10)
  911. UI.stroke(frame, CLR.STROKE_BRIGHT, 1.5)
  912. return frame
  913. end
  914.  
  915. -- Modal de Confirmacao
  916. local ConfirmOverlay = createOverlay(MainFrame, 20)
  917. local ConfirmFrame = createModalFrame(ConfirmOverlay, 310, 130, 21)
  918.  
  919. local ConfirmTitleBar = Instance.new("Frame")
  920. ConfirmTitleBar.Size = UDim2.new(1, 0, 0, 32)
  921. ConfirmTitleBar.BackgroundColor3 = CLR.BG_DARK
  922. ConfirmTitleBar.BorderSizePixel = 0
  923. ConfirmTitleBar.ZIndex = 22
  924. ConfirmTitleBar.Parent = ConfirmFrame
  925. UI.corner(ConfirmTitleBar, 10)
  926.  
  927. UI.label(ConfirmTitleBar, {
  928. text = "! Confirmar Acao",
  929. sz = UDim2.new(1, -16, 1, 0),
  930. pos = UDim2.new(0, 12, 0, 0),
  931. size = 13,
  932. color = CLR.TEXT_PRI,
  933. font = Enum.Font.GothamBold,
  934. align = Enum.TextXAlignment.Left,
  935. }).ZIndex = 23
  936.  
  937. local ConfirmLabel = UI.label(ConfirmFrame, {
  938. text = "",
  939. sz = UDim2.new(1, -20, 0, 40),
  940. pos = UDim2.new(0, 10, 0, 36),
  941. size = 13,
  942. color = CLR.TEXT_SEC,
  943. font = Enum.Font.Gotham,
  944. align = Enum.TextXAlignment.Center,
  945. wrap = true,
  946. })
  947. ConfirmLabel.ZIndex = 22
  948.  
  949. local ConfirmYesBtn = UI.button(ConfirmFrame, {
  950. text = "Confirmar",
  951. sz = UDim2.new(0.5, -12, 0, 32),
  952. pos = UDim2.new(0, 8, 1, -40),
  953. bgColor = CLR.DANGER,
  954. hoverColor = CLR.DANGER_HOV,
  955. size = 13,
  956. radius = 7,
  957. })
  958. ConfirmYesBtn.ZIndex = 22
  959.  
  960. local ConfirmNoBtn = UI.button(ConfirmFrame, {
  961. text = "Cancelar",
  962. sz = UDim2.new(0.5, -12, 0, 32),
  963. pos = UDim2.new(0.5, 4, 1, -40),
  964. bgColor = CLR.ACCENT_DIM,
  965. hoverColor = CLR.ACCENT,
  966. size = 13,
  967. radius = 7,
  968. })
  969. ConfirmNoBtn.ZIndex = 22
  970.  
  971. -- Modal de Renomear
  972. local RenameOverlay = createOverlay(MainFrame, 25)
  973. local RenameFrame = createModalFrame(RenameOverlay, 340, 155, 26)
  974.  
  975. local RenameTitleBar = Instance.new("Frame")
  976. RenameTitleBar.Size = UDim2.new(1, 0, 0, 32)
  977. RenameTitleBar.BackgroundColor3 = CLR.BG_DARK
  978. RenameTitleBar.BorderSizePixel = 0
  979. RenameTitleBar.ZIndex = 27
  980. RenameTitleBar.Parent = RenameFrame
  981. UI.corner(RenameTitleBar, 10)
  982.  
  983. UI.label(RenameTitleBar, {
  984. text = "[ ] Renomear Posicao",
  985. sz = UDim2.new(1, -16, 1, 0),
  986. pos = UDim2.new(0, 12, 0, 0),
  987. size = 13,
  988. color = CLR.TEXT_PRI,
  989. font = Enum.Font.GothamBold,
  990. align = Enum.TextXAlignment.Left,
  991. }).ZIndex = 28
  992.  
  993. local RenameField = Instance.new("TextBox")
  994. RenameField.Size = UDim2.new(1, -20, 0, 38)
  995. RenameField.Position = UDim2.new(0, 10, 0, 40)
  996. RenameField.BackgroundColor3 = CLR.BG_DARK
  997. RenameField.TextColor3 = CLR.TEXT_PRI
  998. RenameField.PlaceholderColor3 = CLR.TEXT_MUTED
  999. RenameField.PlaceholderText = " Digite o novo nome..."
  1000. RenameField.Font = Enum.Font.Gotham
  1001. RenameField.TextSize = 14
  1002. RenameField.ClearTextOnFocus = false
  1003. RenameField.ZIndex = 27
  1004. RenameField.Parent = RenameFrame
  1005. UI.corner(RenameField, 7)
  1006. UI.stroke(RenameField, CLR.STROKE, 1)
  1007.  
  1008. local RenameConfirmBtn = UI.button(RenameFrame, {
  1009. text = "Confirmar",
  1010. sz = UDim2.new(0.5, -12, 0, 34),
  1011. pos = UDim2.new(0, 8, 1, -42),
  1012. bgColor = CLR.INFO,
  1013. hoverColor = CLR.INFO_HOV,
  1014. size = 13,
  1015. radius = 7,
  1016. })
  1017. RenameConfirmBtn.ZIndex = 27
  1018.  
  1019. local RenameCancelBtn = UI.button(RenameFrame, {
  1020. text = "Cancelar",
  1021. sz = UDim2.new(0.5, -12, 0, 34),
  1022. pos = UDim2.new(0.5, 4, 1, -42),
  1023. bgColor = CLR.ACCENT_DIM,
  1024. hoverColor = CLR.ACCENT,
  1025. size = 13,
  1026. radius = 7,
  1027. })
  1028. RenameCancelBtn.ZIndex = 27
  1029.  
  1030. -- Modal de Mover
  1031. local MoveOverlay = createOverlay(MainFrame, 30)
  1032. local MoveFrame = createModalFrame(MoveOverlay, 300, 170, 31)
  1033.  
  1034. local MoveTitleBar = Instance.new("Frame")
  1035. MoveTitleBar.Size = UDim2.new(1, 0, 0, 32)
  1036. MoveTitleBar.BackgroundColor3 = CLR.BG_DARK
  1037. MoveTitleBar.BorderSizePixel = 0
  1038. MoveTitleBar.ZIndex = 32
  1039. MoveTitleBar.Parent = MoveFrame
  1040. UI.corner(MoveTitleBar, 10)
  1041.  
  1042. UI.label(MoveTitleBar, {
  1043. text = "[ ] Mover Posicao",
  1044. sz = UDim2.new(1, -16, 1, 0),
  1045. pos = UDim2.new(0, 12, 0, 0),
  1046. size = 13,
  1047. color = CLR.TEXT_PRI,
  1048. font = Enum.Font.GothamBold,
  1049. align = Enum.TextXAlignment.Left,
  1050. }).ZIndex = 33
  1051.  
  1052. UI.label(MoveFrame, {
  1053. text = "Slot de destino (1 - 50)",
  1054. sz = UDim2.new(1, -20, 0, 22),
  1055. pos = UDim2.new(0, 10, 0, 38),
  1056. size = 12,
  1057. color = CLR.TEXT_SEC,
  1058. font = Enum.Font.Gotham,
  1059. align = Enum.TextXAlignment.Center,
  1060. }).ZIndex = 32
  1061.  
  1062. local MoveInput = Instance.new("TextBox")
  1063. MoveInput.Size = UDim2.new(0, 90, 0, 42)
  1064. MoveInput.Position = UDim2.new(0.5, -45, 0, 64)
  1065. MoveInput.BackgroundColor3 = CLR.BG_DARK
  1066. MoveInput.TextColor3 = CLR.TEXT_PRI
  1067. MoveInput.PlaceholderColor3 = CLR.TEXT_MUTED
  1068. MoveInput.PlaceholderText = "1 - 50"
  1069. MoveInput.Font = Enum.Font.GothamBold
  1070. MoveInput.TextSize = 20
  1071. MoveInput.ClearTextOnFocus = true
  1072. MoveInput.ZIndex = 32
  1073. MoveInput.Parent = MoveFrame
  1074. UI.corner(MoveInput, 8)
  1075. UI.stroke(MoveInput, CLR.STROKE, 1)
  1076.  
  1077. local MoveConfirmBtn = UI.button(MoveFrame, {
  1078. text = "Confirmar",
  1079. sz = UDim2.new(0.5, -12, 0, 34),
  1080. pos = UDim2.new(0, 8, 1, -42),
  1081. bgColor = CLR.INFO,
  1082. hoverColor = CLR.INFO_HOV,
  1083. size = 13,
  1084. radius = 7,
  1085. })
  1086. MoveConfirmBtn.ZIndex = 32
  1087.  
  1088. local MoveCancelBtn = UI.button(MoveFrame, {
  1089. text = "Cancelar",
  1090. sz = UDim2.new(0.5, -12, 0, 34),
  1091. pos = UDim2.new(0.5, 4, 1, -42),
  1092. bgColor = CLR.ACCENT_DIM,
  1093. hoverColor = CLR.ACCENT,
  1094. size = 13,
  1095. radius = 7,
  1096. })
  1097. MoveCancelBtn.ZIndex = 32
  1098.  
  1099. -- ============================================================
  1100. -- SEÇÃO 11.10 ► PAINEL LATERAL DE ACOES (novo - substitui menu flutuante)
  1101. -- ============================================================
  1102.  
  1103. --[[
  1104. O painel ocupa toda a area de slots do MainFrame.
  1105. Desliza da direita para dentro quando o botão = é clicado.
  1106. Conteudo: cabecalho com nome do slot, 4 botoes de acao, botao voltar.
  1107. ]]
  1108.  
  1109. local ActionPanel = Instance.new("Frame")
  1110. ActionPanel.Name = "ActionPanel"
  1111. ActionPanel.Size = UDim2.new(1, -20, 1, -198)
  1112. ActionPanel.Position = UDim2.new(0, 10, 0, 194)
  1113. ActionPanel.BackgroundColor3 = CLR.BG_MID
  1114. ActionPanel.BorderSizePixel = 0
  1115. ActionPanel.Visible = false
  1116. ActionPanel.ZIndex = 15
  1117. ActionPanel.Parent = MainFrame
  1118. UI.corner(ActionPanel, 8)
  1119. UI.stroke(ActionPanel, CLR.STROKE_BRIGHT, 1.5)
  1120. UI.gradient(ActionPanel, CLR.BG_DARK, CLR.BG_MID, 135)
  1121.  
  1122. -- Cabecalho do painel
  1123. local APHeader = Instance.new("Frame")
  1124. APHeader.Name = "Header"
  1125. APHeader.Size = UDim2.new(1, 0, 0, 44)
  1126. APHeader.BackgroundColor3 = CLR.BG_DARK
  1127. APHeader.BorderSizePixel = 0
  1128. APHeader.ZIndex = 16
  1129. APHeader.Parent = ActionPanel
  1130. UI.corner(APHeader, 8)
  1131. UI.stroke(APHeader, CLR.STROKE, 1)
  1132.  
  1133. -- Divisor horizontal abaixo do header
  1134. local APDivider = Instance.new("Frame")
  1135. APDivider.Size = UDim2.new(1, 0, 0, 1)
  1136. APDivider.Position = UDim2.new(0, 0, 1, 0)
  1137. APDivider.BackgroundColor3 = CLR.STROKE
  1138. APDivider.BorderSizePixel = 0
  1139. APDivider.ZIndex = 17
  1140. APDivider.Parent = APHeader
  1141.  
  1142. -- Indicador de cor no header (barra lateral)
  1143. local APHeaderAccent = Instance.new("Frame")
  1144. APHeaderAccent.Size = UDim2.new(0, 3, 1, -12)
  1145. APHeaderAccent.Position = UDim2.new(0, 0, 0, 6)
  1146. APHeaderAccent.BackgroundColor3 = CLR.ACCENT
  1147. APHeaderAccent.BorderSizePixel = 0
  1148. APHeaderAccent.ZIndex = 17
  1149. APHeaderAccent.Parent = APHeader
  1150. UI.corner(APHeaderAccent, 2)
  1151.  
  1152. -- Numero do slot (badge)
  1153. local APSlotBadge = Instance.new("Frame")
  1154. APSlotBadge.Size = UDim2.new(0, 28, 0, 20)
  1155. APSlotBadge.Position = UDim2.new(0, 8, 0.5, -10)
  1156. APSlotBadge.BackgroundColor3 = CLR.ACCENT_DIM
  1157. APSlotBadge.BorderSizePixel = 0
  1158. APSlotBadge.ZIndex = 17
  1159. APSlotBadge.Parent = APHeader
  1160. UI.corner(APSlotBadge, 4)
  1161.  
  1162. local APSlotNum = UI.label(APSlotBadge, {
  1163. text = "00",
  1164. size = 10,
  1165. color = CLR.TEXT_PRI,
  1166. font = Enum.Font.GothamBold,
  1167. align = Enum.TextXAlignment.Center,
  1168. })
  1169. APSlotNum.ZIndex = 18
  1170.  
  1171. -- Nome da posicao no header
  1172. local APSlotName = UI.label(APHeader, {
  1173. text = "",
  1174. sz = UDim2.new(1, -110, 1, 0),
  1175. pos = UDim2.new(0, 44, 0, 0),
  1176. size = 14,
  1177. color = CLR.TEXT_PRI,
  1178. font = Enum.Font.GothamBold,
  1179. align = Enum.TextXAlignment.Left,
  1180. truncate = Enum.TextTruncate.AtEnd,
  1181. })
  1182. APSlotName.ZIndex = 17
  1183.  
  1184. -- Coordenadas no header
  1185. local APCoords = UI.label(APHeader, {
  1186. text = "",
  1187. sz = UDim2.new(1, -110, 0, 14),
  1188. pos = UDim2.new(0, 44, 1, -16),
  1189. size = 9,
  1190. color = CLR.TEXT_MUTED,
  1191. font = Enum.Font.Gotham,
  1192. align = Enum.TextXAlignment.Left,
  1193. })
  1194. APCoords.ZIndex = 17
  1195.  
  1196. -- Botao Voltar (canto direito do header)
  1197. local APBackBtn = UI.button(APHeader, {
  1198. text = "< Voltar",
  1199. sz = UDim2.new(0, 80, 0, 28),
  1200. pos = UDim2.new(1, -88, 0.5, -14),
  1201. bgColor = CLR.BG_LIGHT,
  1202. hoverColor = CLR.ACCENT_DIM,
  1203. textColor = CLR.TEXT_SEC,
  1204. font = Enum.Font.GothamSemibold,
  1205. size = 12,
  1206. radius = 6,
  1207. })
  1208. APBackBtn.ZIndex = 17
  1209.  
  1210. -- Area dos botoes de acao
  1211. local APActionsFrame = Instance.new("Frame")
  1212. APActionsFrame.Name = "Actions"
  1213. APActionsFrame.Size = UDim2.new(1, -24, 1, -64)
  1214. APActionsFrame.Position = UDim2.new(0, 12, 0, 54)
  1215. APActionsFrame.BackgroundTransparency = 1
  1216. APActionsFrame.ZIndex = 16
  1217. APActionsFrame.Parent = ActionPanel
  1218.  
  1219. -- Layout dos botoes de acao (lista vertical centralizada)
  1220. local APListLayout = Instance.new("UIListLayout")
  1221. APListLayout.FillDirection = Enum.FillDirection.Vertical
  1222. APListLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
  1223. APListLayout.VerticalAlignment = Enum.VerticalAlignment.Center
  1224. APListLayout.Padding = UDim.new(0, 10)
  1225. APListLayout.SortOrder = Enum.SortOrder.LayoutOrder
  1226. APListLayout.Parent = APActionsFrame
  1227.  
  1228. -- Funcao helper para criar botoes de acao do painel
  1229. local function makeActionBtn(icon, label, bgColor, hoverColor, order)
  1230. local btn = Instance.new("TextButton")
  1231. btn.Name = label
  1232. btn.Size = UDim2.new(1, 0, 0, 48)
  1233. btn.BackgroundColor3 = bgColor
  1234. btn.BorderSizePixel = 0
  1235. btn.AutoButtonColor = false
  1236. btn.Text = ""
  1237. btn.LayoutOrder = order
  1238. btn.ZIndex = 17
  1239. btn.Parent = APActionsFrame
  1240. UI.corner(btn, 8)
  1241. UI.stroke(btn, CLR.STROKE, 1)
  1242.  
  1243. UI.hoverBG(btn, hoverColor, bgColor)
  1244.  
  1245. -- Hover: stroke mais brilhante
  1246. local btnStroke = btn:FindFirstChildWhichIsA("UIStroke")
  1247. btn.MouseEnter:Connect(function()
  1248. if btnStroke then
  1249. TweenService:Create(btnStroke, CFG.TWEEN_FAST,
  1250. {Color = CLR.STROKE_BRIGHT}):Play()
  1251. end
  1252. end)
  1253. btn.MouseLeave:Connect(function()
  1254. if btnStroke then
  1255. TweenService:Create(btnStroke, CFG.TWEEN_FAST,
  1256. {Color = CLR.STROKE}):Play()
  1257. end
  1258. end)
  1259.  
  1260. -- Icone (lado esquerdo)
  1261. local iconLbl = UI.label(btn, {
  1262. text = icon,
  1263. sz = UDim2.new(0, 48, 1, 0),
  1264. pos = UDim2.new(0, 0, 0, 0),
  1265. size = 18,
  1266. color = CLR.TEXT_SEC,
  1267. font = Enum.Font.GothamBold,
  1268. align = Enum.TextXAlignment.Center,
  1269. })
  1270. iconLbl.ZIndex = 18
  1271.  
  1272. -- Linha vertical separadora
  1273. local sep = Instance.new("Frame")
  1274. sep.Size = UDim2.new(0, 1, 1, -16)
  1275. sep.Position = UDim2.new(0, 48, 0, 8)
  1276. sep.BackgroundColor3 = CLR.STROKE
  1277. sep.BorderSizePixel = 0
  1278. sep.ZIndex = 18
  1279. sep.Parent = btn
  1280.  
  1281. -- Texto do botao
  1282. local textLbl = UI.label(btn, {
  1283. text = label,
  1284. sz = UDim2.new(1, -60, 1, 0),
  1285. pos = UDim2.new(0, 56, 0, 0),
  1286. size = 14,
  1287. color = CLR.TEXT_PRI,
  1288. font = Enum.Font.GothamSemibold,
  1289. align = Enum.TextXAlignment.Left,
  1290. })
  1291. textLbl.ZIndex = 18
  1292.  
  1293. return btn, iconLbl, textLbl
  1294. end
  1295.  
  1296. -- Os 4 botoes de acao
  1297. local APMainBtn, APMainIcon, APMainLbl = makeActionBtn("*", "Definir como Principal", CLR.BG_CARD, CLR.BG_CARD_HOV, 1)
  1298. local APRenameBtn, APRenameIcon, APRenameLbl = makeActionBtn("[ ]","Renomear", CLR.BG_CARD, CLR.BG_CARD_HOV, 2)
  1299. local APMoveBtn, APMoveIcon, APMoveLbl = makeActionBtn("<->","Mover para Slot", CLR.BG_CARD, CLR.BG_CARD_HOV, 3)
  1300. local APDeleteBtn, APDeleteIcon, APDeleteLbl = makeActionBtn("X", "Excluir Posicao", CLR.BG_CARD, CLR.BG_CARD_HOV, 4)
  1301.  
  1302. -- Cor especial para excluir
  1303. APDeleteLbl.TextColor3 = CLR.DANGER
  1304. APDeleteIcon.TextColor3 = CLR.DANGER
  1305.  
  1306. -- Estado do painel de acoes
  1307. local currentActionSlot = nil
  1308.  
  1309. -- Funcao para abrir o painel de acoes para um slot especifico
  1310. local function openActionPanel(slot)
  1311. local data = State.saves[slot]
  1312. if not data then return end
  1313.  
  1314. currentActionSlot = slot
  1315.  
  1316. -- Atualiza header
  1317. APSlotNum.Text = string.format("%02d", slot)
  1318. APSlotName.Text = data.name
  1319. local pos = data.position.Position
  1320. APCoords.Text = string.format("X %.1f Y %.1f Z %.1f", pos.X, pos.Y, pos.Z)
  1321.  
  1322. -- Atualiza icone/texto do botao principal conforme estado atual
  1323. local isMain = State.mainPos
  1324. and typeof(State.mainPos.position) == "CFrame"
  1325. and State.mainPos.position == data.position
  1326.  
  1327. if isMain then
  1328. APMainIcon.Text = "*"
  1329. APMainLbl.Text = "Remover Principal"
  1330. APMainLbl.TextColor3 = CLR.WARNING
  1331. APMainIcon.TextColor3 = CLR.WARNING
  1332. else
  1333. APMainIcon.Text = "*"
  1334. APMainLbl.Text = "Definir como Principal"
  1335. APMainLbl.TextColor3 = CLR.TEXT_PRI
  1336. APMainIcon.TextColor3 = CLR.TEXT_SEC
  1337. end
  1338.  
  1339. -- Mostra o painel e esconde os slots
  1340. SlotsFrame.Visible = false
  1341. ActionPanel.Visible = true
  1342. end
  1343.  
  1344. -- Funcao para fechar o painel e voltar aos slots
  1345. local function closeActionPanel()
  1346. ActionPanel.Visible = false
  1347. SlotsFrame.Visible = true
  1348. currentActionSlot = nil
  1349. end
  1350.  
  1351. -- ============================================================
  1352. -- SEÇÃO 12 ► LOGICA DE ESTADO E ATUALIZACAO DA UI
  1353. -- ============================================================
  1354.  
  1355. local onConfirmYes = nil
  1356. local slotRenaming = nil
  1357. local slotMoving = nil
  1358.  
  1359. local function refreshSlotUI()
  1360. local n = State.saveSlot
  1361. local data = State.saves[n]
  1362. SlotValueLbl.Text = string.format("%02d", n)
  1363. if data then
  1364. SlotStatusLbl.Text = "ocupado"
  1365. SlotStatusLbl.TextColor3 = CLR.WARNING
  1366. else
  1367. SlotStatusLbl.Text = "livre"
  1368. SlotStatusLbl.TextColor3 = CLR.SUCCESS
  1369. end
  1370. end
  1371.  
  1372. local function refreshPageDots()
  1373. for i, dot in ipairs(PageDots) do
  1374. TweenService:Create(dot, CFG.TWEEN_FAST, {
  1375. BackgroundColor3 = (i == State.currentPage) and CLR.ACCENT or CLR.TEXT_MUTED,
  1376. Size = (i == State.currentPage)
  1377. and UDim2.new(0, 9, 0, 9)
  1378. or UDim2.new(0, 7, 0, 7),
  1379. }):Play()
  1380. end
  1381. end
  1382.  
  1383. local function refreshPageLabel()
  1384. PageLabel.Text = string.format("PAGINA %d / %d", State.currentPage, CFG.MAX_PAGES)
  1385. end
  1386.  
  1387. local function refreshMainPosUI()
  1388. MainPosContainer.Visible = (State.mainPos ~= nil)
  1389. end
  1390.  
  1391. local function findNextEmpty()
  1392. for i = 1, CFG.MAX_SAVES do
  1393. if not State.saves[i] then return i end
  1394. end
  1395. return (State.saveSlot % CFG.MAX_SAVES) + 1
  1396. end
  1397.  
  1398. local function advanceSlot()
  1399. State.saveSlot = findNextEmpty()
  1400. refreshSlotUI()
  1401. end
  1402.  
  1403. local function showConfirm(message, yesText, callback)
  1404. ConfirmLabel.Text = message
  1405. ConfirmYesBtn.Text = yesText or "Confirmar"
  1406. onConfirmYes = callback
  1407. ConfirmOverlay.Visible = true
  1408. end
  1409.  
  1410. -- Formata coordenadas
  1411. local function formatCoords(cf)
  1412. local pos = cf.Position
  1413. return string.format("X: %.1f Y: %.1f Z: %.1f", pos.X, pos.Y, pos.Z)
  1414. end
  1415.  
  1416. -- ────────────────────────────────────────────────
  1417. -- 12.1 ► RENDERIZACAO DOS SLOTS
  1418. -- ────────────────────────────────────────────────
  1419.  
  1420. local function buildSlot(slot)
  1421. local data = State.saves[slot]
  1422.  
  1423. local card = Instance.new("Frame")
  1424. card.Name = "Slot_" .. slot
  1425. card.LayoutOrder = slot
  1426. card.BackgroundColor3 = CLR.BG_CARD
  1427. card.BorderSizePixel = 0
  1428. card.ClipsDescendants = false
  1429. UI.corner(card, 7)
  1430.  
  1431. local cardStroke = UI.stroke(card, CLR.STROKE, 1)
  1432.  
  1433. if data then
  1434. local isMain = State.mainPos
  1435. and typeof(State.mainPos.position) == "CFrame"
  1436. and State.mainPos.position == data.position
  1437.  
  1438. -- Barra lateral colorida (sempre roxo/accent)
  1439. local AccentBar = Instance.new("Frame")
  1440. AccentBar.Size = UDim2.new(0, 3, 1, -10)
  1441. AccentBar.Position = UDim2.new(0, 0, 0, 5)
  1442. AccentBar.BackgroundColor3 = CLR.ACCENT
  1443. AccentBar.BorderSizePixel = 0
  1444. AccentBar.Parent = card
  1445. UI.corner(AccentBar, 2)
  1446.  
  1447. -- Badge numero do slot
  1448. local SlotNumBg = Instance.new("Frame")
  1449. SlotNumBg.Size = UDim2.new(0, 24, 0, 18)
  1450. SlotNumBg.Position = UDim2.new(0, 7, 0.5, -9)
  1451. SlotNumBg.BackgroundColor3 = CLR.ACCENT_DIM
  1452. SlotNumBg.BorderSizePixel = 0
  1453. SlotNumBg.Parent = card
  1454. UI.corner(SlotNumBg, 4)
  1455.  
  1456. UI.label(SlotNumBg, {
  1457. text = tostring(slot),
  1458. size = 9,
  1459. color = CLR.TEXT_PRI,
  1460. font = Enum.Font.GothamBold,
  1461. align = Enum.TextXAlignment.Center,
  1462. })
  1463.  
  1464. -- Indicador de principal (ponto dourado discreto, sem emoji)
  1465. if isMain then
  1466. local mainDot = Instance.new("Frame")
  1467. mainDot.Size = UDim2.new(0, 5, 0, 5)
  1468. mainDot.Position = UDim2.new(0, 7, 0, 5)
  1469. mainDot.BackgroundColor3 = CLR.GOLD
  1470. mainDot.BorderSizePixel = 0
  1471. mainDot.Parent = card
  1472. UI.corner(mainDot, 3)
  1473. end
  1474.  
  1475. -- Nome da posicao
  1476. UI.label(card, {
  1477. text = data.name,
  1478. sz = UDim2.new(1, -100, 0, 22),
  1479. pos = UDim2.new(0, 38, 0, 4),
  1480. size = 12,
  1481. color = CLR.TEXT_PRI,
  1482. font = Enum.Font.GothamSemibold,
  1483. align = Enum.TextXAlignment.Left,
  1484. truncate = Enum.TextTruncate.AtEnd,
  1485. })
  1486.  
  1487. -- Coordenadas XYZ
  1488. UI.label(card, {
  1489. text = formatCoords(data.position),
  1490. sz = UDim2.new(1, -100, 0, 14),
  1491. pos = UDim2.new(0, 38, 0, 27),
  1492. size = 9,
  1493. color = CLR.TEXT_MUTED,
  1494. font = Enum.Font.Gotham,
  1495. align = Enum.TextXAlignment.Left,
  1496. })
  1497.  
  1498. -- Botao Teleportar
  1499. local TpBtn = UI.button(card, {
  1500. text = "TP",
  1501. sz = UDim2.new(0, 34, 0, 34),
  1502. pos = UDim2.new(1, -78, 0.5, -17),
  1503. bgColor = CLR.ACCENT,
  1504. hoverColor = CLR.ACCENT_HOV,
  1505. font = Enum.Font.GothamBold,
  1506. size = 13,
  1507. radius = 7,
  1508. })
  1509.  
  1510. -- [ALTERACAO PRINCIPAL] Botao = (menu de acoes) - substitui estrela e menu antigo
  1511. local MenuBtn = UI.button(card, {
  1512. text = "=",
  1513. sz = UDim2.new(0, 34, 0, 34),
  1514. pos = UDim2.new(1, -40, 0.5, -17),
  1515. bgColor = CLR.BG_LIGHT,
  1516. hoverColor = CLR.ACCENT_DIM,
  1517. textColor = CLR.TEXT_SEC,
  1518. font = Enum.Font.GothamBold,
  1519. size = 16,
  1520. radius = 7,
  1521. })
  1522.  
  1523. -- Hover visual no card
  1524. card.MouseEnter:Connect(function()
  1525. TweenService:Create(card, CFG.TWEEN_FAST,
  1526. {BackgroundColor3 = CLR.BG_CARD_HOV}):Play()
  1527. TweenService:Create(cardStroke, CFG.TWEEN_FAST,
  1528. {Color = CLR.STROKE_BRIGHT}):Play()
  1529. end)
  1530. card.MouseLeave:Connect(function()
  1531. TweenService:Create(card, CFG.TWEEN_FAST,
  1532. {BackgroundColor3 = CLR.BG_CARD}):Play()
  1533. TweenService:Create(cardStroke, CFG.TWEEN_FAST,
  1534. {Color = CLR.STROKE}):Play()
  1535. end)
  1536.  
  1537. -- Acao TP
  1538. TpBtn.MouseButton1Click:Connect(function()
  1539. if Teleport.to(data.position) then
  1540. TpBtn.Text = "OK"
  1541. TweenService:Create(TpBtn, CFG.TWEEN_FAST,
  1542. {BackgroundColor3 = CLR.SUCCESS}):Play()
  1543. task.wait(1.2)
  1544. if TpBtn.Parent then
  1545. TpBtn.Text = "TP"
  1546. TweenService:Create(TpBtn, CFG.TWEEN_FAST,
  1547. {BackgroundColor3 = CLR.ACCENT}):Play()
  1548. end
  1549. end
  1550. end)
  1551.  
  1552. -- Acao abrir painel de acoes
  1553. MenuBtn.MouseButton1Click:Connect(function()
  1554. openActionPanel(slot)
  1555. end)
  1556.  
  1557. else
  1558. -- Slot vazio
  1559. local emptyLbl = UI.label(card, {
  1560. text = string.format("Slot %02d - vazio", slot),
  1561. sz = UDim2.new(1, -10, 1, 0),
  1562. pos = UDim2.new(0, 10, 0, 0),
  1563. size = 12,
  1564. color = CLR.TEXT_MUTED,
  1565. font = Enum.Font.Gotham,
  1566. align = Enum.TextXAlignment.Left,
  1567. })
  1568.  
  1569. if slot == State.saveSlot then
  1570. cardStroke.Color = CLR.ACCENT
  1571. cardStroke.Thickness = 1.5
  1572. emptyLbl.TextColor3 = CLR.ACCENT
  1573. emptyLbl.Text = string.format("> Slot %02d - selecionado", slot)
  1574. end
  1575. end
  1576.  
  1577. return card
  1578. end
  1579.  
  1580. -- Renderiza a pagina atual
  1581. local function renderPage()
  1582. -- Fecha painel de acoes se estiver aberto
  1583. if ActionPanel.Visible then
  1584. closeActionPanel()
  1585. end
  1586.  
  1587. -- Limpa cards anteriores
  1588. for _, child in ipairs(SlotsFrame:GetChildren()) do
  1589. if child:IsA("Frame") then child:Destroy() end
  1590. end
  1591.  
  1592. State.optionFrames = {}
  1593.  
  1594. local startSlot = (State.currentPage - 1) * CFG.SLOTS_PER_PAGE + 1
  1595. local endSlot = State.currentPage * CFG.SLOTS_PER_PAGE
  1596.  
  1597. for slot = startSlot, endSlot do
  1598. local card = buildSlot(slot)
  1599. card.Parent = SlotsFrame
  1600. end
  1601.  
  1602. refreshPageDots()
  1603. refreshPageLabel()
  1604. end
  1605.  
  1606. -- BindableEvent de re-render
  1607. local RebuildEvent = Instance.new("BindableEvent")
  1608. RebuildEvent.Name = "__rebuild"
  1609. RebuildEvent.Parent = ScreenGui
  1610. RebuildEvent.Event:Connect(renderPage)
  1611.  
  1612. -- ============================================================
  1613. -- SEÇÃO 13 ► ACOES DO PAINEL LATERAL
  1614. -- ============================================================
  1615.  
  1616. -- Botao Voltar
  1617. APBackBtn.MouseButton1Click:Connect(function()
  1618. closeActionPanel()
  1619. end)
  1620.  
  1621. -- Botao Principal (definir / remover)
  1622. APMainBtn.MouseButton1Click:Connect(function()
  1623. local slot = currentActionSlot
  1624. if not slot or not State.saves[slot] then return end
  1625. local data = State.saves[slot]
  1626. local isMain = State.mainPos
  1627. and typeof(State.mainPos.position) == "CFrame"
  1628. and State.mainPos.position == data.position
  1629.  
  1630. if isMain then
  1631. showConfirm(
  1632. "Remover esta posicao principal?",
  1633. "Remover",
  1634. function()
  1635. State.mainPos = nil
  1636. Persist.deleteMain()
  1637. refreshMainPosUI()
  1638. closeActionPanel()
  1639. renderPage()
  1640. end
  1641. )
  1642. else
  1643. showConfirm(
  1644. State.mainPos
  1645. and "Substituir a posicao principal atual?"
  1646. or "Definir esta posicao como principal?",
  1647. "Confirmar",
  1648. function()
  1649. State.mainPos = {
  1650. position = data.position,
  1651. name = data.name,
  1652. timestamp = data.timestamp,
  1653. }
  1654. Persist.scheduleSave()
  1655. refreshMainPosUI()
  1656. closeActionPanel()
  1657. renderPage()
  1658. end
  1659. )
  1660. end
  1661. end)
  1662.  
  1663. -- Botao Renomear
  1664. APRenameBtn.MouseButton1Click:Connect(function()
  1665. local slot = currentActionSlot
  1666. if not slot or not State.saves[slot] then return end
  1667. slotRenaming = slot
  1668. RenameField.Text = State.saves[slot].name
  1669. RenameOverlay.Visible = true
  1670. end)
  1671.  
  1672. -- Botao Mover
  1673. APMoveBtn.MouseButton1Click:Connect(function()
  1674. local slot = currentActionSlot
  1675. if not slot or not State.saves[slot] then return end
  1676. slotMoving = slot
  1677. MoveInput.Text = ""
  1678. MoveOverlay.Visible = true
  1679. end)
  1680.  
  1681. -- Botao Excluir
  1682. APDeleteBtn.MouseButton1Click:Connect(function()
  1683. local slot = currentActionSlot
  1684. if not slot or not State.saves[slot] then return end
  1685. showConfirm(
  1686. string.format("Excluir o Slot %d \"%s\" ?", slot, State.saves[slot].name),
  1687. "Excluir",
  1688. function()
  1689. State.saves[slot] = nil
  1690. Persist.scheduleSave()
  1691. showToast("Slot " .. slot .. " excluido", "info")
  1692. advanceSlot()
  1693. closeActionPanel()
  1694. renderPage()
  1695. end
  1696. )
  1697. end)
  1698.  
  1699. -- ============================================================
  1700. -- SEÇÃO 14 ► CONEXOES DOS CONTROLES PRINCIPAIS
  1701. -- ============================================================
  1702.  
  1703. -- Fechar totalmente
  1704. DestroyBtn.MouseButton1Click:Connect(function()
  1705. showConfirm(
  1706. "Fechar completamente o Save Locate?\n(So voltara ao executar novamente)",
  1707. "Fechar",
  1708. function()
  1709. Persist.save()
  1710. task.wait(0.1)
  1711. ScreenGui:Destroy()
  1712. end
  1713. )
  1714. end)
  1715.  
  1716. -- Minimizar
  1717. CloseBtn.MouseButton1Click:Connect(function()
  1718. TweenService:Create(MainFrame, CFG.TWEEN_MED, {
  1719. Size = UDim2.new(0, 590, 0, 0),
  1720. Position = UDim2.new(0.5, -295, 0.5, 0),
  1721. }):Play()
  1722. task.wait(0.3)
  1723. MainFrame.Visible = false
  1724. MainFrame.Size = UDim2.new(0, 590, 0, 470)
  1725. MainFrame.Position = UDim2.new(0.5, -295, 0.5, -235)
  1726. end)
  1727.  
  1728. FloatBtn.MouseButton1Click:Connect(function()
  1729. MainFrame.Size = UDim2.new(0, 590, 0, 0)
  1730. MainFrame.Position = UDim2.new(0.5, -295, 0.5, 0)
  1731. MainFrame.Visible = true
  1732. TweenService:Create(MainFrame, CFG.TWEEN_MED, {
  1733. Size = UDim2.new(0, 590, 0, 470),
  1734. Position = UDim2.new(0.5, -295, 0.5, -235),
  1735. }):Play()
  1736. end)
  1737.  
  1738. MainFrame:GetPropertyChangedSignal("Visible"):Connect(function()
  1739. FloatContainer.Visible = not MainFrame.Visible
  1740. end)
  1741.  
  1742. -- Paginacao
  1743. local function changePage(delta)
  1744. local newPage = State.currentPage + delta
  1745. if newPage < 1 then newPage = CFG.MAX_PAGES end
  1746. if newPage > CFG.MAX_PAGES then newPage = 1 end
  1747. State.currentPage = newPage
  1748. renderPage()
  1749. end
  1750.  
  1751. PagePrevBtn.MouseButton1Click:Connect(function() changePage(-1) end)
  1752. PageNextBtn.MouseButton1Click:Connect(function() changePage( 1) end)
  1753.  
  1754. -- Seletor de slot
  1755. SlotPrevBtn.MouseButton1Click:Connect(function()
  1756. State.saveSlot = ((State.saveSlot - 2 + CFG.MAX_SAVES) % CFG.MAX_SAVES) + 1
  1757. refreshSlotUI()
  1758. renderPage()
  1759. end)
  1760.  
  1761. SlotNextBtn.MouseButton1Click:Connect(function()
  1762. State.saveSlot = (State.saveSlot % CFG.MAX_SAVES) + 1
  1763. refreshSlotUI()
  1764. renderPage()
  1765. end)
  1766.  
  1767. -- Salvar
  1768. local function doSave()
  1769. if not root then return false end
  1770. local name = (NameBox.Text ~= "" and NameBox.Text) or ("Slot " .. State.saveSlot)
  1771. State.saves[State.saveSlot] = {
  1772. position = root.CFrame,
  1773. name = name,
  1774. timestamp = os.date("%Y-%m-%d %H:%M:%S"),
  1775. }
  1776. Persist.scheduleSave()
  1777. local targetPage = math.ceil(State.saveSlot / CFG.SLOTS_PER_PAGE)
  1778. if targetPage ~= State.currentPage then
  1779. State.currentPage = targetPage
  1780. end
  1781. renderPage()
  1782. showToast(string.format("Salvo no Slot %d", State.saveSlot), "success")
  1783. advanceSlot()
  1784. return true
  1785. end
  1786.  
  1787. SaveBtn.MouseButton1Click:Connect(function()
  1788. if State.saves[State.saveSlot] then
  1789. showConfirm(
  1790. string.format("O Slot %d ja tem uma posicao.\nDeseja substituir?", State.saveSlot),
  1791. "Substituir",
  1792. doSave
  1793. )
  1794. else
  1795. doSave()
  1796. end
  1797. end)
  1798.  
  1799. -- Posicao Principal (botao flutuante)
  1800. MainPosBtn.MouseButton1Click:Connect(function()
  1801. if State.mainPos and Teleport.to(State.mainPos.position) then
  1802. MainPosBtn.Text = "OK"
  1803. TweenService:Create(MainPosBtn, CFG.TWEEN_FAST,
  1804. {BackgroundColor3 = CLR.SUCCESS}):Play()
  1805. task.wait(1)
  1806. if MainPosBtn.Parent then
  1807. MainPosBtn.Text = ">>"
  1808. TweenService:Create(MainPosBtn, CFG.TWEEN_FAST,
  1809. {BackgroundColor3 = CLR.BG_MID}):Play()
  1810. end
  1811. end
  1812. end)
  1813.  
  1814. MainPosBtn.MouseEnter:Connect(function()
  1815. if State.mainPos then
  1816. TooltipLabel.Text = State.mainPos.name or "Principal"
  1817. MainPosTooltip.Visible = true
  1818. MainPosRemoveBtn.Visible = true
  1819. end
  1820. TweenService:Create(MainPosStroke, CFG.TWEEN_FAST, {Thickness = 3}):Play()
  1821. TweenService:Create(MainPosBtn, CFG.TWEEN_FAST,
  1822. {Size = UDim2.new(1.1, 0, 1.1, 0)}):Play()
  1823. end)
  1824.  
  1825. MainPosBtn.MouseLeave:Connect(function()
  1826. MainPosTooltip.Visible = false
  1827. MainPosRemoveBtn.Visible = false
  1828. TweenService:Create(MainPosStroke, CFG.TWEEN_FAST, {Thickness = 2}):Play()
  1829. TweenService:Create(MainPosBtn, CFG.TWEEN_FAST,
  1830. {Size = UDim2.new(1, 0, 1, 0)}):Play()
  1831. end)
  1832.  
  1833. MainPosRemoveBtn.MouseButton1Click:Connect(function()
  1834. showConfirm("Remover a posicao principal?", "Remover", function()
  1835. State.mainPos = nil
  1836. Persist.deleteMain()
  1837. refreshMainPosUI()
  1838. renderPage()
  1839. end)
  1840. end)
  1841.  
  1842. -- Confirmacao
  1843. ConfirmYesBtn.MouseButton1Click:Connect(function()
  1844. if onConfirmYes then onConfirmYes() end
  1845. onConfirmYes = nil
  1846. ConfirmOverlay.Visible = false
  1847. end)
  1848.  
  1849. ConfirmNoBtn.MouseButton1Click:Connect(function()
  1850. onConfirmYes = nil
  1851. ConfirmOverlay.Visible = false
  1852. end)
  1853.  
  1854. -- Renomear
  1855. RenameConfirmBtn.MouseButton1Click:Connect(function()
  1856. local newName = RenameField.Text
  1857. if not slotRenaming or newName == "" then return end
  1858. local data = State.saves[slotRenaming]
  1859. if data then
  1860. data.name = newName
  1861. if State.mainPos and State.mainPos.position == data.position then
  1862. State.mainPos.name = newName
  1863. end
  1864. Persist.scheduleSave()
  1865. -- Atualiza header do painel se ainda estiver aberto para o mesmo slot
  1866. if currentActionSlot == slotRenaming and ActionPanel.Visible then
  1867. APSlotName.Text = newName
  1868. end
  1869. renderPage()
  1870. showToast("Slot " .. slotRenaming .. " renomeado", "info")
  1871. end
  1872. RenameOverlay.Visible = false
  1873. slotRenaming = nil
  1874. end)
  1875.  
  1876. RenameCancelBtn.MouseButton1Click:Connect(function()
  1877. RenameOverlay.Visible = false
  1878. slotRenaming = nil
  1879. end)
  1880.  
  1881. -- Mover
  1882. MoveConfirmBtn.MouseButton1Click:Connect(function()
  1883. local target = tonumber(MoveInput.Text)
  1884. if not slotMoving or not target then return end
  1885. if target < 1 or target > CFG.MAX_SAVES or target ~= math.floor(target) then
  1886. MoveInput.Text = ""
  1887. MoveInput.PlaceholderText = "Invalido! (1-50)"
  1888. task.delay(1.5, function() MoveInput.PlaceholderText = "1 - 50" end)
  1889. return
  1890. end
  1891. local from, to = slotMoving, target
  1892. if from ~= to then
  1893. if State.saves[to] then
  1894. local temp = State.saves[from]
  1895. State.saves[from] = State.saves[to]
  1896. State.saves[to] = temp
  1897. else
  1898. State.saves[to] = State.saves[from]
  1899. State.saves[from] = nil
  1900. end
  1901. Persist.scheduleSave()
  1902. State.currentPage = math.ceil(to / CFG.SLOTS_PER_PAGE)
  1903. closeActionPanel()
  1904. renderPage()
  1905. showToast(string.format("Slot %d movido para Slot %d", from, to), "info")
  1906. end
  1907. MoveOverlay.Visible = false
  1908. slotMoving = nil
  1909. end)
  1910.  
  1911. MoveCancelBtn.MouseButton1Click:Connect(function()
  1912. MoveOverlay.Visible = false
  1913. slotMoving = nil
  1914. end)
  1915.  
  1916. -- Enter confirma campos de texto
  1917. RenameField.FocusLost:Connect(function(enter)
  1918. if enter then RenameConfirmBtn.MouseButton1Click:Fire() end
  1919. end)
  1920.  
  1921. MoveInput.FocusLost:Connect(function(enter)
  1922. if enter then MoveConfirmBtn.MouseButton1Click:Fire() end
  1923. end)
  1924.  
  1925. -- ============================================================
  1926. -- SEÇÃO 15 ► EVENTOS DE CICLO DE VIDA
  1927. -- ============================================================
  1928.  
  1929. plr.CharacterAdded:Connect(function(character)
  1930. chr = character
  1931. root = character:WaitForChild("HumanoidRootPart")
  1932. end)
  1933.  
  1934. game:BindToClose(Persist.save)
  1935.  
  1936. task.spawn(function()
  1937. while task.wait(60) do
  1938. if State.isDirty then Persist.save() end
  1939. end
  1940. end)
  1941.  
  1942. -- ============================================================
  1943. -- SEÇÃO 16 ► INICIALIZACAO
  1944. -- ============================================================
  1945.  
  1946. Persist.load()
  1947. refreshSlotUI()
  1948. refreshMainPosUI()
  1949. renderPage()
  1950.  
  1951. print(string.format(
  1952. "Save Locate (NickZ) V%s | %d slots | FS: %s",
  1953. CFG.VERSION,
  1954. CFG.MAX_SAVES,
  1955. FS.active and "ativo" or "inativo"
  1956. ))
Add Comment
Please, Sign In to add comment