local script = script.Parent.Pieces.PieceScript if not script.Parent:FindFirstChild("Roots") then game.ServerStorage.Roots.Parent = script.Parent end local roots = {} for _,root in pairs(script.Parent.Roots:GetChildren()) do if root.Name == "Root" then root.Anchored = true root.Transparency = 1 root.CanCollide = false table.insert(roots,root) end end -- piece: {"X,Y,Z,NX,NY,NZ,A,B...} marking each property it has local pieces = {} for _,piece in pairs(script.Parent:GetChildren()) do if piece:IsA("Model") then -- Set of 'characteristics' this has, equivalent to (unary?) branches in lhmes14c local characteristics = {} local position = piece:GetPivot().Position local closest_root local closest = 32 for _,root in pairs(roots) do local distance = (root.Position - position).Magnitude if distance < closest then closest = distance closest_root = root end end if closest_root then closest_root.Parent = piece piece.PrimaryPart = closest_root end -- Make sure there is a PrimaryPart if not piece.PrimaryPart then piece.PrimaryPart = piece:FindFirstChildWhichIsA("BasePart") end if not piece.PrimaryPart then warn(string.format("Piece: '%s' has no viable PrimaryPart (empty), please provide one.",piece.Name)) continue end -- Weld all Parts together piece.PrimaryPart.Anchored = true local template_weld = Instance.new("WeldConstraint") template_weld.Part0 = piece.PrimaryPart for _,item in pairs(piece:GetChildren()) do if item:IsA("BasePart") and item ~= piece.PrimaryPart then local weld = template_weld:Clone() weld.Parent = piece weld.Part1 = item end end -- Populate characteristics for literal in string.gmatch(piece.Name,"[^%.]+") do local value,class = string.match(literal,"^(!?)(.*)") characteristics[class] = #value == 0 end piece.Parent = game.ServerStorage --piece:ScaleTo() table.insert(pieces,{characteristics = characteristics,piece = piece}) end end -- Compute whether variants are viable and actually copy/rotate them as options local rotator = { ["X"] = "Z", ["Z"] = "NX", ["NX"] = "NZ", ["NZ"] = "X" } local function alreadyExists(match) for _,piece in pairs(pieces) do local success = true for class,value in pairs(match) do if piece.characteristics[class] ~= value then success = false break end end if success then return true end end end local function rotateClass(class) return rotator[class] or class end local new_pieces = {} for _,piece in pairs(pieces) do -- This isn't very optimised, but it runs at the start of the program, this is ok. local r90 = {} local r180 = {} local r270 = {} for class,value in pairs(piece.characteristics) do local c90 = rotateClass(class) local c180 = rotateClass(c90) local c270 = rotateClass(c180) r90[c90] = value r180[c180] = value r270[c270] = value end local function pieceFactory(angle,characteristics) if not alreadyExists(characteristics) then local new_piece = piece.piece:Clone() new_piece.Name = "V."..new_piece.Name new_piece:PivotTo(new_piece:GetPivot() * CFrame.Angles(0,math.rad(angle),0)) table.insert(new_pieces,{piece = new_piece,characteristics = characteristics}) end end pieceFactory(270,r90) pieceFactory(180,r180) pieceFactory(90,r270) end for _,piece in pairs(pieces) do table.insert(new_pieces,piece) end pieces = new_pieces --[[local city = function(x,y,z) return (math.noise(x*0.16,y*0.16,z*0.16) - (y * 0.05) + 0.2) > 0 end]] local scale = 4 local template_part = Instance.new("Part") template_part.Anchored = true template_part.Name = "PieceTemplate" template_part.CanCollide = false template_part.Transparency = 0.5 template_part.Size = Vector3.one * scale local function block(x,y,z,f,city) local X = city(x+f,y,z) local Y = city(x,y+f,z) local Z = city(x,y,z+f) local NX = city(x-f,y,z) local NY = city(x,y-f,z) local NZ = city(x,y,z-f) local match = { -- The matching characteristics table for the hypothetical piece in this place X = X, Y = Y, Z = Z, NX = NX, NY = NY, NZ = NZ } if X and Y and Z and NX and NY and NZ then return false end local greatest_rank = 0 -- The amount of matching characteristics for the best matching piece local greatest = template_part -- The physical piece for _,piece in pairs(pieces) do -- Look through every known piece local rank = 0 for class,value in pairs(match) do -- Assimilate a rank of the characteristics it shares with this hypothetical one local this = piece.characteristics[class] if value == this then rank = rank + 1 elseif this ~= nil then rank = rank - 1 end -- If it's greatest, make it so end if rank > greatest_rank or (rank == greatest_rank and (math.random(1,10) > 3)) then greatest = piece.piece greatest_rank = rank end end greatest = greatest:Clone() greatest.Parent = game.Workspace -- Position it greatest:PivotTo(greatest:GetPivot().Rotation + Vector3.new(x,y,z)) return true end --[[local function gen() for x = 1,20 do for y = 1,15 do for z = 1,20 do if city(x,y,z) then end end end end end]] return {block=block}