local H=178 local u=13 local z=5 local A=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local Z=game:GetService("\080\104\121\115\105\099\115\083\101\114\118\105\099\101")local W=require((A:WaitForChild("\080\114\111\106\101\099\116")):WaitForChild("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101"))local s=(require((A:WaitForChild("\080\114\111\106\101\099\116")):WaitForChild("\083\101\114\118\101\114\083\099\114\105\112\116\083\101\114\118\105\099\101"))):GetContext(script)local V=W:GetResource("\071\097\109\101\068\097\116\097\046\073\116\101\109\046\073\116\101\109\115")local U=(W:GetResource("\069\120\116\101\114\110\097\108\085\116\105\108\046\078\101\120\117\115\073\110\115\116\097\110\099\101\046\078\101\120\117\115\073\110\115\116\097\110\099\101")):Extend()U:SetClassName("\067\104\097\114\097\099\116\101\114\083\101\114\118\105\099\101")U.LastPlayerCFrames={}s:SetContextResource(U)local d=s:GetResource("\083\101\114\118\105\099\101\046\073\110\118\101\110\116\111\114\121\083\101\114\118\105\099\101")local f=s:GetResource("\083\101\114\118\105\099\101\046\080\101\116\083\101\114\118\105\099\101")Z:CreateCollisionGroup("\067\104\097\114\097\099\116\101\114\115")Z:CollisionGroupSetCollidable("\067\104\097\114\097\099\116\101\114\115","\067\104\097\114\097\099\116\101\114\115",false)function U.GetRobloxIdForSlot(z,H,u)local A=d:GetItem(H,u)if A and A.Name then return V[A.Name].RobloxId end return 0 end function U.GetHumanoidDescription(u,H)local z=Instance.new("\072\117\109\097\110\111\105\100\068\101\115\099\114\105\112\116\105\111\110")z.HeadColor=(BrickColor.new("\066\114\105\103\104\116 \121\101\108\108\111\119")).Color z.LeftArmColor=(BrickColor.new("\066\114\105\103\104\116 \121\101\108\108\111\119")).Color z.RightArmColor=(BrickColor.new("\066\114\105\103\104\116 \121\101\108\108\111\119")).Color z.TorsoColor=(BrickColor.new("\066\114\105\103\104\116 \103\114\101\101\110")).Color z.LeftLegColor=(BrickColor.new("\066\114\105\103\104\116 \098\108\117\101")).Color z.RightLegColor=(BrickColor.new("\066\114\105\103\104\116 \098\108\117\101")).Color z.HatAccessory=u:GetRobloxIdForSlot(H,"\080\108\097\121\101\114\072\097\116")z.Torso=u:GetRobloxIdForSlot(H,"\080\108\097\121\101\114\084\111\114\115\111")z.LeftArm=u:GetRobloxIdForSlot(H,"\080\108\097\121\101\114\076\101\102\116\065\114\109")z.RightArm=u:GetRobloxIdForSlot(H,"\080\108\097\121\101\114\082\105\103\104\116\065\114\109")z.LeftLeg=u:GetRobloxIdForSlot(H,"\080\108\097\121\101\114\076\101\102\116\076\101\103")z.RightLeg=u:GetRobloxIdForSlot(H,"\080\108\097\121\101\114\082\105\103\104\116\076\101\103")return z end function U.SpawnCharacter(W,A)A:LoadCharacterWithHumanoidDescription(W:GetHumanoidDescription(A))local s=A.Character local V=s:WaitForChild("\072\117\109\097\110\111\105\100\082\111\111\116\080\097\114\116")if W.LastPlayerCFrames[A]then V.CFrame=W.LastPlayerCFrames[A]W.LastPlayerCFrames[A]=nil else V.CFrame=CFrame.new(H*100+math.random(-30,30),3.5,u*100+math.random(-30,30))*CFrame.Angles(0,-math.pi/2,0)end local U=s:WaitForChild("\072\117\109\097\110\111\105\100")U.Died:Connect(function()wait(z)W:SpawnCharacter(A)end);(d:GetInventoryChangedEvent(A)):Connect(function()if s.Parent then U:ApplyDescription(W:GetHumanoidDescription(A))f:UpdatePet(A)end end)f:SpawnPet(A)for H,u in pairs(s:GetDescendants())do if u:IsA("\066\097\115\101\080\097\114\116")then Z:SetPartCollisionGroup(u,"\067\104\097\114\097\099\116\101\114\115")end end s.DescendantAdded:Connect(function(H)if H:IsA("\066\097\115\101\080\097\114\116")then Z:SetPartCollisionGroup(H,"\067\104\097\114\097\099\116\101\114\115")end end)local v=s:FindFirstChild("\072\101\097\108\116\104")if v then v:Destroy()end end function U.SaveLastSpot(u,H)local z=H.Character if z then local A=z:FindFirstChild("\072\117\109\097\110\111\105\100\082\111\111\116\080\097\114\116")if A then u.LastPlayerCFrames[H]=A.CFrame end end end function U.TeleportToLastSpot(u,H)local z=H.Character if z and u.LastPlayerCFrames[H]then local A=z:FindFirstChild("\072\117\109\097\110\111\105\100\082\111\111\116\080\097\114\116")if A then A.CFrame=u.LastPlayerCFrames[H]end u.LastPlayerCFrames[H]=nil end end return U
--[[
TheNexusAvenger

Controls spawning and modifying characters.
Class is static (should not be created).
--]]

