Here what It should be like
Here what I get
the image for “Here what It should be like” is my old version without queue so It gonna be like that
--[[
CAUTION : THIS MODULE IS IN ALPHA!!!
THX TO : wackz for insp and shatterbox for optimize tips!!!
Version: 1
]]
local blockBuster = {}
--remotes
local replicate = script.Replicate
--modules
local Subdivide = require(script.Subdivide)
local Encapsulates = require(script.Encapsulates)
local PartSen = require(script.PartSen)
--Setup
local tempBlockBusterFolder = Instance.new("Folder",workspace)
tempBlockBusterFolder.Name = ""
local server = Instance.new("Folder",workspace)
server.Name = "server_blockBuster"
local client = Instance.new("Folder",workspace)
client.Name = "client_blockBuster"
--Service and stuff
local runService = game:GetService("RunService")
local blockBusterQueue = {}
local currentId = 0
blockBuster.destroyableTag = "Destroyable"
--optimize stuff
blockBuster.maxDividePerFrame = 100
blockBuster.defaultVoxelSize = 1 --defalut voxel size change this if you like!!!
--this is default overlapParams bc why not
blockBuster.defaultOverlapParams = OverlapParams.new()
blockBuster.defaultOverlapParams.FilterType = Enum.RaycastFilterType.Exclude
blockBuster.defaultOverlapParams.FilterDescendantsInstances = {}
blockBuster.partDestroy = function(part) -- you can change behivor of this to make what you like (when destroy voxels btw) this get replicate to client too so IF you want 2 behavior using rs in the function
part:Destroy()
end
function destroy(part,isVoxel,destroyFunction) -- this is for the replicate Stuff
if isVoxel then
destroyFunction(part)
else
part:Destroy()
end
end
function divideable(part: BasePart, allowTemp)
if not part:IsA("BasePart") then return false end
if part.Shape ~= Enum.PartType.Block then return false end
if not part:HasTag(blockBuster.destroyableTag) then return false end
if not allowTemp and part.Parent == tempBlockBusterFolder then return false end
return true
end
function blockBuster.partToHitbox(hitbox : BasePart, voxelSize : number, overlapParams : OverlapParams, voxelHandler)
replicate:FireAllClients()
local parts
voxelSize = voxelSize or blockBuster.defaultVoxelSize
overlapParams = overlapParams or blockBuster.defaultOverlapParams
voxelHandler = voxelHandler or blockBuster.partDestroy
if overlapParams == blockBuster.defaultOverlapParams then
overlapParams.FilterDescendantsInstances = {hitbox,tempBlockBusterFolder}
end
repeat
parts = workspace:GetPartsInPart(hitbox, overlapParams)
local remainingParts = {}
local processedParts = {}
if #parts == 0 then break end
local maxProcess = math.min(#parts, blockBuster.maxDividePerFrame)
for i = 1, maxProcess do
local part = parts[i]
if divideable(part) then
local subdivide = Subdivide.subdivide(part, voxelSize,hitbox)
if subdivide then
for _, sub in pairs(subdivide) do
--create a part in client
local size = sub.Size
local clonePart = part:Clone()
clonePart.Anchored = true
clonePart.CFrame = sub.CFrame
clonePart.Size = size
clonePart.Parent = server
end
destroy(part,false)
else
destroy(part,true,voxelHandler)
end
table.insert(processedParts,part)
end
end
for _, part in pairs(parts) do
if not table.find(processedParts,part) then
table.insert(remainingParts, part)
end
end
if #remainingParts > 0 then
for _, part in pairs(remainingParts) do
blockBusterQueue[part] = {
voxelSize = voxelSize,
voxelHandler = voxelHandler,
parent = server,
hitbox = hitbox,
}
part.Parent = tempBlockBusterFolder
end
end
until #parts == 0
end
runService.Heartbeat:Connect(function()
for part, data in pairs(blockBusterQueue) do
--if divideCount >= blockBuster.maxDividePerFrame then
-- break
--end
local voxelSize = data.voxelSize
local hitbox = data.hitbox
local handler = data.voxelHandler
if divideable(part,true) then
local subdivide = Subdivide.subdivide(part, voxelSize)
if subdivide then
for _, sub in pairs(subdivide) do
local size = sub.Size
local clonePart = part:Clone()
clonePart.Anchored = true
clonePart.CFrame = sub.CFrame
clonePart.Size = size
clonePart.Parent = server
if not Subdivide.isVoxel(size,voxelSize) then
blockBusterQueue[clonePart] = {
voxelSize = voxelSize,
voxelHandler = handler,
parent = server,
hitbox = hitbox,
}
clonePart.Parent = tempBlockBusterFolder
end
end
local isIn,Point = Encapsulates(part,hitbox.CFrame,hitbox.Size)
if Point > 0 then
destroy(part,false)
blockBusterQueue[part] = nil
elseif Point <= 0 then
blockBusterQueue[part] = nil
end
else
destroy(part,true,handler)
blockBusterQueue[part] = nil
end
else
blockBusterQueue[part] = nil
end
end
end)
return blockBuster