local J=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local s=game:GetService("\083\101\114\118\101\114\083\099\114\105\112\116\083\101\114\118\105\099\101")local p=require((s:WaitForChild("\070\117\110\099\116\105\111\110\097\108\068\111\109\097\105\110\115")):WaitForChild("\069\120\078\105\104\105\108\111"))local Z=require(J:WaitForChild("\078\101\118\101\114\109\111\114\101",2))local d=Z("\083\116\100")local t=d.rquery local F=Z("\114\111\100\097\115\104")local G={}function G.HasHumanoid(J)local s=F.any(J:GetChildren(),function(J)return J.Name=="\072\117\109\097\110\111\105\100"or J:IsA("\072\117\109\097\110\111\105\100")end)return s~=nil and s end function G.GetHumanoidFromPersonage(J)if not G.HasHumanoid(J)then error("\078\111\116 \097 \112\101\114\115\111\110\097\103\101\058 "..J.Name)return nil end local s=F.find(J:GetChildren(),function(J)return J.Name=="\072\117\109\097\110\111\105\100"or J:IsA("\072\117\109\097\110\111\105\100")end)return s end function G.IsPersonageR6(J)local s=G.GetHumanoidFromPersonage(J)if s.HumanoidRigType==0 then return true end return false end function G.AddDefaultR6Animations(J)local s=G.GetHumanoidFromPersonage(J)s.Died:Connect(onDied)s.Running:Connect(onRunning)s.Jumping:Connect(onJumping)s.Climbing:Connect(onClimbing)s.GettingUp:Connect(onGettingUp)s.FreeFalling:Connect(onFreeFall)s.FallingDown:Connect(onFallingDown)s.Seated:Connect(onSeated)s.PlatformStanding:Connect(onPlatformStanding)s.Swimming:Connect(onSwimming)end function G.SpawnPersonageAsync(J,s,Z,d,t)p.CreateFromServerStorage(J,s,Z,function(J)d(J)end,t)end function G.GetStorageFolderForGender(J)local s=""if F.startsWith(J,"\077")then s="\077\097\108\101\072\117\109\097\110\111\105\100\115"else s="\070\101\109\097\108\101\072\117\109\097\110\111\105\100\115"end return s end function G.GetPersonageFactoryAsync(J,s,p)p=p or{""}local function Z(s)local p=G.GetStorageFolderForGender(J)local Z=t.GetOrAddItem("\078\112\099\115","\070\111\108\100\101\114",game:GetService("\087\111\114\107\115\112\097\099\101"))local d=(game:GetService("\087\111\114\107\115\112\097\099\101")):FindFirstChild("\078\112\099\115")return G.SpawnPersonage(p)end end return G
-- Assemble pieces into a person

-- get a basic person

-- add a shirt 
-- pants

-- personality?
-- tools + ability

-- set health
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local exNihilo = require(ServerScriptService:WaitForChild("FunctionalDomains"):WaitForChild("ExNihilo"))

local require = require(ReplicatedStorage:WaitForChild("Nevermore", 2))
local std = require("Std")
local rq = std.rquery
local _  = require("rodash")

local module = {}

function module.HasHumanoid(personage)
    local hasHumanoid = _.any(personage:GetChildren(),
        function (entry)
            return entry.Name == "Humanoid" or entry:IsA("Humanoid")
        end)

    return hasHumanoid ~= nil and hasHumanoid
end

function module.GetHumanoidFromPersonage( personage )
    if not module.HasHumanoid( personage ) then
        error("Not a personage: " .. personage.Name)
        return nil
    end
    
    local humanoid = _.find(personage:GetChildren(), function(part) 
        return part.Name == "Humanoid" or part:IsA("Humanoid")
    end)

    return humanoid
end

function module.IsPersonageR6( personage )
    local humanoid = module.GetHumanoidFromPersonage(personage)

    if humanoid.HumanoidRigType == 0 then
        return true
    end

    return false
end

function module.AddDefaultR6Animations( personage )
    
    local humanoid = module.GetHumanoidFromPersonage(personage)

        humanoid.Died:Connect(onDied)
        humanoid.Running:Connect(onRunning)
        humanoid.Jumping:Connect(onJumping)
        humanoid.Climbing:Connect(onClimbing)
        humanoid.GettingUp:Connect(onGettingUp)
        humanoid.FreeFalling:Connect(onFreeFall)
        humanoid.FallingDown:Connect(onFallingDown)
        humanoid.Seated:Connect(onSeated)
        humanoid.PlatformStanding:Connect(onPlatformStanding)
        humanoid.Swimming:Connect(onSwimming)
    
end

function module.SpawnPersonageAsync(storageFolder, 
        personagePrototypeId, 
        spawnLocation,
        onSpawnCompleteCallback, targetFolder)
    
        exNihilo.CreateFromServerStorage(storageFolder, 
            personagePrototypeId,
            spawnLocation, 
            function(createdPersonage)
                onSpawnCompleteCallback(createdPersonage)
            end, targetFolder)
end

function module.GetStorageFolderForGender(gender)
    local storageFolder = ""
    if _.startsWith(gender, "M") then
        storageFolder = "MaleHumanoids"
    else
        storageFolder = "FemaleHumanoids"
    end

    return storageFolder
end

function module.GetPersonageFactoryAsync(gender, personagePrototypeId, recipe)
    recipe = recipe or { "" }

    local function createUsingRecipe(onSpawnCompleteCallback)
        local storageFolder = module.GetStorageFolderForGender(gender)
        local targetFolder = rq.GetOrAddItem("Npcs", "Folder", game:GetService("Workspace"))

        local Workspace = game:GetService("Workspace"):FindFirstChild("Npcs")
        return module.SpawnPersonage(storageFolder)
    end 
end

return module