local BASE_SPAWN_GRID_X = 178
local BASE_SPAWN_GRID_Y = 13
local RESPAWN_DELAY = 5



local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PhysicsService = game:GetService("PhysicsService")

local ReplicatedStorageProject = require(ReplicatedStorage:WaitForChild("Project"):WaitForChild("ReplicatedStorage"))
local ServerScriptServiceProject = require(ReplicatedStorage:WaitForChild("Project"):WaitForChild("ServerScriptService")):GetContext(script)

local ItemData = ReplicatedStorageProject:GetResource("GameData.Item.Items")

local CharacterService = ReplicatedStorageProject:GetResource("ExternalUtil.NexusInstance.NexusInstance"):Extend()
CharacterService:SetClassName("CharacterService")
CharacterService.LastPlayerCFrames = {}
ServerScriptServiceProject:SetContextResource(CharacterService)

local InventoryService = ServerScriptServiceProject:GetResource("Service.InventoryService")
local PetService = ServerScriptServiceProject:GetResource("Service.PetService")



--Set up the characters collision group.
PhysicsService:CreateCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters","Characters",false)



--[[
Returns the Roblox id for a given slot
of a player's inventory. Returns 0 if
no items is equipped in the slot.
--]]
function CharacterService:GetRobloxIdForSlot(Player,SlotName)
    --Return the item's Roblox id.
    local Item = InventoryService:GetItem(Player,SlotName)
    if Item and Item.Name then
        return ItemData[Item.Name].RobloxId
    end
    
    --Return 0 (not found).
    return 0
end

--[[
Returns the humanoid description to use
for a player.
--]]
function CharacterService:GetHumanoidDescription(Player)
    --Create the base description.
    local Description = Instance.new("HumanoidDescription")
    Description.HeadColor = BrickColor.new("Bright yellow").Color
    Description.LeftArmColor = BrickColor.new("Bright yellow").Color
    Description.RightArmColor = BrickColor.new("Bright yellow").Color
    Description.TorsoColor = BrickColor.new("Bright green").Color
    Description.LeftLegColor = BrickColor.new("Bright blue").Color
    Description.RightLegColor = BrickColor.new("Bright blue").Color

    --Add the body parts.
    Description.HatAccessory = self:GetRobloxIdForSlot(Player,"PlayerHat")
    Description.Torso = self:GetRobloxIdForSlot(Player,"PlayerTorso")
    Description.LeftArm = self:GetRobloxIdForSlot(Player,"PlayerLeftArm")
    Description.RightArm = self:GetRobloxIdForSlot(Player,"PlayerRightArm")
    Description.LeftLeg = self:GetRobloxIdForSlot(Player,"PlayerLeftLeg")
    Description.RightLeg = self:GetRobloxIdForSlot(Player,"PlayerRightLeg")
    
    --Return the description.
    return Description
end

--[[
Spawns a player.
--]]
function CharacterService:SpawnCharacter(Player)
    --Load the character.
    Player:LoadCharacterWithHumanoidDescription(self:GetHumanoidDescription(Player))

    --Move the character.
    local Character = Player.Character
    local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
    if self.LastPlayerCFrames[Player] then
        HumanoidRootPart.CFrame = self.LastPlayerCFrames[Player]
        self.LastPlayerCFrames[Player] = nil
    else
        HumanoidRootPart.CFrame = CFrame.new((BASE_SPAWN_GRID_X * 100) + math.random(-30,30),3.5,(BASE_SPAWN_GRID_Y * 100) + math.random(-30,30)) * CFrame.Angles(0,-math.pi/2,0)
    end

    --Connect the player being killed.
    local Humanoid = Character:WaitForChild("Humanoid")
    Humanoid.Died:Connect(function()
        wait(RESPAWN_DELAY)
        self:SpawnCharacter(Player)
    end)

    --Connect the inventory changing.
    InventoryService:GetInventoryChangedEvent(Player):Connect(function()
        if Character.Parent then
            Humanoid:ApplyDescription(self:GetHumanoidDescription(Player))
            PetService:UpdatePet(Player)
        end
    end)

    --Spawn the pet.
    PetService:SpawnPet(Player)

    --Make the character uncollidable with others.
    for _,Part in pairs(Character:GetDescendants()) do
        if Part:IsA("BasePart") then
            PhysicsService:SetPartCollisionGroup(Part,"Characters")
        end
    end
    Character.DescendantAdded:Connect(function(Part)
        if Part:IsA("BasePart") then
            PhysicsService:SetPartCollisionGroup(Part,"Characters")
        end
    end)

    --Remove the default healing script.
    local HealthScript = Character:FindFirstChild("Health")
    if HealthScript then
        HealthScript:Destroy()
    end
end

--[[
Saves the last CFrame of a player.
--]]
function CharacterService:SaveLastSpot(Player)
    local Character = Player.Character
    if Character then
        local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
        if HumanoidRootPart then
            self.LastPlayerCFrames[Player] = HumanoidRootPart.CFrame
        end
    end
end

--[[
Teleports the player to last CFrame.
--]]
function CharacterService:TeleportToLastSpot(Player)
    local Character = Player.Character
    if Character and self.LastPlayerCFrames[Player] then
        local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
        if HumanoidRootPart then
            HumanoidRootPart.CFrame = self.LastPlayerCFrames[Player]
        end
        self.LastPlayerCFrames[Player] = nil
    end
end



return CharacterService