MineClone2/mods/CORE/mcl_loottables/api.lua

120 lines
3.2 KiB
Lua
Raw Normal View History

mcl_loottables.register_entry = mcl_util.registration_function(mcl_loottables.entries)
mcl_loottables.register_table = mcl_util.registration_function(mcl_loottables.tables, function(name, def)
local function set_parents(parent)
for _, child in ipairs(parent.children or parent.entries or parent.pools or {}) do
child.parent = parent
set_parents(child)
end
end
set_parents(def)
end)
function mcl_loottables.get_table(def)
2021-03-11 10:05:46 +01:00
return mcl_util.switch_type(def, {
["nil"] = function()
return {}
end,
["string"] = function()
return mcl_loottables.tables[def], "table"
end,
["table"] = function()
return def
end,
}, "loot table")
end
function mcl_loottables.get_entry_type(entry)
2021-03-11 10:05:46 +01:00
return mcl_loottables.entries[entry.type]
end
function mcl_loottables.get_candidates(entries, data, func)
local candidates = {}
for _, entry in ipairs(entries) do
local success = mcl_predicates.do_predicates(entry.conditions, data)
if success then
local children = entry.children
if children then
table.insert_all(candidates, mcl_loottables.get_candidates(children, data, mcl_loottables.get_entry_type(entry).preprocess))
else
table.insert(candidates, entry)
end
end
if func and func(success, data) then
break
end
end
return candidates
end
function mcl_loottables.do_item_modifiers(itemstack, node, data)
if node then
mcl_functions.do_item_modifiers(itemstack, node.functions, data)
mcl_loottables.do_item_modifiers(itemstack, node.parent, data)
end
end
function mcl_loottables.do_pools(pools, functions, data)
local luck = data.luck or 0
local stacks = {}
for _, pool in ipairs(pools or {}) do
if mcl_conditions.do_conditions(pool.conditions, data) do
local rolls = mcl_loottables.get_number(pool.rolls, data) + mcl_loottables.get_number(pool.bonus_rolls, data) * luck
for i = 1, rolls do
local candidates = mcl_loottables.get_candidates(pool.entries, data)
if #candidates > 0 then
local total_weight = 0
local weights = {}
for _, candidate in ipairs(candidates)
total_weight = total_weight + math.floor((candidate.weight or 1) + (candidate.quality or 0) * luck)
table.insert(weights, total_weight)
end
local selected
local rnd = mcl_util.rand(data.pr, 0, weight - 1)
for i, w in ipairs(weights) do
if rnd < w then
selected = candidates[i]
break
end
end
local func = mcl_loottables.get_entry_type(entry).process
local stacks = func(selected, data)
for _, stack in ipairs(stacks) do
2021-03-11 10:05:46 +01:00
mcl_item_modifiers.do_item_modifiers(stack, selected, data)
end
table.insert_all(stacks, stack)
end
end
end
end
return stacks
end
function mcl_loottables.get_loot(def, data)
def = mcl_loottables.get_table(def)
return mcl_loottables.do_pools(def.pools)
end
function mcl_loottables.drop_loot(def, data)
2021-03-11 10:05:46 +01:00
local loot = mcl_loottables.get_loot(def, data)
local old_loot = table.copy(loot)
for _, stack in ipairs(old_loot) do
local max_stack = stack:get_stack_max()
while max_stack < stack:get_count() do
table.insert(loot, stack:take_items(max_stack))
end
end
return loot
end
function mcl_loottables.fill_chest(def, data)
2021-03-11 10:05:46 +01:00
local loot = mcl_loottables.get_loot(def, data)
end