function RoomPackager.CategoriseModel(q,Z)if Z:FindFirstChild("\069\110\100\080\097\114\116\115")then return game.ReplicatedStorage.PathModules.Branch elseif Z.ObjectPrimaryPart.PathName.Value=="\083\116\097\114\116"then return game.ReplicatedStorage.PathModules.StartModule elseif Z.Start.Position.Y<Z.End.Position.Y-5 then return game.ReplicatedStorage.PathModules.GoingUp elseif Z.Start.Position.Y>Z.End.Position.Y+5 then return game.ReplicatedStorage.PathModules.GoingDown else return game.ReplicatedStorage.PathModules.SameHeight end end local function Z(q,C)local A=q:GetChildren()for q=1,#A,1 do if A[q]:isA("\066\097\115\101\080\097\114\116")then(C:Clone()).Parent=A[q]else Z(A[q],C)end end end RoomPackager.setUpBehaviours=function(q)if q:FindFirstChild("\066\101\104\097\118\105\111\117\114\115")then Z(q,q.Behaviours)return end local C=q:GetChildren()for Z=1,#C,1 do RoomPackager.setUpBehaviours(C[Z])end end function RoomPackager.PackageRoom(q,Z)local C=Instance.new("\077\111\100\101\108")C.Name=Z.PathName.Value C.Parent=game.ReplicatedStorage.PathModules local A=q:RegionFromBasePlate(Z)local G=false while true do local Z=game.Workspace:FindPartsInRegion3(A,nil,100)for Z,q in pairs(Z)do if q.Name=="\069\110\100"and C:FindFirstChild("\069\110\100")then local Z=Instance.new("\077\111\100\101\108")Z.Name="\069\110\100\080\097\114\116\115"Z.Parent=C q.Parent=Z;(C:FindFirstChild("\069\110\100")).Parent=Z elseif q.Name=="\069\110\100"and C:FindFirstChild("\069\110\100\080\097\114\116\115")then q.Parent=C:FindFirstChild("\069\110\100\080\097\114\116\115")else local Z=closestParentToWorkspace(q)if Z~=nil then if Z~=q.Parent then G=true end Z.Parent=C end end end if G==false then break else G=false end end C.ObjectPrimaryPart.Transparency=1 C.Start.Transparency=1 if C:FindFirstChild("\069\110\100\080\097\114\116\115")then local Z=(C:FindFirstChild("\069\110\100\080\097\114\116\115")):GetChildren()for q=1,#Z,1 do Z[q].Transparency=1 end else C.End.Transparency=1 end C.PrimaryPart=C.ObjectPrimaryPart C.Parent=q:CategoriseModel(C)RoomPackager.setUpBehaviours(C)return C end return RoomPackager
--Categorises a model based on the location of the start and end points of the path in the model
function RoomPackager:CategoriseModel(pathModel)
	if pathModel:FindFirstChild("EndParts") then
		return game.ReplicatedStorage.PathModules.Branch
	elseif pathModel.ObjectPrimaryPart.PathName.Value == "Start" then
		return game.ReplicatedStorage.PathModules.StartModule
	elseif pathModel.Start.Position.Y < pathModel.End.Position.Y - 5 then
		return game.ReplicatedStorage.PathModules.GoingUp
	elseif pathModel.Start.Position.Y > pathModel.End.Position.Y + 5 then
		return game.ReplicatedStorage.PathModules.GoingDown
	else
		return game.ReplicatedStorage.PathModules.SameHeight
	end
end

local function addBehavioursRecur(model, behaviourFolder)
	local children = model:GetChildren()
	for i = 1, #children do
		if children[i]:isA("BasePart") then
			behaviourFolder:Clone().Parent = children[i]
		else
			addBehavioursRecur(children[i], behaviourFolder)
		end
	end
end

RoomPackager.setUpBehaviours = function(roomModel)
	if roomModel:FindFirstChild("Behaviours") then
		addBehavioursRecur(roomModel, roomModel.Behaviours)
		return
	end
	local children = roomModel:GetChildren()
	for i = 1, #children do
		RoomPackager.setUpBehaviours(children[i])
	end
end

function RoomPackager:PackageRoom(roomBasePlate)
	local roomModel = Instance.new("Model")
	roomModel.Name = roomBasePlate.PathName.Value
	roomModel.Parent = game.ReplicatedStorage.PathModules

	local region = self:RegionFromBasePlate(roomBasePlate)
	local modelFound = false

	--Repeatedly finds 100 parts in the region, if the parts are seperated into different models more than 100 parts can be used
	while true do
		local parts = game.Workspace:FindPartsInRegion3(region, nil, 100)
		for _, part in pairs(parts) do
			if part.Name == "End" and roomModel:FindFirstChild("End") then
				local endsModel = Instance.new("Model") --Used for branching the path
				endsModel.Name = "EndParts"
				endsModel.Parent = roomModel
				part.Parent = endsModel
				roomModel:FindFirstChild("End").Parent = endsModel
			elseif part.Name == "End" and roomModel:FindFirstChild("EndParts") then
				part.Parent = roomModel:FindFirstChild("EndParts")
			else
				local topLevelParent = closestParentToWorkspace(part)
				if topLevelParent ~= nil then
					if topLevelParent ~= part.Parent then
						--A model has been found, this means we will search again for more parts in the region
						modelFound = true
					end
					topLevelParent.Parent = roomModel
				end
			end
		end
		if modelFound == false then
			break
		else
			modelFound = false
		end
	end

	--Set-up model for use in the path (parts for locating the path are made transparent)
	roomModel.ObjectPrimaryPart.Transparency = 1
	roomModel.Start.Transparency = 1
	if roomModel:FindFirstChild("EndParts") then
		local ends = roomModel:FindFirstChild("EndParts"):GetChildren()
		for i = 1, #ends do
			ends[i].Transparency = 1
		end
	else
		roomModel.End.Transparency = 1
	end
	roomModel.PrimaryPart = roomModel.ObjectPrimaryPart
	roomModel.Parent = self:CategoriseModel(roomModel)
	RoomPackager.setUpBehaviours(roomModel)
	return roomModel
end

return RoomPackager
