Menu
CoddyTech

Rolagens de Raridade

Lição 10 de 18 do curso Jogo Roblox: Simulador de Pets da Coddy.

Um ovo não deve sempre dar um Cat. Settings.Pets lista todos os pets com uma Chance de 100 (Cat 45, Dog 30, Bunny 15, Fox 8, Dragon 2), uma raridade e um poder.

Uma seleção ponderada: escolha um número de 0 a 100 e, em seguida, percorra a lista subtraindo a chance de cada pet. O pet que fizer o valor chegar a 0 ou menos vence, então um pet com chance 45 vence, em média, 45 sorteios em 100:

local roll = math.random() * 100
for _, info in Settings.Pets do
	roll -= info.Chance
	if roll <= 0 then
		return info.Name
	end
end

O pet que sai do ovo também carrega Rarity e Power como atributos. Uma tabela dos pets por nome (petInfo["Fox"]) permite encontrá-los rapidamente.

challenge icon

Desafio

Médio
  1. Crie petInfo, com Settings.Pets indexado por Name.
  2. Em givePet, defina os atributos Rarity e Power do pet usando petInfo.
  3. Escreva rollPet(), a rolagem ponderada, e faça a eclosão com rollPet() em vez de um Cat (o print mostra o nome do que eclodiu).

Pressione Play e faça a eclosão de alguns. Depois, Check: as verificações alteram as chances para garantir que sua rolagem as siga.

Experimente você mesmo

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local remotes = game.ReplicatedStorage.Remotes
local piles = workspace.Piles
local pileSpot = {} -- cada pilha -> o local onde ela está
local lastHit = {} -- cada jogador -> quando deu o último golpe

print("A Meadow pile gives " .. Settings.PileValue .. " coins")

-- Um pet: um StringValue na pasta Pets do jogador que armazena seu nome
local function givePet(player, name)
	local pet = Instance.new("StringValue")
	pet.Name = "Pet"
	pet.Value = name
	pet.Parent = player.Pets
	return pet
end

-- Todo jogador recebe Coins na tabela de classificação
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local coins = Instance.new("IntValue")
	coins.Name = "Coins"
	coins.Parent = leaderstats

	-- os pets que eles possuem
	local pets = Instance.new("Folder")
	pets.Name = "Pets"
	pets.Parent = player
end)

-- Uma pilha de moedas em um local: uma cópia de ServerStorage.CoinPile com sua vida
-- e seu valor como atributos
local function spawnPile(spot)
	local pile = ServerStorage.CoinPile:Clone()
	pile.Position = spot.Position
	pile:SetAttribute("MaxHealth", Settings.PileHealth)
	pile:SetAttribute("Health", Settings.PileHealth)
	pile:SetAttribute("Value", Settings.PileValue)
	pile.HealthGui.Label.Text = pile:GetAttribute("Health") .. "/" .. pile:GetAttribute("MaxHealth")
	pileSpot[pile] = spot
	pile.Parent = piles
	return pile
end

-- Um golpe reduz em 1 a vida de uma pilha;
-- ao chegar a 0, a pilha se quebra e concede seu valor
local function hitPile(player, pile)
	local health = pile:GetAttribute("Health") - 1
	if health > 0 then
		pile:SetAttribute("Health", health)
		pile.HealthGui.Label.Text = health .. "/" .. pile:GetAttribute("MaxHealth")
		return
	end
	player.leaderstats.Coins.Value += pile:GetAttribute("Value")
	local spot = pileSpot[pile]
	pileSpot[pile] = nil
	pile:Destroy()
	-- uma nova pilha no mesmo local, alguns segundos depois
	task.delay(Settings.RespawnTime, spawnPile, spot)
end

-- Uma pilha em cada local de Meadow
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
	spawnPile(spot)
end

-- O cliente solicita um golpe em uma pilha. Nunca confie no cliente: qualquer pessoa pode disparar
-- este remote com qualquer coisa, de qualquer lugar, tão rápido quanto quiserem.
remotes.Hit.OnServerEvent:Connect(function(player, pile)
	-- uma pilha de verdade
	if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
		return
	end
	-- ao alcance
	local character = player.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if not root or (root.Position - pile.Position).Magnitude > Settings.Reach then
		return
	end
	-- não rápido demais
	local now = time()
	if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
		return
	end
	lastHit[player] = now
	hitPile(player, pile)
end)

-- Chocagem: o prompt do ovo, pago com moedas
workspace.Egg.ProximityPrompt.Triggered:Connect(function(player)
	local coins = player.leaderstats.Coins
	if coins.Value < Settings.EggPrice then
		return
	end
	coins.Value -= Settings.EggPrice
	local name = "Cat"
	givePet(player, name)
	print(player.Name .. " hatched a " .. name)
end)
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Jogo Roblox: Simulador de Pets