NOTE: I am basing my chance system off of the solution in How do i make a chance system?, so tell me if it is outdated or something.
So I am making a chance system where there is a chance that you get Moltenite instead of Meteorite.
I made a test one on a baseplate and here is the script:
local deb = false
script.Parent.Touched:Connect(function(hit)
if not deb then
if hit.Parent:FindFirstChild("Humanoid") then
if game.Players:GetPlayerFromCharacter(hit.Parent) then
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
local leaderstats = plr.leaderstats
local chances = {
Cash = 75,
Crystals = 25
}
local random = math.random(100)
for i, v in pairs(chances) do
if random <= v then
print(i)
leaderstats[i].Value = leaderstats[i].Value + 1
else
--print(i)
end
end
script.Parent.Parent = game.ServerStorage
deb = true
wait(1)
deb = false
script.Parent.Parent = workspace
end
end
end
end)
However, there is one problem. If you get crystals, you also get cash (prints “Crystals” and “Cash”).
How am I supposed to fix this?
END NOTE: Please do not tell me my code is messy, I am not looking for people to say “Your code is messy”. I want to get my problem solved and I will make it less messy later.
Basically, you were using the same randomness value for Cash and Crystals, so if you change it after each value, you have different chances of getting them.
In the solution, i’ve seen that inside the else statement, it would substract the random variable wiith the entry weight, something like this:
else
random = random - v
end
I don’t know if that would be the issue.
Try to finish the loop when you find a random currency, something like this:
local AlreadyFound = false
for i, v in pairs(chances) do
if not AlreadyFound then
if random <= v then
print(i)
leaderstats[i].Value = leaderstats[i].Value + 1
else
random = random - v
end
end
end
With your current code, if you get the number 10, the code would search for every item inside your table, and check if the number is smaller than the weight of every item, since the number 10 is smaller than both items you have, then you would recieve two currencies, in the solution of my thread, it would be a function, when it finds an item, it would return the value, since it returns, the code would stop, and your code wouldn’t stop even if you find a result, the way to fix that would be converting the part of the code i quoted in a function, or just check if a result was already found with a boolean variable, as i mentioned before, i hope this helps you
You iterate through all of the chances and in some cases random is bigger than 75 and 25, causing you to get both.
Here is some code I wrote to show you how weighted chances would work with your system:
local Debounce = false
local Chances = {
Cash = 75,
Crystals = 25
}
local WeightedChances = {}
for Type, Value in next, Chances do -- Iterate through all of the things in the table
for Loop = 1, Value do -- Add x elements to the WeightedChances table
table.insert(WeightedChances, tostring(Type))
end
end
function PickChance()
return WeightedChances[math.random(1, #WeightedChances)] -- Pick a random chance. Think of this like a raffle there are 75 "Cash" tickets and 25 "Crystals" tickets. Picking one randomly should give Cash and Crystals a 75 and 25 percent chance, respectively.
end
function OnTouched(Hit)
if not Debounce then -- Typical debounce stuff
local Chance = PickChance() -- Store the chance we got in this
local Player = game:GetService("Players"):GetPlayerFromCharacter(Hit.Parent) -- Get the player that touched the part
if Player then
local Parent = script.Parent.Parent
Debounce = true
Player.leaderstats[Chance].Value = Player.leaderstats[Chance].Value + 1
script.Parent.Parent = game:GetService("ServerStorage")
coroutine.resume(coroutine.create(function()
wait(1)
script.Parent.Parent = Parent
Debounce = false
end))
end
end
end
script.Parent.Touched:Connect(OnTouched)
local deb = false
local Minimum = 25
local Maximum = 700
script.Parent.Touched:Connect(function(hit)
if not deb then
if hit.Parent:FindFirstChild("Humanoid") then
if game.Players:GetPlayerFromCharacter(hit.Parent) then
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
local leaderstats = plr.leaderstats
local chances = {
Cash = NumberRange.new(250,700),
Crystals = NumberRange.new(25,70)
}
local random = math.random(Minimum,Maximum)
for i, v in pairs(chances) do
if random >= v.Min and random <= v.Max then
leaderstats[i].Value = leaderstats[i].Value + 1
print(i)
end
end
script.Parent.Parent = game.ServerStorage
deb = true
wait(1)
deb = false
script.Parent.Parent = workspace
end
end
end
end)
What’s now weird is that sometimes you don’t even get anything. Neither cash or crystals…