Lets say I have this table.
Config.LootboxesRewards = {
[1] = {
{name = 'a45amg', label = 'Mercedes A45 AMG ', amount = 1, type = 'car', luck = 3},
{name = '720s', label = '720s mclaren', amount = 1, type = 'car', luck = 20},
{name = 'bac2', label = 'bac2', amount = 1, type = 'car', luck = 20},
{name = 'm6prior', label = 'BMW M6', amount = 1, type = 'car', luck = 19},
{name = 'huracan', label = 'Lamborghini Huracan', amount = 1, type = 'car', luck = 19},
{name = 'yzfr6', label = 'Yamaha R6', amount = 1, type = 'car', luck = 19},
},
}
Based on that I would like to give the the player 1 item based on luck value on that table. What is the best way to do it?
CodePudding user response:
The simplest way is to index Config.LootboxesRewards[1]
with math.random(#Config.LootboxesRewards[1])
This assumes that you just want to give your player a random item with uniform distribution. If you want to vary the chanc of getting particular items I suggest you start here:
https://en.wikipedia.org/wiki/Probability
Read:
https://www.lua.org/manual/5.4/manual.html#pdf-math.random
https://www.lua.org/manual/5.4/manual.html#pdf-math.randomseed
CodePudding user response:
One simple solution is to put the values with a higher chance (higher luck value) more often in the loot-table than the items with a lower change (lower luck value).
You can still keep your table for convenience and pre-process the table like this:
local function gcd(a, b)
while a ~= b do
if a > b then
a = a - b
else
b = b - a
end
end
return a
end
local function gcd_tbl(values, value_getter)
if #values < 1 then
return nil
end
value_getter = value_getter or function(v) return v end
local result = value_getter(values[1])
for i = 2, #values do
result = gcd(result, value_getter(values[i]))
end
return result
end
local function process_rewards(tbl)
local result = {}
for id, rewards in pairs(tbl) do
result[id] = {}
local greatest_common_divisor = gcd_tbl(rewards, function(v) return v.luck end)
for _, reward in ipairs(rewards) do
for i = 1, reward.luck / greatest_common_divisor do
table.insert(result[id], reward)
end
end
end
return result
end
Config.LootboxesRewards = process_rewards({
[1] = {
{name = 'a45amg', label = 'Mercedes A45 AMG ', amount = 1, type = 'car', luck = 3},
{name = '720s', label = '720s mclaren', amount = 1, type = 'car', luck = 20},
{name = 'bac2', label = 'bac2', amount = 1, type = 'car', luck = 20},
{name = 'm6prior', label = 'BMW M6', amount = 1, type = 'car', luck = 19},
{name = 'huracan', label = 'Lamborghini Huracan', amount = 1, type = 'car', luck = 19},
{name = 'yzfr6', label = 'Yamaha R6', amount = 1, type = 'car', luck = 19},
}
})
You can then choose a random index from the table to find the reward:
function get_random_reward(lootbox_id)
local lootbox_rewards = Config.LootboxesRewards[lootbox_id]
if not lootbox_rewards then
return nil
end
return lootbox_rewards[math.random(#lootbox_rewards)]
end
get_random_reward(1)
EDIT: If you wish to indicate the other way around (higher luck = less chance to drop), you could chance these 2 functions:
local function gcd_and_max_tbl(values, value_getter)
if #values < 1 then
return nil, nil
end
value_getter = value_getter or function(v) return v end
local value = value_getter(values[1])
local gcd_result, max_result = value, value
for i = 2, #values do
value = value_getter(values[i])
gcd_result = gcd(gcd_result, value)
max_result = math.max(max_result, value)
end
return gcd_result, max_result
end
local function process_rewards(tbl)
local result = {}
for id, rewards in pairs(tbl) do
result[id] = {}
local greatest_common_divisor, max_luck = gcd_and_max_tbl(rewards, function(v) return v.luck end)
local max_relevant_luck = max_luck / greatest_common_divisor
for _, reward in ipairs(rewards) do
for i = 1, max_relevant_luck - (reward.luck / greatest_common_divisor) 1 do
table.insert(result[id], reward)
end
end
end
return result
end