ColdSpecs

Working (New LBU)

Nov 18th, 2025
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.24 KB | None | 0 0
  1. -- // ==============================================
  2. -- // PAYLOAD0 – CLICK TO CALIBRATE + HOLD F TO AUTO-SHOOT
  3. -- // Perfect Distance | Auto-Jump | One Shot Per Jump
  4. -- // MULTI-POWER SUPPORT (54.68 → 75, 40.54 → 20, …)
  5. -- // ==============================================
  6.  
  7. local Players = game:GetService('Players')
  8. local UserInputService = game:GetService('UserInputService')
  9. local RunService = game:GetService('RunService')
  10. local ReplicatedStorage = game:GetService('ReplicatedStorage')
  11. local CoreGui = game:GetService('CoreGui')
  12. local TweenService = game:GetService('TweenService')
  13. local Workspace = game:GetService('Workspace')
  14. local Camera = workspace.CurrentCamera
  15.  
  16. local plr = Players.LocalPlayer
  17. local char = plr.Character or plr.CharacterAdded:Wait()
  18.  
  19. -- === STATE ===
  20. getgenv().PAYLOAD0_SYSTEM_ACTIVE = true
  21. local SystemOn = true
  22. local shootKey = nil
  23. local selectedRim = nil
  24. local activeNotifyGui = nil
  25. local ballTool = nil
  26.  
  27. -- === NEW STATE (F-HOLD SYSTEM) ===
  28. local fKeyDown = false
  29. local SystemActive = false -- true while F is held
  30.  
  31. -- === CONFIGURATION ===
  32. local ACTIVE_RANGE_MAIN = 90
  33.  
  34. -- === POWER MAP ===
  35. -- distance → power (add as many as you want)
  36. local DISTANCE_TO_POWER = {
  37. [61.25] = 80, -- Far shot
  38. --[30.00] = 15, -- example
  39. }
  40.  
  41. -- Perfect distance system
  42. local PERFECT_DISTANCES = { 61.25 } -- list every distance you use
  43. local PERFECT_TOL = 0.12
  44. local PREDICTIVE_BIAS = 2.0
  45. local SINGLE_SHOT_PER_JUMP = true
  46.  
  47. -- Auto-jump
  48. local AUTOJUMP_PREWINDOW = 4.0
  49. local AUTOJUMP_COOLDOWN = 0.20
  50. local MIN_JUMP_VELOCITY = 2.2
  51.  
  52. -- Remote replay
  53. local INCLUDE_TEMPLATE_ARGS = true
  54. local lastArgTemplate = nil
  55.  
  56. -- Rim size
  57. local RimSize =
  58. Vector3.new(3.632131576538086, 0.35878971219062805, 3.632131576538086)
  59.  
  60. -- === NOTIFY SYSTEM ===
  61. local function notify(msg)
  62. if activeNotifyGui and activeNotifyGui.Parent then
  63. activeNotifyGui:Destroy()
  64. end
  65. local gui = Instance.new('ScreenGui')
  66. gui.ResetOnSpawn = false
  67. gui.Parent = CoreGui
  68. activeNotifyGui = gui
  69.  
  70. local label = Instance.new('TextLabel')
  71. label.AnchorPoint = Vector2.new(0.5, 0.5)
  72. label.Position = UDim2.new(0.5, 0, 0.9, 0)
  73. label.Size = UDim2.new(0, 560, 0, 38)
  74. label.BackgroundTransparency = 1
  75. label.Font = Enum.Font.Code
  76. label.TextSize = 26
  77. label.TextColor3 = Color3.fromRGB(255, 255, 255)
  78. label.Text = msg
  79. label.Parent = gui
  80.  
  81. task.delay(1.2, function()
  82. if gui == activeNotifyGui then
  83. gui:Destroy()
  84. activeNotifyGui = nil
  85. end
  86. end)
  87. end
  88.  
  89. -- === BALL CHECK ===
  90. local function hasBall()
  91. local c = plr.Character
  92. if not c then
  93. return false
  94. end
  95. for _, tool in ipairs(c:GetChildren()) do
  96. if tool:IsA('Tool') and tool.Name:lower():find('ball') then
  97. ballTool = tool
  98. return true
  99. end
  100. end
  101. ballTool = nil
  102. return false
  103. end
  104.  
  105. -- === CALIBRATE UI (ORIGINAL) ===
  106. local calibrateGui
  107. local function showCalibrateUI()
  108. if calibrateGui or shootKey or not hasBall() then
  109. return
  110. end
  111. calibrateGui = Instance.new('ScreenGui')
  112. calibrateGui.Name = 'CalibrateReminder'
  113. calibrateGui.ResetOnSpawn = false
  114. calibrateGui.IgnoreGuiInset = true
  115. calibrateGui.Parent = CoreGui
  116.  
  117. local frame = Instance.new('Frame')
  118. frame.AnchorPoint = Vector2.new(0.5, 0.5)
  119. frame.Position = UDim2.new(0.5, 0, 0.85, 0)
  120. frame.Size = UDim2.new(0, 420, 0, 45)
  121. frame.BackgroundTransparency = 0.3
  122. frame.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
  123. frame.BorderSizePixel = 0
  124. frame.Parent = calibrateGui
  125.  
  126. Instance.new('UICorner', frame).CornerRadius = UDim.new(0, 10)
  127.  
  128. local label = Instance.new('TextLabel')
  129. label.BackgroundTransparency = 1
  130. label.Size = UDim2.new(1, 0, 1, 0)
  131. label.Font = Enum.Font.GothamMedium
  132. label.TextSize = 22
  133. label.TextColor3 = Color3.fromRGB(255, 255, 255)
  134. label.Text = 'Click once to calibrate your shot.'
  135. label.Parent = frame
  136.  
  137. task.spawn(function()
  138. while calibrateGui and not shootKey and hasBall() do
  139. local t1 = TweenService:Create(
  140. label,
  141. TweenInfo.new(0.8, Enum.EasingStyle.Sine),
  142. { TextTransparency = 0.3 }
  143. )
  144. local t2 = TweenService:Create(
  145. label,
  146. TweenInfo.new(0.8, Enum.EasingStyle.Sine),
  147. { TextTransparency = 0 }
  148. )
  149. t1:Play()
  150. t1.Completed:Wait()
  151. t2:Play()
  152. t2.Completed:Wait()
  153. end
  154. end)
  155. end
  156.  
  157. local function removeCalibrateUI()
  158. if calibrateGui then
  159. calibrateGui:Destroy()
  160. calibrateGui = nil
  161. end
  162. end
  163.  
  164. task.spawn(function()
  165. while task.wait(0.5) do
  166. if not hasBall() or shootKey then
  167. removeCalibrateUI()
  168. else
  169. showCalibrateUI()
  170. end
  171. end
  172. end)
  173.  
  174. -- === REMOTE HOOKING (ORIGINAL + TEMPLATE CAPTURE + NEAR-PAIR LISTENER) ===
  175. local shootRemote = nil
  176. local hookedMeta = nil
  177. local SEARCH_PATTERN = 'shoot'
  178.  
  179. local function getRoots()
  180. local roots = {}
  181. local userFolder = Workspace:FindFirstChild(plr.Name)
  182. if userFolder and userFolder:FindFirstChild('Basketball') then
  183. table.insert(roots, userFolder.Basketball)
  184. end
  185. local remotes = ReplicatedStorage:FindFirstChild('Remotes')
  186. if remotes then
  187. table.insert(roots, remotes)
  188. end
  189. return roots
  190. end
  191.  
  192. local function findShootRemote()
  193. for _, root in ipairs(getRoots()) do
  194. for _, obj in ipairs(root:GetDescendants()) do
  195. if
  196. obj:IsA('RemoteEvent') and obj.Name:lower():find(SEARCH_PATTERN)
  197. then
  198. return obj
  199. end
  200. end
  201. local direct = root:FindFirstChild('Shoot')
  202. if direct and direct:IsA('RemoteEvent') then
  203. return direct
  204. end
  205. end
  206. return nil
  207. end
  208.  
  209. -- === NEAR-PAIR SIGNATURE HELPERS ===
  210. local function isVector3(v)
  211. return typeof(v) == "Vector3"
  212. end
  213.  
  214. local function looksLikeShootPacket(args)
  215. -- Matches your captured remote:
  216. -- FireServer(Vector3, Vector3, "🔥🔥", tool, number, table, bool)
  217. if #args < 6 then
  218. return false
  219. end
  220.  
  221. return isVector3(args[1])
  222. and isVector3(args[2])
  223. and type(args[3]) == "string" and #args[3] <= 6
  224. and typeof(args[4]) == "Instance"
  225. and type(args[5]) == "number"
  226. and type(args[6]) == "table"
  227. end
  228.  
  229. local function hookRemote(remote)
  230. if hookedMeta then
  231. return
  232. end
  233. local old
  234. old = hookmetamethod(game, '__namecall', function(self, ...)
  235. local m = getnamecallmethod()
  236.  
  237. if m == 'FireServer' then
  238. local args = { ... }
  239.  
  240. -- ORIGINAL BEHAVIOR: only when self == remote
  241. if self == remote then
  242. -- Capture shootKey on first legit shot
  243. if type(args[3]) == 'string' and not shootKey then
  244. shootKey = args[3]
  245. removeCalibrateUI()
  246. notify('Shoot key captured: ' .. shootKey)
  247. end
  248. -- Save full argument template
  249. if INCLUDE_TEMPLATE_ARGS then
  250. lastArgTemplate = args
  251. end
  252.  
  253. -- NEW: NEAR-PAIR LISTENER (same packet shape, different remote)
  254. elseif looksLikeShootPacket(args) then
  255. if type(args[3]) == 'string' and not shootKey then
  256. shootKey = args[3]
  257. removeCalibrateUI()
  258. notify('Shoot key (near-pair) captured: ' .. shootKey)
  259. end
  260. if INCLUDE_TEMPLATE_ARGS then
  261. lastArgTemplate = args
  262. end
  263. end
  264. end
  265.  
  266. return old(self, ...)
  267. end)
  268. hookedMeta = old
  269. shootRemote = remote
  270. end
  271.  
  272. local function unhookRemote()
  273. hookedMeta = nil
  274. shootRemote = nil
  275. end
  276.  
  277. RunService.Heartbeat:Connect(function()
  278. if not SystemOn then
  279. return
  280. end
  281. local current = findShootRemote()
  282. if current then
  283. if current ~= shootRemote then
  284. unhookRemote()
  285. hookRemote(current)
  286. end
  287. elseif shootRemote then
  288. unhookRemote()
  289. end
  290. end)
  291.  
  292. -- === RIM DETECTION ===
  293. local Rims = {}
  294. for _, v in ipairs(Workspace:GetDescendants()) do
  295. if v:IsA('BasePart') and v.Name == 'Rim' and v.Size == RimSize then
  296. table.insert(Rims, v)
  297. end
  298. end
  299. Workspace.DescendantAdded:Connect(function(o)
  300. if o:IsA('BasePart') and o.Name == 'Rim' and o.Size == RimSize then
  301. table.insert(Rims, o)
  302. end
  303. end)
  304. Workspace.DescendantRemoving:Connect(function(o)
  305. for i, rim in ipairs(Rims) do
  306. if rim == o then
  307. table.remove(Rims, i)
  308. break
  309. end
  310. end
  311. if selectedRim == o then
  312. selectedRim = nil
  313. end
  314. end)
  315.  
  316. -- Rim selector (runs always when system on)
  317. task.spawn(function()
  318. while task.wait(0.1) do
  319. if not SystemOn then
  320. continue
  321. end
  322. local root = plr.Character
  323. and plr.Character:FindFirstChild('HumanoidRootPart')
  324. if not root then
  325. continue
  326. end
  327. local bestRim, bestDist = nil, 85
  328. for _, rim in ipairs(Rims) do
  329. if rim:IsDescendantOf(Workspace) then
  330. local dist = (rim.Position - root.Position).Magnitude
  331. if dist < bestDist then
  332. local _, on = Camera:WorldToViewportPoint(rim.Position)
  333. if on then
  334. bestRim, bestDist = rim, dist
  335. end
  336. end
  337. end
  338. end
  339. selectedRim = bestRim
  340. end
  341. end)
  342.  
  343. -- === AIM HELPERS ===
  344. local lastTick, moveOffset = 0, Vector3.zero
  345. local function computeOffset()
  346. if tick() - lastTick > 0.1 then
  347. local hum = plr.Character
  348. and plr.Character:FindFirstChildOfClass('Humanoid')
  349. local moveDir = (hum and hum.MoveDirection) or Vector3.zero
  350. moveOffset = Vector3.new(moveDir.X * 1.5, 0, moveDir.Z * 1.5)
  351. lastTick = tick()
  352. end
  353. return moveOffset
  354. end
  355.  
  356. local function computeArc(dist)
  357. return Vector3.new(0, 43 + (dist / 15), 0)
  358. end
  359.  
  360. local function smartAim(rim)
  361. local offset = computeOffset()
  362. local root = plr.Character
  363. and plr.Character:FindFirstChild('HumanoidRootPart')
  364. if not root then
  365. return rim.Position
  366. end
  367. local dist = (root.Position - rim.Position).Magnitude
  368. return rim.Position + computeArc(dist) - offset
  369. end
  370.  
  371. local function getLolChild(rim)
  372. if not rim then
  373. return nil
  374. end
  375. for _, ch in ipairs(rim:GetChildren()) do
  376. if ch:IsA('BasePart') and ch.Name == 'Lol' then
  377. return ch
  378. end
  379. end
  380. local p = rim.Parent
  381. if p then
  382. local c = p:FindFirstChild('Lol')
  383. if c and c:IsA('BasePart') then
  384. return c
  385. end
  386. end
  387. return nil
  388. end
  389.  
  390. local function planarDistance(a, b)
  391. local dx, dz = a.X - b.X, a.Z - b.Z
  392. return math.sqrt(dx * dx + dz * dz)
  393. end
  394.  
  395. local function getNearestPerfectDistance(current)
  396. local nearest
  397. for _, pd in ipairs(PERFECT_DISTANCES) do
  398. local diff = math.abs(pd - current)
  399. if not nearest or diff < (math.abs(nearest - current)) then
  400. nearest = pd
  401. end
  402. end
  403. return nearest or current
  404. end
  405.  
  406. -- === DYNAMIC POWER SELECTOR ===
  407. local function getPowerForDistance(dist)
  408. local exact = DISTANCE_TO_POWER[dist]
  409. if exact then
  410. return exact
  411. end
  412.  
  413. -- fallback: closest entry
  414. local bestDist, bestPower = nil, nil
  415. for d, p in pairs(DISTANCE_TO_POWER) do
  416. local diff = math.abs(d - dist)
  417. if not bestDist or diff < (math.abs(bestDist - dist)) then
  418. bestDist, bestPower = d, p
  419. end
  420. end
  421. return bestPower or 75
  422. end
  423.  
  424. -- === FIRE REMOTE (TEMPLATE REPLAY + DYNAMIC POWER) ===
  425. local function fireShootRemote(aimPos, shootFrom, targetDist)
  426. if not (shootRemote and shootKey) then
  427. return
  428. end
  429. local c = plr.Character
  430. local head = c and c:FindFirstChild('Head')
  431. local root = c and c.PrimaryPart
  432. if not (c and head and root) then
  433. return
  434. end
  435.  
  436. -- ----- TEMPLATE REPLAY -----
  437. if INCLUDE_TEMPLATE_ARGS and lastArgTemplate then
  438. local args = table.clone(lastArgTemplate)
  439. local v3Idx = {}
  440. for i, v in ipairs(args) do
  441. if typeof(v) == 'Vector3' then
  442. table.insert(v3Idx, i)
  443. end
  444. end
  445. if #v3Idx >= 2 then
  446. args[v3Idx[1]] = aimPos
  447. args[v3Idx[2]] = shootFrom
  448. end
  449. for i, v in ipairs(args) do
  450. if type(v) == 'string' and v ~= shootKey and #v <= 6 then
  451. args[i] = shootKey
  452. break
  453. end
  454. end
  455. -- inject correct power
  456. for i = #args, math.max(1, #args - 3), -1 do
  457. if type(args[i]) == 'number' then
  458. args[i] = getPowerForDistance(targetDist)
  459. break
  460. end
  461. end
  462. shootRemote:FireServer(table.unpack(args))
  463. return
  464. end
  465.  
  466. -- ----- FALLBACK -----
  467. local tool = ballTool or (c and c:FindFirstChildOfClass('Tool'))
  468. shootRemote:FireServer(
  469. aimPos,
  470. shootFrom,
  471. shootKey,
  472. tool,
  473. getPowerForDistance(targetDist), -- dynamic power
  474. {
  475. CFrame = root.CFrame,
  476. FieldOfView = Camera.FieldOfView,
  477. ViewportSize = Camera.ViewportSize,
  478. },
  479. true
  480. )
  481. end
  482.  
  483. -- === PER-JUMP STATE ===
  484. local perJumpShotDone = false
  485. local lastJumpAssistAt = 0
  486. local wasOutside = true
  487.  
  488. local function resetJumpFlags()
  489. perJumpShotDone = false
  490. wasOutside = true
  491. end
  492.  
  493. plr.CharacterAdded:Connect(function()
  494. task.wait(0.5)
  495. resetJumpFlags()
  496. end)
  497.  
  498. local function isAirborne(hum)
  499. if not hum then
  500. return false
  501. end
  502. local st = hum:GetState()
  503. return not (
  504. st == Enum.HumanoidStateType.Running
  505. or st == Enum.HumanoidStateType.RunningNoPhysics
  506. or st == Enum.HumanoidStateType.Landed
  507. or st == Enum.HumanoidStateType.Seated
  508. )
  509. end
  510.  
  511. -- === INPUT HANDLERS ===
  512. UserInputService.InputBegan:Connect(function(i, gp)
  513. if gp then
  514. return
  515. end
  516.  
  517. -- V: Toggle system
  518. if i.KeyCode == Enum.KeyCode.V then
  519. SystemOn = not SystemOn
  520. getgenv().PAYLOAD0_SYSTEM_ACTIVE = SystemOn
  521. notify(SystemOn and 'System On' or 'System Off')
  522. end
  523.  
  524. -- F: Hold to activate auto-shoot
  525. if i.KeyCode == Enum.KeyCode.F then
  526. if fKeyDown then
  527. return
  528. end
  529. fKeyDown = true
  530. SystemActive = true
  531. notify('AUTO-SHOOT ON (Hold F)')
  532. end
  533.  
  534. -- Click: Only for calibration
  535. if
  536. SystemOn
  537. and i.UserInputType == Enum.UserInputType.MouseButton1
  538. and hasBall()
  539. and not shootKey
  540. then
  541. notify('Calibrating... click to shoot once.')
  542. end
  543. end)
  544.  
  545. UserInputService.InputEnded:Connect(function(i, gp)
  546. if gp or i.KeyCode ~= Enum.KeyCode.F then
  547. return
  548. end
  549. if not fKeyDown then
  550. return
  551. end
  552. fKeyDown = false
  553. SystemActive = false
  554. notify('AUTO-SHOOT OFF')
  555. end)
  556.  
  557. -- === MAIN AUTO-SHOOT LOOP (F-HOLD) ===
  558. RunService.RenderStepped:Connect(function(dt)
  559. if
  560. not (
  561. SystemActive
  562. and SystemOn
  563. and hasBall()
  564. and shootKey
  565. and selectedRim
  566. )
  567. then
  568. return
  569. end
  570.  
  571. local c = plr.Character
  572. local hum = c and c:FindFirstChildOfClass('Humanoid')
  573. local root = c
  574. and (
  575. c:FindFirstChild('HumanoidRootPart')
  576. or c:FindFirstChildWhichIsA('BasePart')
  577. )
  578. local head = c and c:FindFirstChild('Head')
  579. if not (hum and root and head) then
  580. return
  581. end
  582.  
  583. local rim = selectedRim
  584. if not rim:IsDescendantOf(Workspace) then
  585. return
  586. end
  587.  
  588. local lol = getLolChild(rim)
  589. local refPos = (lol and lol.Position) or rim.Position
  590. local dist = planarDistance(root.Position, refPos)
  591. if dist > ACTIVE_RANGE_MAIN then
  592. return
  593. end
  594.  
  595. local target = getNearestPerfectDistance(dist)
  596. local diff = dist - target
  597. local absDiff = math.abs(diff)
  598.  
  599. local vel = root.AssemblyLinearVelocity or root.Velocity
  600. local yVel = vel.Y
  601. local airborne = (yVel > MIN_JUMP_VELOCITY) or isAirborne(hum)
  602.  
  603. -- Auto-jump when entering perfect zone
  604. if not airborne then
  605. local entering = (diff > 0)
  606. and (diff <= AUTOJUMP_PREWINDOW)
  607. and wasOutside
  608. if entering and (tick() - lastJumpAssistAt > AUTOJUMP_COOLDOWN) then
  609. hum:ChangeState(Enum.HumanoidStateType.Jumping)
  610. lastJumpAssistAt = tick()
  611. wasOutside = false
  612. elseif diff > AUTOJUMP_PREWINDOW then
  613. wasOutside = true
  614. elseif diff < 0 then
  615. wasOutside = false
  616. end
  617. end
  618.  
  619. -- Auto-shoot
  620. if airborne and not (SINGLE_SHOT_PER_JUMP and perJumpShotDone) then
  621. local predictedPos = root.Position + vel * dt
  622. local pDist = planarDistance(predictedPos, refPos)
  623. local pTarget = getNearestPerfectDistance(pDist)
  624.  
  625. if
  626. math.abs(pDist - pTarget) <= (PERFECT_TOL * PREDICTIVE_BIAS)
  627. or absDiff <= PERFECT_TOL
  628. then
  629. local aimPos = smartAim(rim)
  630. local dir = (aimPos - head.Position).Unit
  631. local shootFrom = root.Position + dir * 4
  632. fireShootRemote(aimPos, shootFrom, target) -- pass the perfect distance
  633. perJumpShotDone = true
  634. end
  635. end
  636. end)
  637.  
  638. -- Reset on land
  639. task.spawn(function()
  640. local lastState
  641. while task.wait(0.02) do
  642. local hum = plr.Character
  643. and plr.Character:FindFirstChildOfClass('Humanoid')
  644. if hum then
  645. local st = hum:GetState()
  646. if
  647. st ~= lastState
  648. and (
  649. st == Enum.HumanoidStateType.Landed
  650. or st == Enum.HumanoidStateType.Running
  651. )
  652. then
  653. resetJumpFlags()
  654. end
  655. lastState = st
  656. end
  657. end
  658. end)
  659.  
  660. --[[
  661. Payload0 Arc Visualizer (One-Time Placement Edition)
  662. Creates static, anchored arcs for each Rim once and never updates them.
  663. Zero loops, zero runtime cost, no transparency toggles.
  664. ]]
  665.  
  666. -- === SERVICES ===
  667. local Players = game:GetService('Players')
  668. local Workspace = game:GetService('Workspace')
  669.  
  670. -- === CONFIGURATION ===
  671. local PERFECT_DISTANCES = { 64.25 }
  672. local RING_ARC_DEGREES = 180
  673. local DEGREE_STEP = 4
  674. local DOT_MATERIAL = Enum.Material.Neon
  675. local DOT_COLOR = Color3.fromRGB(0, 0, 0)
  676. local LINK_THICKNESS = 0.25
  677. local RIM_SIZE =
  678. Vector3.new(3.632131576538086, 0.5587897300720215, 3.632131576538086)
  679. local HEIGHT_OFFSET = -18.361
  680. local ARC_ADJUSTMENTS = { [1] = -18 }
  681.  
  682. -- === INTERNALS ===
  683. local ArcFolder = Instance.new('Folder', Workspace)
  684. ArcFolder.Name = 'Payload0_StaticArcs'
  685.  
  686. -- === HELPERS ===
  687. local function isValidRim(o)
  688. return o:IsA('BasePart') and o.Name == 'Rim' and o.Size == RIM_SIZE
  689. end
  690.  
  691. local function createStaticArc(rimPart, radius, extraDegrees)
  692. local model = Instance.new('Model')
  693. model.Name = 'Payload0_StaticArc_' .. rimPart:GetDebugId()
  694. model.Parent = ArcFolder
  695.  
  696. local forward = rimPart.CFrame.LookVector
  697. local right = rimPart.CFrame.RightVector
  698. local startDeg = -RING_ARC_DEGREES / 2 - extraDegrees
  699. local endDeg = RING_ARC_DEGREES / 2 + extraDegrees
  700.  
  701. local points = {}
  702. for deg = startDeg, endDeg, DEGREE_STEP do
  703. local rad = math.rad(deg)
  704. local offset = (forward * math.cos(rad) + right * math.sin(rad))
  705. * radius
  706. table.insert(
  707. points,
  708. rimPart.Position + Vector3.new(offset.X, HEIGHT_OFFSET, offset.Z)
  709. )
  710. end
  711.  
  712. for i = 1, #points - 1 do
  713. local a, b = points[i], points[i + 1]
  714. local dist = (a - b).Magnitude
  715. local link = Instance.new('Part')
  716. link.Anchored = true
  717. link.CanCollide = false
  718. link.Material = DOT_MATERIAL
  719. link.Color = DOT_COLOR
  720. link.Transparency = 0
  721. link.Size = Vector3.new(LINK_THICKNESS, LINK_THICKNESS, dist)
  722. link.CFrame = CFrame.new(a, b) * CFrame.new(0, 0, -dist / 2)
  723. link.Parent = model
  724. end
  725.  
  726. return model
  727. end
  728.  
  729. local function registerRim(rim)
  730. -- Skip if already has arcs
  731. if ArcFolder:FindFirstChild('Payload0_StaticArc_' .. rim:GetDebugId()) then
  732. return
  733. end
  734.  
  735. for i, dist in ipairs(PERFECT_DISTANCES) do
  736. local extra = ARC_ADJUSTMENTS[i] or 0
  737. createStaticArc(rim, dist, extra)
  738. end
  739. end
  740.  
  741. -- === INITIAL SCAN ===
  742. for _, v in ipairs(Workspace:GetDescendants()) do
  743. if isValidRim(v) then
  744. registerRim(v)
  745. end
  746. end
  747.  
  748. -- === AUTO REGISTER ON SPAWN ===
  749. Workspace.DescendantAdded:Connect(function(o)
  750. if isValidRim(o) then
  751. registerRim(o)
  752. end
  753. end)
  754.  
Advertisement
Add Comment
Please, Sign In to add comment