heres the module code:
--Services
local AvatarEditorService = game:GetService("AvatarEditorService")
local RunService = game:GetService("RunService")
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local catalog = {}
catalog.assetFolders = {}
catalog.creatorName = ""
catalog.dataItems = {
-- Extras
["DynamicHead"] = {};
["Gear"] = {};
-- Accessories
["BackAccessory"] = {};
["FaceAccessory"] = {};
["FrontAccessory"] ={};
["HairAccessory"] = {};
["Hat"] = {};
["NeckAccessory"] = {};
["ShoulderAccessory"] = {};
["WaistAccessory"] = {};
-- Animations
["ClimbAnimation"] = {};
["FallAnimation"] = {};
["IdleAnimation"] = {};
["JumpAnimation"] = {};
["RunAnimation"] = {};
["SwimAnimation"] = {};
["WalkAnimation"] = {};
["EmoteAnimation"] = {};
-- Body Parts
["Face"] = {};
["Head"] = {};
["LeftArm"] = {};
["LeftLeg"] = {};
["RightArm"] = {};
["RightLeg"] = {};
["Torso"] = {};
-- Clothes
["TShirt"] = {};
["Pants"] = {};
["Shirt"] = {};
}
-- roblox api is broken currently and gives camelCase
local function tableToPascalCaseKeys(oldTable)
local newTable = {}
for k, v in pairs(oldTable) do
local newKey = k
if typeof(k) == "string" then
newKey = string.upper(string.sub(k, 1, 1)) .. string.sub(k, 2)
end
local newValue = v
if typeof(v) == "table" then
newValue = tableToPascalCaseKeys(v)
end
newTable[newKey] = newValue
end
return newTable
end
function iterPageItems(pages)
return coroutine.wrap(function()
local pagenum = 1
while true do
for _, item in ipairs(pages:GetCurrentPage()) do
coroutine.yield(item, pagenum)
end
if pages.IsFinished then
break
end
pages:AdvanceToNextPageAsync()
pagenum = pagenum + 1
end
end)
end
-- Reformat pages as tables
--local function pagesToTable(pages)
-- local items = {}
-- while true do
-- table.insert(items, pages:GetCurrentPage())
-- if pages.IsFinished then
-- break
-- end
-- pages:AdvanceToNextPageAsync()
-- end
-- return items
--end
--local function iterPageItems(pages)
-- local contents = pagesToTable(pages)
-- -- Track the current page number starting at 1
-- local pageNum = 1
-- -- Get last page number so we don't iterate over it
-- local lastPageNum = #contents
-- -- for resumes this coroutine until there's nothing to go through
-- return coroutine.wrap(function()
-- -- Loop until page number is greater than last page number
-- while pageNum <= lastPageNum do
-- -- Go through all the entries of the current page
-- for _, item in ipairs(contents[pageNum]) do
-- -- Pause loop to let developer handle entry and page number
-- coroutine.yield(item, pageNum)
-- end
-- pageNum += 1
-- end
-- end)
--end
local function retry(functionToRetry, timeToWait, max): (boolean, any)
if not timeToWait then timeToWait = 2 end
if not max then max = math.huge end
local success, returnValue
local attempts = 0
repeat
success, returnValue = pcall(functionToRetry)
if not success then
warn(returnValue)
local timeWaited = 0
repeat
timeWaited += RunService.Heartbeat:Wait()
until timeWaited >= timeToWait
end
attempts += 1
until success == true or attempts == max
return success, returnValue
end
function catalog:generateCatalog(options: { assetTypes: { Enum.AvatarAssetType }, searchKeyword: string|nil, creatorName: string|nil })
local params = CatalogSearchParams.new()
params.AssetTypes = options.assetTypes
params.SearchKeyword = options.searchKeyword or ""
params.CreatorName = options.creatorName or ""
local itemAssetType
for _, avatarAssetType in options.assetTypes do
if avatarAssetType == Enum.AvatarAssetType.ClimbAnimation or avatarAssetType == Enum.AvatarAssetType.FallAnimation or avatarAssetType == Enum.AvatarAssetType.IdleAnimation or avatarAssetType == Enum.AvatarAssetType.JumpAnimation or avatarAssetType == Enum.AvatarAssetType.RunAnimation or avatarAssetType == Enum.AvatarAssetType.SwimAnimation or avatarAssetType == Enum.AvatarAssetType.WalkAnimation then
params.CreatorName = "Roblox"
params.SearchKeyword = ""
params.IncludeOffSale = true
elseif avatarAssetType == Enum.AvatarAssetType.Head then
params.CreatorName = "Roblox"
params.SearchKeyword = ""
params.IncludeOffSale = false
else
params.AssetTypes = {avatarAssetType}
end
itemAssetType = avatarAssetType.Name
end
while #self.dataItems[itemAssetType] < script:GetAttribute("maxItems") and #self.dataItems[itemAssetType] == 0 do
local _, result = retry(function()
return AvatarEditorService:SearchCatalog(params)
end)
if #self.dataItems[itemAssetType] < script:GetAttribute("maxItems") and #self.dataItems[itemAssetType] == 0 then
-- generate new results
local currentPage = result:GetCurrentPage()
for index, itemData in pairs(currentPage) do --for index, itemData in ipairs(currentPage) do
if script:GetAttribute("showFolders") then
if not script:FindFirstChild("Assets") then
Instance.new("Folder", script).Name = "Assets"
end
local folders = catalog:setUpFolders(itemAssetType)
for _, folder in folders do
for i=1, script:GetAttribute("maxItems") do
local item = Instance.new("NumberValue", script.Assets:FindFirstChild(itemData.AssetType))
item.Name = itemData.Name
item.Value = itemData.Id
local Childs = script.Assets:FindFirstChild(itemData.AssetType):GetChildren() --You can edit this for whatever fits for you.
local StringValueNames = {} --A table just to put the original string value names in.
for i,v in ipairs(Childs) do
if v:IsA("NumberValue") then
if table.find(StringValueNames,v.Name,1) == nil then
table.insert(StringValueNames,#StringValueNames+1,v.Name) --Inserts a new stringvalue name because there wasn't one in the table.
else
v:Destroy() --Destroys the string value because another stringvalue with the same name exist.
end
end
end
break
end
end
end
--if #self.dataItems[itemAssetType] == script:GetAttribute("maxItems") then
-- break
--end
table.insert(self.dataItems[itemAssetType], itemData.Id)
if #self.dataItems[itemAssetType] == script:GetAttribute("maxItems") then
break
end
end
pcall(result.AdvanceToNextPageAsync, result)
else--if #self.dataItems[itemAssetType] == script:GetAttribute("maxItems") then
break
end
end
return self.dataItems
end
function catalog:setUpFolders(data)
retry(function()
if not script.Assets:FindFirstChild(data) then
local Folder = Instance.new("Folder", script.Assets)
Folder.Name = data
table.insert(self.assetFolders, Folder)
end
end)
return self.assetFolders
end
return catalog
Why does it not work? last time with my code it worked but now it doesn’t. Anyone know why?