Advertisement
yal_f

Untitled

May 2nd, 2024 (edited)
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.40 KB | None | 0 0
  1. --!optimize 2
  2.  
  3. local debrisHandler = require(script.DebrisModule)
  4. local module = {}
  5.  
  6. --
  7.  
  8. local RES = 1
  9. local DEBRIS_LIFETIME = 15
  10.  
  11. --
  12.  
  13. local function CubePointCollision(cubeCFrame, cubeSize, params)
  14.     local point = params[1]
  15.     local localSphereCenter = cubeCFrame:PointToObjectSpace(point)
  16.  
  17.     local closestLocalPoint = localSphereCenter:Min(cubeSize/2):Max(-cubeSize/2)
  18.     local closestGlobalPoint = cubeCFrame:PointToWorldSpace(closestLocalPoint)
  19.  
  20.     return (closestGlobalPoint - point).Magnitude
  21. end
  22.  
  23. local function CubeLineCollision(cubeCFrame, cubeSize, params)
  24.     local rayStart = params[1]
  25.     local rayDir = params[2]
  26.     local depth = params[3]-1
  27.  
  28.     local lowestDist = math.huge
  29.     local offset = 0
  30.  
  31.     for i = 1, depth do
  32.         local stack = math.ldexp(1, i-1)
  33.  
  34.         local subRayDir = rayDir/stack
  35.         local totalRayOffset = rayStart + (rayDir*offset)
  36.  
  37.         local dist1 = CubePointCollision(cubeCFrame, cubeSize, {totalRayOffset + (subRayDir*.25)})
  38.         local dist2 = CubePointCollision(cubeCFrame, cubeSize, {totalRayOffset + (subRayDir*.75)})
  39.  
  40.         if dist1 < dist2 then
  41.             lowestDist = dist1
  42.         else
  43.             lowestDist = dist2
  44.             offset += .5/stack
  45.         end
  46.     end
  47.  
  48.     return lowestDist
  49. end
  50.  
  51. local collisionMap = {
  52.     point = CubePointCollision,
  53.     line = CubeLineCollision
  54. }
  55.  
  56. --
  57.  
  58. function module.DestroyPartInRange(part, range: number, force, power: number, mode: string, params)
  59.     local partRef = part:Clone()
  60.     part:Destroy()
  61.  
  62.     local collision = collisionMap[mode]
  63.  
  64.     local partSize = partRef.Size
  65.     local resFull = (partSize//RES)+Vector3.one
  66.    
  67.     local resX = resFull.X
  68.     local resY = resFull.Y
  69.     local resZ = resFull.Z
  70.  
  71.     local resXY = resX*resY
  72.     local bitSize = partSize/resFull
  73.     local debrisSize = bitSize*0.9
  74.     local minBound = partRef.CFrame * CFrame.new((bitSize - partSize)/2)
  75.     local reserved = buffer.create(resX*resY*resZ)
  76.    
  77.     --
  78.  
  79.     for Z = 0, resZ-1 do
  80.         local ZIndex = Z * resXY
  81.         for Y = 0, resY-1 do
  82.             local YZIndex = (Y * resX) + ZIndex
  83.             for X = 0, resX-1 do
  84.                 local gridIndex = X + YZIndex
  85.                 if buffer.readu8(reserved, gridIndex) == 1 then
  86.                     continue
  87.                 end
  88.  
  89.                 local truePos = minBound * CFrame.new(Vector3.new(X,Y,Z)*bitSize)
  90.                 local dist = collision(truePos, bitSize, params)
  91.  
  92.                 if dist > range then
  93.                     local xMax, yMax, zMax = 1,1,1
  94.                    
  95.                     for x = X+1, resX-1 do
  96.                         local reserveIndex = gridIndex+xMax
  97.                         local nextTruePos = minBound * CFrame.new(Vector3.new(x,Y,Z)*bitSize)
  98.  
  99.                         if buffer.readu8(reserved, reserveIndex) == 1 or collision(nextTruePos, bitSize, params) <= range then
  100.                             break
  101.                         end
  102.  
  103.                         buffer.writeu8(reserved, reserveIndex, 1)
  104.                         xMax += 1
  105.                     end
  106.  
  107.                     for y = Y+1, resY-1 do
  108.                         if collision(minBound * CFrame.new(Vector3.new(X+(xMax-1)/2,y,Z)*bitSize), Vector3.new(bitSize.X*xMax, bitSize.Y, bitSize.Z), params) <= range then
  109.                             break
  110.                         end
  111.  
  112.                         local abort
  113.                         local yzIndex = (y*resX) + ZIndex
  114.  
  115.                         for x = X, X+xMax-1 do
  116.                             if buffer.readu8(reserved, x + yzIndex) == 1 then
  117.                                 abort = true
  118.                                 break
  119.                             end
  120.                         end
  121.  
  122.                         if abort then
  123.                             break
  124.                         end
  125.  
  126.                         buffer.fill(reserved, X + yzIndex, 1, xMax)
  127.                         yMax += 1
  128.                     end
  129.  
  130.                     for z = Z+1, resZ-1 do
  131.                         if collision(minBound * CFrame.new(Vector3.new(X+(xMax-1)/2, Y+(yMax-1)/2, z)*bitSize), Vector3.new(bitSize.X*xMax, bitSize.Y*yMax, bitSize.Z), params) <= range then
  132.                             break
  133.                         end
  134.  
  135.                         local abort
  136.                        
  137.                         local clock = os.clock()
  138.                        
  139.                         local zIndex = z * resXY
  140.  
  141.                         for y = Y, Y+yMax-1 do
  142.                             local yzIndex = (y*resX) + zIndex
  143.  
  144.                             for x = X, X+xMax-1 do
  145.                                 if buffer.readu8(reserved, x + yzIndex) == 1 then
  146.                                     abort = true
  147.                                     break
  148.                                 end
  149.                             end
  150.  
  151.                             if abort then
  152.                                 break
  153.                             end
  154.                         end
  155.  
  156.                         if abort then
  157.                             break
  158.                         end
  159.  
  160.                         for y = Y, Y+yMax-1 do
  161.                             buffer.fill(reserved, X + (y*resX) + zIndex, 1, xMax)
  162.                         end
  163.                        
  164.                         stat += os.clock() - clock
  165.  
  166.                         zMax += 1
  167.                     end
  168.  
  169.                     --
  170.  
  171.                     local partSize = bitSize * Vector3.new(xMax, yMax, zMax)
  172.  
  173.                     local bit = partRef:Clone()
  174.                     bit.CFrame = truePos * CFrame.new((partSize-bitSize)/2)
  175.                     bit.Size = partSize
  176.                     bit.Parent = workspace
  177.                 elseif dist > range*power then
  178.                     task.defer(debrisHandler.CreateDebrisFromRef, force, DEBRIS_LIFETIME, partRef, debrisSize, truePos)
  179.                 end
  180.             end
  181.         end
  182.     end
  183. end
  184.  
  185. return module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement