Help with pets system

Hi devs, i wanted to do a “Equip Best” button for my pet UI.

I tried some of my knowledge but didn’t work.

This is my script now:

Module script:

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

local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local PetsConfig = require(ReplicatedStorage.Config.PetsConfig)
local PetModels = ReplicatedStorage.Pets

local player = Players.LocalPlayer

local screenGui = script.Parent
local frame = screenGui.Frame
local container = frame.PetsContainer

local info = frame.Info

local stats = frame.Stats

local petInfo = info.PetInfo
local deleteInfo = info.DeleteFrame

local equippedStat = stats.Pets
local storageStat = stats.Storage

local exit = frame.ExitButton

local template = script.Template


local module = {}

module.SelectedPet = nil
module.SelectedPets = {}
module.Mode = "Default"

function module.GetRarityColor(rarity: string)
	local color

	if rarity == "Common" then
		color = Color3.fromRGB(173, 173, 173)
	elseif rarity == "Uncommon" then
		color = Color3.fromRGB(9, 176, 0)
	elseif rarity == "Rare" then
		color = Color3.fromRGB(19, 193, 164)
	elseif rarity == "Secret" then
		color = Color3.fromRGB(0, 0, 0)
	elseif rarity == "Premium" then
		color = Color3.fromRGB(170, 85, 255)
	end

	return color
end

function module.equipBest(container: ScrollingFrame)
	local list = container
	local bestPet
	local table = {}
	
	for _, pet in ipairs(list:GetChildren()) do
		if not pet:IsA("TextButton") then continue end

	end
	return bestPet
end

function module.GenerateViewportFrame(viewportFrame: ViewportFrame, petModel: Model)
	petModel:PivotTo(CFrame.new() * CFrame.Angles(0, math.rad(180), 0))
	petModel.Parent = viewportFrame

	local camera = Instance.new("Camera", viewportFrame)
	viewportFrame.CurrentCamera = camera

	if petModel.Name == "Giant_Chicken" or "Giant_Doge" or "Neon_Agony" or "Neon_Angel" then
		camera.FieldOfView = 120
		camera.CFrame = CFrame.new(Vector3.new(-0.5,0,4), petModel.PrimaryPart.Position)
	else	
		camera.FieldOfView = 10
		camera.CFrame = CFrame.new(Vector3.new(-1,1,4), petModel.PrimaryPart.Position)
	end
end

function module.UpdatePetStored()
	local stored = #player.petInventory:GetChildren()
	storageStat.Number.Text = "📦"..stored.."/"..player.petInfo.MaxStored.Value
end

function module.UpdatePetsEquipped()
	local equipped = 0
	for _, pet in ipairs(player.petInventory:GetChildren()) do
		if pet.Equipped.Value  then
			equipped += 1
		end
	end
	
	equippedStat.Number.Text = "🐶"..equipped.."/"..player.petInfo.MaxEquipped.Value
end

function module.DisplayPetInfo(pet: table)
	local petStat = PetsConfig[pet.ID][pet.Rarity]
	local petInstance = player.petInventory:FindFirstChild(pet.UUID)

	petInfo.Namee.Text = pet.ID:gsub("_", " ")
	petInfo.Rarity.Text = pet.Rarity
	petInfo.Rarity.TextColor3 = module.GetRarityColor(pet.Rarity)
	petInfo.StatsFrame.Dribbles.Text = "x"..petStat
	petInfo.StatsFrame.Coins.Text = "x"..petStat

	local previousModel = petInfo.ViewportFrame:FindFirstChildOfClass("Model")

	if previousModel then
		previousModel:Destroy()
	end

	local petModel = PetModels[pet.ID]:Clone()
	module.GenerateViewportFrame(petInfo.ViewportFrame, petModel)

	if petInstance.Equipped.Value then
		petInfo.EquipBtn.Text = "Unequip"
		petInfo.EquipBtn.BackgroundColor3 = Color3.fromRGB(255, 0, 4)
	else
		petInfo.EquipBtn.Text = "Equip"
		petInfo.EquipBtn.BackgroundColor3 = Color3.fromRGB(12, 190, 2)
	end
end

