You could try including an upper bound to your percentages so that there are two numbers to compare between:
local R = Random.new()
local MAX_RANGE = 100
local MIN_RANGE = 0
local percentages = {
--Name = {lowerBound, upperBound}
Common = {50, 100},
Uncommon = {25, 50},
Rare = {10, 25},
Epic = {0, 10}
}
local getRandomItem = R:NextNumber(MIN_RANGE, MAX_RANGE)
local found
for item, bounds in pairs(percentages) do
if getRandomItem >= bounds[1] and getRandomItem < bounds[2] then
found = item
break
end
end
--whatever you wanna do with `found`
If you had a larger list of items and wanted to assign them appropriately according to a weight like you have, you could take the sum of all weights and make that the max range, and in the meantime create lower and upper bounds for all your items:
local weightedItems = {
Duck1 = 30,
Duck2 = 80,
Duck3 = 11
}
local percentages = {}
local sum = 0
MIN_RANGE = sum
for k, weight in pairs(weightedItems) do
percentages[k] = {sum, sum + weight}
sum += weight
end
MAX_RANGE = sum
I just checked that scripting helpers page, and that guy came up with a better concept than I did, so just use that. In fact, I’ll just repurpose my code to model it:
local R = Random.new()
local weightedItems = {
Duck1 = 30,
Duck2 = 80,
Duck3 = 11
}
local function getRandomItem(weightedItems)
local totalWeight = 0
for _, weight in pairs(weightedItems) do
totalWeight += weight
end
local choice = R:NextNumber(0, totalWeight)
local result
for item, weight in pairs(weightedItems) do
choice -= weight
if choice <= 0 then
return item
end
end
error("item not found")
end