Dark_Agent

FE Nano Bots Module Script

Dec 23rd, 2025
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 22.00 KB | Gaming | 0 0
  1. if not game:IsLoaded() then game.Loaded:Wait() end
  2.  
  3. local function missing(t, f, fallback)
  4.     if type(f) == t then return f end
  5.     return fallback
  6. end
  7.  
  8. cloneref = missing("function", cloneref, function(...) return ... end)
  9. newcclosure = missing("function", newcclosure, function(f) return f end)
  10. setscriptable = missing("function", setscriptable, nil)
  11. sethiddenproperty = missing("function", sethiddenproperty or set_hidden_property or set_hidden_prop, nil)
  12.  
  13. local sethidden = newcclosure(function(instance, property, value)
  14.     pcall(function()
  15.         if sethiddenproperty then
  16.             sethiddenproperty(instance, property, value)
  17.         elseif setscriptable then
  18.             setscriptable(instance, property, true)
  19.             instance[property] = value
  20.             task.wait()
  21.             setscriptable(instance, property, false)
  22.         else
  23.             instance[property] = value
  24.         end
  25.     end)
  26. end)
  27.  
  28. local Services = setmetatable({}, {
  29.     __index = function(self, name)
  30.         local ok, svc = pcall(function() return cloneref(game:GetService(name)) end)
  31.         if ok then rawset(self, name, svc) return svc end
  32.         error("Invalid Service: " .. tostring(name))
  33.     end
  34. })
  35.  
  36. local Players = Services.Players
  37. local RunService = Services.RunService
  38. local Workspace = Services.Workspace
  39. local UserInputService = Services.UserInputService
  40. local LocalPlayer = Players.LocalPlayer
  41.  
  42. local function CleanupNano()
  43.     if getgenv().NanoConnection then
  44.         getgenv().NanoConnection:Disconnect()
  45.         getgenv().NanoConnection = nil
  46.     end
  47.    
  48.     if getgenv().NanoRuntime and getgenv().NanoRuntime.BodyMovers then
  49.         for part, _ in pairs(getgenv().NanoRuntime.BodyMovers) do
  50.             pcall(function()
  51.                 if part and part.Parent then
  52.                     local bp = part:FindFirstChild("NanoBP")
  53.                     local bg = part:FindFirstChild("NanoBG")
  54.                     if bp then bp:Destroy() end
  55.                     if bg then bg:Destroy() end
  56.                    
  57.                     local state = getgenv().NanoRuntime.OriginalStates[part]
  58.                     if state then
  59.                         part.CanCollide = state.CanCollide
  60.                         part.Massless = state.Massless
  61.                     end
  62.                 end
  63.             end)
  64.         end
  65.     end
  66.    
  67.     if getgenv().NanoGui then
  68.         pcall(function() getgenv().NanoGui:Destroy() end)
  69.         getgenv().NanoGui = nil
  70.     end
  71.    
  72.     if getgenv().NanoDebugBox then
  73.         pcall(function() getgenv().NanoDebugBox:Destroy() end)
  74.         getgenv().NanoDebugBox = nil
  75.     end
  76.    
  77.     getgenv().NanoRuntime = nil
  78. end
  79.  
  80. CleanupNano()
  81.  
  82. getgenv().NanoConfigs = {
  83.     ContainerSize = Vector3.new(10, 10, 10),
  84.    
  85.     OffsetX = 0,
  86.     OffsetY = 5,
  87.     OffsetZ = -14,
  88.    
  89.     RotateX = 0,
  90.     RotateY = 0,
  91.     RotateZ = 0,
  92.    
  93.     ScanRadius = 100,
  94.     ScanBoxSize = Vector3.new(80, 40, 80),
  95.     MaxParts = 500,
  96.    
  97.     SimRadius = 1000,
  98.    
  99.     PartsCanCollide = false,
  100.     PartsMassless = true,
  101.    
  102.     Padding = 0.05,
  103.    
  104.     BinFollow = false,
  105.     PackInterval = 0.4,
  106.    
  107.     BodyPositionP = 50000,
  108.     BodyPositionD = 800,
  109.     BodyPositionMaxForce = 1e9,
  110.    
  111.     BodyGyroP = 10000,
  112.     BodyGyroD = 300,
  113.     BodyGyroMaxTorque = 1e9,
  114.    
  115.     AutoResize = true,
  116.     MinSize = Vector3.new(5, 5, 5),
  117.     MaxSize = Vector3.new(25, 25, 25),
  118.    
  119.     CheckNetworkOwner = true,
  120.     UseRootPriority = true,
  121.     RootPriorityValue = 2147483647,
  122.    
  123.     Whitelist = nil,
  124.     Blacklist = nil,
  125.    
  126.     Debug = true,
  127.     ShowContainer = true
  128. }
  129.  
  130. local CFG = getgenv().NanoConfigs
  131.  
  132. getgenv().NanoRuntime = {
  133.     BodyMovers = {},
  134.     OriginalStates = {},
  135.     Placements = {},
  136.    
  137.     LastPackTime = 0,
  138.     LastPartCount = 0,
  139.     StaticLocation = nil,
  140.     SimRadiusSet = false,
  141.     IsRunning = false,
  142.     CurrentSize = nil,
  143.    
  144.     Stats = {
  145.         Parts = 0,
  146.         Efficiency = 0,
  147.         Dropped = 0
  148.     }
  149. }
  150.  
  151. local Runtime = getgenv().NanoRuntime
  152.  
  153. local function Log(msg)
  154.     if CFG.Debug then print("[NANO]", msg) end
  155. end
  156.  
  157. local function SetSimRadius()
  158.     if Runtime.SimRadiusSet then return end
  159.     sethidden(LocalPlayer, "SimulationRadius", CFG.SimRadius)
  160.     sethidden(LocalPlayer, "MaximumSimulationRadius", CFG.SimRadius)
  161.     Runtime.SimRadiusSet = true
  162. end
  163.  
  164. local function GetContainerCFrame(rootCF)
  165.     local offset = CFrame.new(CFG.OffsetX, CFG.OffsetY, CFG.OffsetZ)
  166.     local rotation = CFrame.Angles(math.rad(CFG.RotateX), math.rad(CFG.RotateY), math.rad(CFG.RotateZ))
  167.     return rootCF * offset * rotation
  168. end
  169.  
  170. local Shelf3D = {}
  171. Shelf3D.__index = Shelf3D
  172.  
  173. function Shelf3D.new(containerSize, padding)
  174.     local self = setmetatable({}, Shelf3D)
  175.     self.W = containerSize.X
  176.     self.H = containerSize.Y
  177.     self.D = containerSize.Z
  178.     self.padding = padding or 0.05
  179.     self.halfSize = containerSize / 2
  180.    
  181.     self.layers = {}
  182.     self.currentLayerZ = 0
  183.     self.currentLayerMaxD = 0
  184.    
  185.     self.shelves = {}
  186.     self.currentShelfY = 0
  187.     self.currentShelfMaxH = 0
  188.    
  189.     self.cursorX = 0
  190.    
  191.     self.placements = {}
  192.     self.usedVolume = 0
  193.     self.containerVolume = containerSize.X * containerSize.Y * containerSize.Z
  194.    
  195.     return self
  196. end
  197.  
  198. function Shelf3D:getBestRotation(partSize)
  199.     local rotations = {
  200.         {s = Vector3.new(partSize.X, partSize.Y, partSize.Z), r = CFrame.new()},
  201.         {s = Vector3.new(partSize.Z, partSize.Y, partSize.X), r = CFrame.Angles(0, math.rad(90), 0)},
  202.         {s = Vector3.new(partSize.X, partSize.Z, partSize.Y), r = CFrame.Angles(math.rad(90), 0, 0)},
  203.         {s = Vector3.new(partSize.Y, partSize.X, partSize.Z), r = CFrame.Angles(0, 0, math.rad(90))},
  204.         {s = Vector3.new(partSize.Z, partSize.X, partSize.Y), r = CFrame.Angles(math.rad(90), math.rad(90), 0)},
  205.         {s = Vector3.new(partSize.Y, partSize.Z, partSize.X), r = CFrame.Angles(0, math.rad(90), math.rad(90))}
  206.     }
  207.    
  208.     local best = nil
  209.     local bestScore = math.huge
  210.    
  211.     for _, rot in ipairs(rotations) do
  212.         local s = rot.s
  213.         if s.X <= self.W and s.Y <= self.H and s.Z <= self.D then
  214.             local score = s.Y * 100 + s.Z * 10 + s.X
  215.             if score < bestScore then
  216.                 bestScore = score
  217.                 best = rot
  218.             end
  219.         end
  220.     end
  221.    
  222.     return best
  223. end
  224.  
  225. function Shelf3D:place(part)
  226.     local rot = self:getBestRotation(part.Size)
  227.     if not rot then return nil end
  228.    
  229.     local w, h, d = rot.s.X, rot.s.Y, rot.s.Z
  230.     local pad = self.padding
  231.    
  232.     if self.cursorX + w > self.W then
  233.         self.cursorX = 0
  234.         self.currentShelfY = self.currentShelfY + self.currentShelfMaxH + pad
  235.         self.currentShelfMaxH = 0
  236.     end
  237.    
  238.     if self.currentShelfY + h > self.H then
  239.         self.currentShelfY = 0
  240.         self.currentShelfMaxH = 0
  241.         self.cursorX = 0
  242.         self.currentLayerZ = self.currentLayerZ + self.currentLayerMaxD + pad
  243.         self.currentLayerMaxD = 0
  244.     end
  245.    
  246.     if self.currentLayerZ + d > self.D then
  247.         return nil
  248.     end
  249.    
  250.     local x = self.cursorX
  251.     local y = self.currentShelfY
  252.     local z = self.currentLayerZ
  253.    
  254.     local localPos = Vector3.new(
  255.         x + w/2 - self.halfSize.X,
  256.         y + h/2 - self.halfSize.Y,
  257.         z + d/2 - self.halfSize.Z
  258.     )
  259.    
  260.     self.cursorX = x + w + pad
  261.     self.currentShelfMaxH = math.max(self.currentShelfMaxH, h)
  262.     self.currentLayerMaxD = math.max(self.currentLayerMaxD, d)
  263.    
  264.     self.usedVolume = self.usedVolume + (w * h * d)
  265.    
  266.     local placement = {
  267.         part = part,
  268.         localPos = localPos,
  269.         rotation = rot.r,
  270.         size = rot.s
  271.     }
  272.    
  273.     self.placements[#self.placements + 1] = placement
  274.     return placement
  275. end
  276.  
  277. function Shelf3D:getEfficiency()
  278.     if self.containerVolume == 0 then return 0 end
  279.     return self.usedVolume / self.containerVolume
  280. end
  281.  
  282. function Shelf3D:getUsedBounds()
  283.     local maxX = self.cursorX
  284.     local maxY = self.currentShelfY + self.currentShelfMaxH
  285.     local maxZ = self.currentLayerZ + self.currentLayerMaxD
  286.     return Vector3.new(maxX, maxY, maxZ)
  287. end
  288.  
  289. local function CreateGui()
  290.     if getgenv().NanoGui then return end
  291.    
  292.     local gui = Instance.new("ScreenGui")
  293.     gui.Name = "NanoGui"
  294.     gui.ResetOnSpawn = false
  295.    
  296.     local main = Instance.new("Frame")
  297.     main.Size = UDim2.new(0, 200, 0, 140)
  298.     main.Position = UDim2.new(0, 10, 0.5, -70)
  299.     main.BackgroundColor3 = Color3.fromRGB(20, 20, 30)
  300.     main.BorderSizePixel = 0
  301.     main.Active = true
  302.     main.Parent = gui
  303.    
  304.     Instance.new("UICorner", main).CornerRadius = UDim.new(0, 8)
  305.    
  306.     local stroke = Instance.new("UIStroke", main)
  307.     stroke.Color = Color3.fromRGB(0, 200, 150)
  308.     stroke.Thickness = 1
  309.    
  310.     local dragging, dragStart, startPos
  311.     main.InputBegan:Connect(function(input)
  312.         if input.UserInputType == Enum.UserInputType.MouseButton1 then
  313.             dragging = true
  314.             dragStart = input.Position
  315.             startPos = main.Position
  316.         end
  317.     end)
  318.     main.InputEnded:Connect(function(input)
  319.         if input.UserInputType == Enum.UserInputType.MouseButton1 then
  320.             dragging = false
  321.         end
  322.     end)
  323.     UserInputService.InputChanged:Connect(function(input)
  324.         if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
  325.             local delta = input.Position - dragStart
  326.             main.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
  327.         end
  328.     end)
  329.    
  330.     local title = Instance.new("TextLabel")
  331.     title.Size = UDim2.new(1, -30, 0, 25)
  332.     title.Position = UDim2.new(0, 8, 0, 2)
  333.     title.BackgroundTransparency = 1
  334.     title.Text = "NanoBin Shelf3D"
  335.     title.TextColor3 = Color3.fromRGB(0, 255, 180)
  336.     title.TextSize = 14
  337.     title.Font = Enum.Font.GothamBold
  338.     title.TextXAlignment = Enum.TextXAlignment.Left
  339.     title.Parent = main
  340.    
  341.     local closeBtn = Instance.new("TextButton")
  342.     closeBtn.Size = UDim2.new(0, 22, 0, 22)
  343.     closeBtn.Position = UDim2.new(1, -26, 0, 3)
  344.     closeBtn.BackgroundColor3 = Color3.fromRGB(180, 50, 50)
  345.     closeBtn.Text = "X"
  346.     closeBtn.TextColor3 = Color3.new(1, 1, 1)
  347.     closeBtn.TextSize = 12
  348.     closeBtn.Font = Enum.Font.GothamBold
  349.     closeBtn.Parent = main
  350.     Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0, 4)
  351.     closeBtn.MouseButton1Click:Connect(CleanupNano)
  352.    
  353.     local stats = Instance.new("TextLabel")
  354.     stats.Name = "Stats"
  355.     stats.Size = UDim2.new(1, -16, 1, -32)
  356.     stats.Position = UDim2.new(0, 8, 0, 28)
  357.     stats.BackgroundTransparency = 1
  358.     stats.Text = "..."
  359.     stats.TextColor3 = Color3.fromRGB(180, 180, 180)
  360.     stats.TextSize = 11
  361.     stats.Font = Enum.Font.Gotham
  362.     stats.TextXAlignment = Enum.TextXAlignment.Left
  363.     stats.TextYAlignment = Enum.TextYAlignment.Top
  364.     stats.Parent = main
  365.    
  366.     pcall(function() gui.Parent = game:GetService("CoreGui") end)
  367.     if not gui.Parent then gui.Parent = LocalPlayer:WaitForChild("PlayerGui") end
  368.    
  369.     getgenv().NanoGui = gui
  370.    
  371.     task.spawn(function()
  372.         while gui.Parent and Runtime do
  373.             local s = Runtime.Stats
  374.             local sz = Runtime.CurrentSize or CFG.ContainerSize
  375.             stats.Text = string.format(
  376.                 "Parts: %d\nEfficiency: %.1f%%\nDropped: %d\n\nContainer: %.0fx%.0fx%.0f\nOffset: %.0f, %.0f, %.0f\nRotate: %.0f°, %.0f°, %.0f°",
  377.                 s.Parts,
  378.                 s.Efficiency * 100,
  379.                 s.Dropped,
  380.                 sz.X, sz.Y, sz.Z,
  381.                 CFG.OffsetX, CFG.OffsetY, CFG.OffsetZ,
  382.                 CFG.RotateX, CFG.RotateY, CFG.RotateZ
  383.             )
  384.             task.wait(0.2)
  385.         end
  386.     end)
  387. end
  388.  
  389. local function UpdateDebugBox(cf)
  390.     if not CFG.Debug or not CFG.ShowContainer then
  391.         if getgenv().NanoDebugBox then
  392.             pcall(function() getgenv().NanoDebugBox:Destroy() end)
  393.             getgenv().NanoDebugBox = nil
  394.         end
  395.         return
  396.     end
  397.    
  398.     local size = Runtime.CurrentSize or CFG.ContainerSize
  399.    
  400.     if not getgenv().NanoDebugBox or not getgenv().NanoDebugBox.Parent then
  401.         local box = Instance.new("Part")
  402.         box.Name = "NanoDebugBox"
  403.         box.Anchored = true
  404.         box.CanCollide = false
  405.         box.CastShadow = false
  406.         box.Material = Enum.Material.ForceField
  407.         box.Color = Color3.fromRGB(0, 255, 180)
  408.         box.Transparency = 0.9
  409.         box.Parent = Workspace
  410.         getgenv().NanoDebugBox = box
  411.     end
  412.    
  413.     getgenv().NanoDebugBox.CFrame = cf
  414.     getgenv().NanoDebugBox.Size = size
  415. end
  416.  
  417. local function GetOrCreateBP(part)
  418.     local bp = part:FindFirstChild("NanoBP")
  419.     if not bp then
  420.         bp = Instance.new("BodyPosition")
  421.         bp.Name = "NanoBP"
  422.         bp.MaxForce = Vector3.new(CFG.BodyPositionMaxForce, CFG.BodyPositionMaxForce, CFG.BodyPositionMaxForce)
  423.         bp.P = CFG.BodyPositionP
  424.         bp.D = CFG.BodyPositionD
  425.         bp.Parent = part
  426.     end
  427.     return bp
  428. end
  429.  
  430. local function GetOrCreateBG(part)
  431.     local bg = part:FindFirstChild("NanoBG")
  432.     if not bg then
  433.         bg = Instance.new("BodyGyro")
  434.         bg.Name = "NanoBG"
  435.         bg.MaxTorque = Vector3.new(CFG.BodyGyroMaxTorque, CFG.BodyGyroMaxTorque, CFG.BodyGyroMaxTorque)
  436.         bg.P = CFG.BodyGyroP
  437.         bg.D = CFG.BodyGyroD
  438.         bg.Parent = part
  439.     end
  440.     return bg
  441. end
  442.  
  443. local function RemoveMovers(part)
  444.     pcall(function()
  445.         local bp = part:FindFirstChild("NanoBP")
  446.         local bg = part:FindFirstChild("NanoBG")
  447.         if bp then bp:Destroy() end
  448.         if bg then bg:Destroy() end
  449.     end)
  450. end
  451.  
  452. local function IsValidPart(part)
  453.     if not part or not part.Parent then return false end
  454.     if not part:IsA("BasePart") then return false end
  455.     if part.Anchored then return false end
  456.     if part:IsA("Terrain") then return false end
  457.     if part.Name == "NanoDebugBox" then return false end
  458.    
  459.     local char = LocalPlayer.Character
  460.     if char and part:IsDescendantOf(char) then return false end
  461.    
  462.     local ancestor = part.Parent
  463.     while ancestor and ancestor ~= Workspace do
  464.         if ancestor:FindFirstChildOfClass("Humanoid") then return false end
  465.         ancestor = ancestor.Parent
  466.     end
  467.    
  468.     if CFG.Whitelist and #CFG.Whitelist > 0 then
  469.         local found = false
  470.         for _, name in ipairs(CFG.Whitelist) do
  471.             if part.Name == name or string.find(part.Name, name) then
  472.                 found = true
  473.                 break
  474.             end
  475.         end
  476.         if not found then return false end
  477.     end
  478.    
  479.     if CFG.Blacklist then
  480.         for _, name in ipairs(CFG.Blacklist) do
  481.             if part.Name == name or string.find(part.Name, name) then
  482.                 return false
  483.             end
  484.         end
  485.     end
  486.    
  487.     if CFG.CheckNetworkOwner then
  488.         local ok, owner = pcall(function() return part:GetNetworkOwner() end)
  489.         if ok and owner and owner ~= LocalPlayer then return false end
  490.     end
  491.    
  492.     local containerSize = Runtime.CurrentSize or CFG.ContainerSize
  493.     local minDim = math.min(containerSize.X, containerSize.Y, containerSize.Z)
  494.     local partMax = math.max(part.Size.X, part.Size.Y, part.Size.Z)
  495.    
  496.     if partMax > minDim * 0.9 then return false end
  497.     if part.Size.Magnitude < 0.3 then return false end
  498.    
  499.     return true
  500. end
  501.  
  502. local function SaveState(part)
  503.     if not Runtime.OriginalStates[part] then
  504.         Runtime.OriginalStates[part] = {
  505.             CanCollide = part.CanCollide,
  506.             Massless = part.Massless
  507.         }
  508.     end
  509. end
  510.  
  511. local function PreparePart(part)
  512.     pcall(function()
  513.         SaveState(part)
  514.        
  515.         if part.Locked then part.Locked = false end
  516.        
  517.         if CFG.UseRootPriority then
  518.             part.RootPriority = CFG.RootPriorityValue
  519.         end
  520.        
  521.         for _, child in ipairs(part:GetChildren()) do
  522.             local cn = child.ClassName
  523.             if cn == "BodyPosition" or cn == "BodyGyro" or cn == "BodyVelocity" or cn == "BodyForce" then
  524.                 if child.Name ~= "NanoBP" and child.Name ~= "NanoBG" then
  525.                     child:Destroy()
  526.                 end
  527.             elseif cn == "RopeConstraint" or cn == "RodConstraint" then
  528.                 child.Length = math.huge
  529.                 child.Visible = false
  530.             elseif cn == "SpringConstraint" then
  531.                 child.FreeLength = math.huge
  532.                 child.Stiffness = 0
  533.             elseif cn == "AlignPosition" then
  534.                 child.MaxForce = 0
  535.             elseif cn == "AlignOrientation" then
  536.                 child.MaxTorque = 0
  537.             end
  538.         end
  539.        
  540.         part.CanCollide = CFG.PartsCanCollide
  541.         part.Massless = CFG.PartsMassless
  542.     end)
  543. end
  544.  
  545. local function ScanParts(rootPos)
  546.     local params = OverlapParams.new()
  547.     params.FilterType = Enum.RaycastFilterType.Exclude
  548.    
  549.     local filter = {}
  550.     for _, player in ipairs(Players:GetPlayers()) do
  551.         if player.Character then filter[#filter + 1] = player.Character end
  552.     end
  553.     params.FilterDescendantsInstances = filter
  554.     params.MaxParts = CFG.MaxParts
  555.    
  556.     local parts = Workspace:GetPartBoundsInRadius(rootPos, CFG.ScanRadius, params)
  557.    
  558.     local valid = {}
  559.     for _, part in ipairs(parts) do
  560.         if IsValidPart(part) then
  561.             valid[#valid + 1] = part
  562.         end
  563.     end
  564.    
  565.     table.sort(valid, function(a, b)
  566.         local volA = a.Size.X * a.Size.Y * a.Size.Z
  567.         local volB = b.Size.X * b.Size.Y * b.Size.Z
  568.         return volA > volB
  569.     end)
  570.    
  571.     return valid
  572. end
  573.  
  574. local function PackParts(parts, containerCF)
  575.     local oldMovers = Runtime.BodyMovers
  576.     Runtime.BodyMovers = {}
  577.    
  578.     local partsSet = {}
  579.     for _, p in ipairs(parts) do partsSet[p] = true end
  580.    
  581.     for part, _ in pairs(oldMovers) do
  582.         if part and part.Parent and not partsSet[part] then
  583.             RemoveMovers(part)
  584.         end
  585.     end
  586.    
  587.     local containerSize = Runtime.CurrentSize or CFG.ContainerSize
  588.     local packer = Shelf3D.new(containerSize, CFG.Padding)
  589.    
  590.     local dropped = 0
  591.    
  592.     for _, part in ipairs(parts) do
  593.         PreparePart(part)
  594.         local placement = packer:place(part)
  595.        
  596.         if placement then
  597.             local bp = GetOrCreateBP(part)
  598.             local bg = GetOrCreateBG(part)
  599.            
  600.             local targetCF = containerCF * CFrame.new(placement.localPos) * placement.rotation
  601.             bp.Position = targetCF.Position
  602.             bg.CFrame = targetCF
  603.            
  604.             Runtime.BodyMovers[part] = {
  605.                 bp = bp,
  606.                 bg = bg,
  607.                 localPos = placement.localPos,
  608.                 rotation = placement.rotation
  609.             }
  610.         else
  611.             dropped = dropped + 1
  612.             RemoveMovers(part)
  613.         end
  614.     end
  615.    
  616.     Runtime.Stats.Parts = #packer.placements
  617.     Runtime.Stats.Efficiency = packer:getEfficiency()
  618.     Runtime.Stats.Dropped = dropped
  619.    
  620.     if CFG.AutoResize and packer:getEfficiency() > 0.85 and dropped > 0 then
  621.         local usedBounds = packer:getUsedBounds()
  622.         local newSize = Vector3.new(
  623.             math.min(containerSize.X * 1.1, CFG.MaxSize.X),
  624.             math.min(containerSize.Y * 1.1, CFG.MaxSize.Y),
  625.             math.min(containerSize.Z * 1.1, CFG.MaxSize.Z)
  626.         )
  627.         if newSize ~= containerSize then
  628.             Runtime.CurrentSize = newSize
  629.             Log(string.format("Resize: %.1fx%.1fx%.1f", newSize.X, newSize.Y, newSize.Z))
  630.         end
  631.     end
  632.    
  633.     Runtime.Placements = packer.placements
  634.    
  635.     return packer.placements
  636. end
  637.  
  638. local function UpdatePositions(containerCF)
  639.     for part, data in pairs(Runtime.BodyMovers) do
  640.         if part and part.Parent and data.bp and data.bg then
  641.             local targetCF = containerCF * CFrame.new(data.localPos) * data.rotation
  642.             data.bp.Position = targetCF.Position
  643.             data.bg.CFrame = targetCF
  644.         end
  645.     end
  646. end
  647.  
  648. local function StartNano()
  649.     local char = LocalPlayer.Character
  650.     if not char then return end
  651.    
  652.     local root = char:FindFirstChild("HumanoidRootPart")
  653.     local hum = char:FindFirstChildOfClass("Humanoid")
  654.     if not root or not hum then return end
  655.    
  656.     if Runtime.IsRunning then return end
  657.     Runtime.IsRunning = true
  658.     Runtime.CurrentSize = CFG.ContainerSize
  659.     Runtime.BodyMovers = {}
  660.     Runtime.OriginalStates = {}
  661.    
  662.     SetSimRadius()
  663.     CreateGui()
  664.    
  665.     if not CFG.BinFollow then
  666.         Runtime.StaticLocation = GetContainerCFrame(root.CFrame)
  667.     end
  668.    
  669.     hum.Died:Once(function()
  670.         Log("Died")
  671.         Runtime.IsRunning = false
  672.         for part, _ in pairs(Runtime.BodyMovers) do
  673.             if part and part.Parent then RemoveMovers(part) end
  674.         end
  675.         Runtime.BodyMovers = {}
  676.     end)
  677.    
  678.     local conn = RunService.Heartbeat:Connect(function()
  679.         if not Runtime.IsRunning then return end
  680.        
  681.         local c = LocalPlayer.Character
  682.         local r = c and c:FindFirstChild("HumanoidRootPart")
  683.         local h = c and c:FindFirstChildOfClass("Humanoid")
  684.         if not r or not h or h.Health <= 0 then return end
  685.        
  686.         local containerCF
  687.         if CFG.BinFollow then
  688.             containerCF = GetContainerCFrame(r.CFrame)
  689.         else
  690.             containerCF = Runtime.StaticLocation
  691.         end
  692.        
  693.         UpdateDebugBox(containerCF)
  694.         UpdatePositions(containerCF)
  695.        
  696.         local now = tick()
  697.         if now - Runtime.LastPackTime >= CFG.PackInterval then
  698.             Runtime.LastPackTime = now
  699.            
  700.             local parts = ScanParts(r.Position)
  701.             local count = #parts
  702.            
  703.             if count ~= Runtime.LastPartCount then
  704.                 Runtime.LastPartCount = count
  705.                 PackParts(parts, containerCF)
  706.             end
  707.         end
  708.     end)
  709.    
  710.     getgenv().NanoConnection = conn
  711.     Log("Started - Shelf3D Packer")
  712. end
  713.  
  714. StartNano()
Advertisement
Add Comment
Please, Sign In to add comment