function module.GeneratePet(pet: table)
	local clone = template:Clone()
	clone.Visible = true
	clone.Parent = container
	clone.Name = pet.UUID
	clone.Stat.Value = PetsConfig[pet.ID][pet.Rarity]
	clone.Holder.PetName.Text = pet.ID:gsub("_", " ")
	clone.Holder.Equipped.Visible = pet.Equipped

	local petModel = PetModels[pet.ID]:Clone()
	module.GenerateViewportFrame(clone.Holder.ViewportFrame, petModel)

	clone.MouseButton1Click:Connect(function()
		if module.Mode == "Default" then
			module.SelectedPet = pet
			module.DisplayPetInfo(pet)
			petInfo.Visible = true
		else
			if table.find(module.SelectedPets, pet) then
				table.remove(module.SelectedPets, table.find(module.SelectedPets, pet))
				clone.Holder.Delete.Visible = false
			else
				table.insert(module.SelectedPets, pet)
				clone.Holder.Delete.Visible = true
			end
			deleteInfo.Selected.Text = "Pets selected: "..#module.SelectedPets
		end
	end)
end

function module.PetInstanceToTable(pet: Instance)
	local newpet = {}
	newpet.UUID = pet.Name
	newpet.ID = pet.ID.Value
	newpet.Rarity = pet.Rarity.Value
	newpet.Equipped = pet.Equipped.Value
	return newpet
end

return module

Local script:

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

local Handler = require(script.Parent.Handler)
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local PetsConfig = require(ReplicatedStorage.Config.PetsConfig)
local PetModels = ReplicatedStorage.Pets

local player = Players.LocalPlayer

local screenGui = script.Parent
local frame = screenGui.Frame
local container = frame.PetsContainer
local info = frame.Info
local warning = frame.Warn

local multiDelete = frame.MultiDeleteBtn
local deleteInfo = info.DeleteFrame

local confBtn = deleteInfo.ConfirmBtn

local petInfo = info.PetInfo

local equipBtn = petInfo.EquipBtn
local deleteButton = petInfo.DeleteButton

local exit = frame.ExitButton

--local template = script.Template

for _, pet in ipairs(player.petInventory:GetChildren()) do
	local petTable = Handler.PetInstanceToTable(pet)
	Handler.GeneratePet(petTable)
end

Handler.UpdatePetsEquipped()
Handler.UpdatePetStored()

equipBtn.MouseButton1Click:Connect(function()
	if not Handler.SelectedPet then return end
	local result = Remotes.PetEquip:InvokeServer(Handler.SelectedPet.UUID)
	
	if not result then return end
	
	local petTemplateInstance = container:FindFirstChild(Handler.SelectedPet.UUID)
	
	if result == "Equipped" then
		petInfo.EquipBtn.Text = "Unequip"
		petInfo.EquipBtn.BackgroundColor3 = Color3.fromRGB(255, 0, 4)
		petTemplateInstance.Holder.Equipped.Visible = true
		Handler.UpdatePetsEquipped()
	elseif result == "Unequipped" then
		petInfo.EquipBtn.Text = "Equip"
		petInfo.EquipBtn.BackgroundColor3 = Color3.fromRGB(12, 190, 2)
		petTemplateInstance.Holder.Equipped.Visible = false
		Handler.UpdatePetsEquipped()
	elseif result == "Full" then
		warning.Visible = true
		task.delay(3, function()
			warning.Visible = false
		end)
	end
end)

deleteButton.MouseButton1Click:Connect(function()
	if not Handler.SelectedPet then return end
	Remotes.PetDelete:FireServer(Handler.SelectedPet.UUID)
	
	local petTemplateInstance = container:FindFirstChild(Handler.SelectedPet.UUID)
	petTemplateInstance:Destroy()
	petInfo.Visible = false
	
	task.delay(.01, function()
		Handler.UpdatePetStored()
		Handler.UpdatePetsEquipped()
	end)
end)

multiDelete.MouseButton1Click:Connect(function()
	Handler.SelectedPet = nil
	Handler.SelectedPets = {}
	
	if Handler.Mode == "Default" then
		Handler.Mode = "Delete"
		petInfo.Visible = false
		deleteInfo.Visible = true
		deleteInfo.Selected.Text = "Pets Selected: 0"
	else
		Handler.Mode = "Default"
		petInfo.Visible = true
		deleteInfo.Visible = false
		for _, pet in ipairs(container:GetChildren()) do
			if not pet:IsA("TextButton") then continue end
			pet.Holder.Delete.Visible = false
		end
	end
end)

confBtn.MouseButton1Click:Connect(function()
	for _, pet in ipairs(Handler.SelectedPets) do
		Remotes.PetDelete:FireServer(pet.UUID)
		
		local petTemplateInstance = container:FindFirstChild(pet.UUID)
		petTemplateInstance:Destroy()
	end
	
	deleteInfo.Visible = false
	Handler.Mode = "Default"
	
	task.delay(.01, function()
		Handler.UpdatePetStored()
		Handler.UpdatePetsEquipped()
	end)
end)

exit.MouseButton1Click:Connect(function()
	screenGui.Enabled = not screenGui.Enabled
end)

Remotes.PetHatched.OnClientEvent:Connect(function(player: Player, pet: table, petInstance: Instance)
	local petTable = Handler.PetInstanceToTable(pet)
	Handler.GeneratePet(petTable)
	Handler.UpdatePetStored()
end)

frame.EquipBest.TextButton.MouseButton1Click:Connect(function()
	Handler.equipBest(container)
end)

Thanks!
image
image

1 Like

Could you expand on how it doesn’t work? Are there any errors in the logs? What happens in-game?

1 Like

I have no errors, but i wanted if someone could help me with this rest of the code because i tried all my methods.
Thanks!

1 Like

Could you expand on what happens in-game? What should I be looking for in the code? Why isn’t it working?

So, i tried using this:

function module.equipBest(container: ScrollingFrame)
	local list = container
	local bestPet
	local table = {}
	
	for _, pet in ipairs(list:GetChildren()) do
		if not pet:IsA("TextButton") then continue end
        table.insert(pet.Stat.Value, table)

        bestPet = table.find(math.max(table))
	end
	return bestPet
end

i used this too:

frame.EquipBest.TextButton.MouseButton1Click:Connect(function()
	Remotes.PetEquip:InvokeServer(Handler.equipBest(container))
end)

And this too(script that i didnt show here because i forgot):

local function PetEquip(player: Player, uuid: string)
	local pet = player.petInventory:FindFirstChild(uuid)
	if not pet then return end
	
	if pet.Equipped.Value  then
		pet.Equipped.Value = false
		PetUnfollow(player, pet)
		return "Unequipped"
	elseif CanEquipPet(player) then
		pet.Equipped.Value = true
		PetFollow(player, pet)
		return "Equipped"
	else
		return "Full"
	end
end

Error:

P.S: I want to equip all best pet, so like i have 60 pets and when i press equip best the script equips for me the best 3 pets or more.

1 Like

could you provide me a way to get the table with every single pet in the player’s storage with its strength?

What do you mean with this?

Sorry i dont understand D :

I need a table with the player’s pets and its strength
For ex

local pets = {
["petid1"] = strength,
["petid2"] = strength
}

Ohh Ok, Should be this:

local module = {
	Dog = {
		Common = 1.5,
		Uncommon = 6
	},
	Cat = {
		Common = 2
	},
	Seal = {
		Uncommon = 3.5
	},
	Doge = {
		Uncommon = 5
	},
	Chicken = {
		Rare = 8
	},
	Pig = {
		Uncommon = 7
	},
	Giant_Doge = {
		Secret = 100
	},
	Giant_Chicken = {
		Secret = 100
	},
	Neon_Agony = {
		Premium = 500
	},
	Neon_Angel = {
		Premium = 750
	}
}

return module

These are pets names and pets stats.

1 Like

I think he meant the player’s inventory of pets, not the pets from the eggs.

1 Like

I only have this(idk if this is what you mean):


image

You don’t have a pet inventory system? Do you have a table of the pets that the player owns?

1 Like

I don’t think so, i use the DataStore to save pets in the cloud, and when the player join the DataStore gives the player all the pets.

image

1 Like

So you just get the petInventory of the player, or just get the data from the cloud or smth
Then use something like table.sort() to get the highest value…

I give up my head’s exploding lol

I mean don’t give up, try to take a break to rest your head.

3 Likes

Ok, im back, my time zone was 12am so i slept.

Now i’m here, i don’t know if you are online or offline, reply whenever you want.

Thanks!

I notice you do not have a “fitness” for best pet, most games have a damage value or some simple number that could be compared to find the highest; at best you have a rarity.

If you have add a fitness you can find the single best pet with a function like this, otherwise compare rarities.

local function best_pet(list: ScrollingFrame): PetType?
    local bestPet = nil
    local bestPetValue: number? = nil

    for _, pet in ipairs(list:GetChildren()) do

        if bestPet then
            -- compare fitness values, if it's higher it's the new best pet
            if pet.Fitness.Value > bestPetValue then
                bestPet = pet
                bestPetValue = pet.Fitness.Value
            end
        else
            -- there is no best pet yet! so we set what ever we find first to it.
            bestPet = pet
            bestPetValue = pet.Fitness.Value
        end
    end
    return bestPet
end
1 Like

I put this script in the Module Script, but now it gives me this error:

RemoteFunction:

image

Local script:

1 Like

Right because you don’t have a Fitness value, I propose you could use Rarity but it would have to be by lookup since Rarity appears to be a string. I only use Fitness as general an example, again most games would use Damage.

The important question is How do you want to sort your pets? What makes a pet the best to equip?