Made loot table parsing more lenient and added more loot tables

This commit is contained in:
WillConker 2024-07-11 12:11:12 +01:00
parent cf21f43f8c
commit 853880d96d
13 changed files with 750 additions and 8 deletions

View File

@ -0,0 +1,145 @@
{
"type": "chest",
"functions": [],
"pools": [
{
"rolls": {"min": 2, "max": 4},
"entries": [
{
"type": "item",
"name": "mcl_mobitems:bone",
"weight": 25,
"functions": [{
"function": "set_count",
"count": {"min": 4, "max": 6}
}]
}, {
"type": "item",
"name": "mcl_mobitems:rotten_flesh",
"weight": 25,
"functions": [{
"function": "set_count",
"count": {"min": 3, "max": 7}
}]
}, {
"type": "item",
"name": "mcl_mobitems:spider_eye",
"weight": 25,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_books:book",
"functions": [{"function": "enchant_randomly"}],
"weight": 20,
}, {
"type": "item",
"name": "mcl_mobitems:saddle",
"weight": 20,
}, {
"type": "item",
"name": "mcl_core:apple_gold",
"weight": 20,
}, {
"type": "item",
"name": "mcl_core:gold_ingot",
"weight": 15,
"functions": [{
"function": "set_count",
"count": {"min": 2, "max": 7}
}]
}, {
"type": "item",
"name": "mcl_core:iron_ingot",
"weight": 15,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_core:emerald",
"weight": 15,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "empty",
"weight": 15
}, {
"type": "item",
"name": "mcl_mobitems:iron_horse_armor",
"weight": 15,
}, {
"type": "item",
"name": "mcl_mobitems:gold_horse_armor",
"weight": 10,
}, {
"type": "item",
"name": "mcl_mobitems:diamond_horse_armor",
"weight": 5,
}, {
"type": "item",
"name": "mcl_core:diamond",
"weight": 5,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_core:apple_gold_enchanted",
"weight": 2,
}
]
}, {
"rolls": 4,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 8}
}],
"entries": [
{
"type": "item",
"name": "mcl_mobitems:bone",
"weight": 10
}, {
"type": "item",
"name": "mcl_mobitems:rotten_flesh",
"weight": 10
}, {
"type": "item",
"name": "mcl_mobitems:gunpowder",
"weight": 10
}, {
"type": "item",
"name": "mcl_core:sand",
"weight": 10
}, {
"type": "item",
"name": "mcl_mobitems:string",
"weight": 10
},
]
}, {
"rolls": 1,
"entries": [
{
"type": "item",
"name": "mcl_armor:dune",
"weight": 1,
"functions": [{
"function": "set_count",
"count": 2,
}]
}, {
"type": "empty",
"weight": 6
}
]
}
]
}

View File

@ -0,0 +1,103 @@
{
"type": "chest",
"functions": [],
"pools": [{
"rolls": {"min": 2, "max": 6},
"entries": [
{
"type": "item",
"name": "mcl_mobitems:bone",
"weight": 20,
"functions": [{
"function": "set_count",
"count": {"min": 4, "max": 6}
}]
}, {
"type": "item",
"name": "mcl_mobitems:rotten_flesh",
"weight": 16,
"functions": [{
"function": "set_count",
"count": {"min": 3, "max": 7}
}]
}, {
"type": "item",
"name": "mcl_core:gold_ingot",
"weight": 15,
"functions": [{
"function": "set_count",
"count": {"min": 2, "max": 7}
}]
}, {
"type": "item",
"name": "mcl_bamboo:bamboo",
"weight": 15,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_core:iron_ingot",
"weight": 15,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_core:diamond",
"weight": 3,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_mobitems:saddle",
"weight": 3
}, {
"type": "item",
"name": "mcl_core:emerald",
"weight": 2,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_books:book",
"weight": 1,
"functions": [{"function": "enchant_randomly"}]
}, {
"type": "item",
"name": "mcl_mobitems:iron_horse_armor",
"weight": 1
}, {
"type": "item",
"name": "mcl_mobitems:gold_horse_armor",
"weight": 1
}, {
"type": "item",
"name": "mcl_mobitems:diamond_horse_armor",
"weight": 1
}, {
"type": "item",
"name": "mcl_core:apple_gold_enchanted",
"weight": 2
}
]
}, {
"rolls": 1,
"entries": [
{
"type": "item",
"name": "mcl_armor:wild",
"weight": 1
}, {
"type": "empty",
"weight": 2
}
]
}]
}

View File

@ -0,0 +1,186 @@
{
"type": "chest",
"functions": [],
"pools": [{
"rolls": {"min": 4, "max": 8},
"functions": [],
"conditions": [],
"entries": [
{
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 9, "max": 18}
}],
"name": "mcl_core:iron_nugget",
"weight": 40
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 4}
}],
"name": "mcl_core:flint",
"weight": 40
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 2}
}],
"name": "mcl_core:obsidian",
"weight": 40
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}],
"name": "mcl_fire:fire_charge",
"weight": 40
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}],
"name": "mcl_fire:flint_and_steel",
"weight": 40
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 4, "max": 24}
}],
"name": "mcl_core:gold_nugget",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [],
"name": "mcl_core:apple_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_tools:axe_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_farming:hoe_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_tools:pick_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_tools:shovel_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_tools:sword_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_armor:helmet_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_armor:chestplate_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_armor:leggings_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{"function": "enchant_randomly"}],
"name": "mcl_armor:boots_gold",
"weight": 15
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 4, "max": 12}
}],
"name": "mcl_potions:speckled_melon",
"weight": 5
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 4, "max": 12}
}],
"name": "mcl_farming:carrot_item_gold",
"weight": 5
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 2, "max": 8}
}],
"name": "mcl_core:gold_ingot",
"weight": 5
}, {
"type": "item",
"conditions": [],
"functions": [],
"name": "mcl_clock:clock",
"weight": 5
}, {
"type": "item",
"conditions": [],
"functions": [],
"name": "mcl_mobitems:gold_horse_armor",
"weight": 1
}, {
"type": "item",
"conditions": [],
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 2}
}],
"name": "mcl_core:goldblock",
"weight": 1
}, {
"type": "item",
"conditions": [],
"functions": [],
"name": "mcl_bells:bell",
"weight": 1
}, {
"type": "item",
"conditions": [],
"functions": [],
"name": "mcl_core:apple_gold_enchanted",
"weight": 1
}
]
}]
}

View File

@ -0,0 +1,265 @@
{
"type": "chest",
"pools": [
{
"rolls": {"min": 3, "max": 10},
"entries": [
{
"type": "item",
"name": "mcl_sus_stew:stew",
"weight": 10,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}]
}, {
"type": "item",
"name": "mcl_core:paper",
"weight": 8,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 12}
}]
}, {
"type": "item",
"name": "mcl_farming:wheat_item",
"weight": 7,
"functions": [{
"function": "set_count",
"count": {"min": 8, "max": 21}
}]
}, {
"type": "item",
"name": "mcl_farming:carrot_item",
"weight": 7,
"functions": [{
"function": "set_count",
"count": {"min": 4, "max": 8}
}]
}, {
"type": "item",
"name": "mcl_farming:potato_item_poison",
"weight": 7,
"functions": [{
"function": "set_count",
"count": {"min": 2, "max": 6}
}]
}, {
"type": "item",
"name": "mcl_farming:potato_item",
"weight": 7,
"functions": [{
"function": "set_count",
"count": {"min": 2, "max": 6}
}]
}, {
"type": "item",
"name": "mcl_core:coal_lump",
"weight": 6,
"functions": [{
"function": "set_count",
"count": {"min": 2, "max": 8}
}]
}, {
"type": "item",
"name": "mcl_mobitems:rotten_flesh",
"weight": 5,
"functions": [{
"function": "set_count",
"count": {"min": 5, "max": 24}
}]
}, {
"type": "item",
"name": "mcl_farming:potato_item",
"weight": 3,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_armor:helmet_leather",
"weight": 3,
"functions": [{"function": "enchant_randomly"}]
}, {
"type": "item",
"name": "mcl_armor:chestplate_leather",
"weight": 3,
"functions": [{"function": "enchant_randomly"}]
}, {
"type": "item",
"name": "mcl_armor:leggings_leather",
"weight": 3,
"functions": [{"function": "enchant_randomly"}]
}, {
"type": "item",
"name": "mcl_armor:boots_leather",
"weight": 3,
"functions": [{"function": "enchant_randomly"}]
}, {
"type": "item",
"name": "mcl_bamboo:bamboo",
"weight": 2,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_farming:pumpkin",
"weight": 2,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 3}
}]
}, {
"type": "item",
"name": "mcl_tnt:tnt",
"weight": 1,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 2}
}]
}
]
}, {
"rolls": {"min": 2, "max": 6},
"entries": [
{
"type": "item",
"name": "mcl_core:iron_ingot",
"weight": 90,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_core:iron_nugget",
"weight": 50,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 10}
}]
}, {
"type": "item",
"name": "mcl_core:emerald",
"weight": 40,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_core:lapis",
"weight": 20,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 10}
}]
}, {
"type": "item",
"name": "mcl_core:gold_ingot",
"weight": 10,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_core:gold_nugget",
"weight": 10,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 10}
}]
}, {
"type": "item",
"name": "mcl_experience:bottle",
"weight": 5,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}]
}, {
"type": "item",
"name": "mcl_core:diamond",
"weight": 5,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}]
}
]
}, {
"rolls": {"min": 3, "max": 3},
"entries": [
{
"type": "item",
"name": "mcl_core:paper",
"weight": 20,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 10}
}]
}, {
"type": "item",
"name": "mcl_mobitems:feather",
"weight": 10,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_books:book",
"weight": 5,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 5}
}]
}, {
"type": "item",
"name": "mcl_clock:clock",
"weight": 1,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}]
}, {
"type": "item",
"name": "mcl_compass:compass",
"weight": 1,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}]
}, {
"type": "item",
"name": "mcl_maps:empty_map",
"weight": 1,
"functions": [{
"function": "set_count",
"count": {"min": 1, "max": 1}
}]
}
]
}, {
"rolls": 1,
"entries": [
{
"type": "item",
"name": "mcl_armor:coast",
"functions": [{
"function": "set_count",
"count": 2
}],
"weight": 1
}, {
"type": "empty",
"weight": 5
}
]
}
]
}

View File

@ -0,0 +1,20 @@
{
"type": "chest",
"functions": [],
"pools": [
{
"rolls": 1,
"conditions": [],
"functions": [],
"entries": [
{
"type": "item",
"name": "xpanes:pane_silver_flat",
"conditions": [],
"functions": [],
"weight": 1
}
]
}
]
}

View File

@ -242,12 +242,20 @@
"functions": [], "functions": [],
"weight": 2, "weight": 2,
"name": "mcl_core:apple_gold_enchanted" "name": "mcl_core:apple_gold_enchanted"
}, { }
]
}, {
"rolls": 1,
"entries": [
{
"type": "item", "type": "item",
"conditions": [], "conditions": [],
"functions": [], "functions": [],
"weight": 1, "weight": 1,
"name": "mcl_armor:vex" "name": "mcl_armor:vex"
}, {
"type": "empty",
"weight": 1
} }
] ]
} }

View File

@ -0,0 +1,4 @@
TODO: Better loot in hidden jungle temple chest
TODO: Different loot in differentchests (e.g. shipwreck)
Shipwreck: --{ itemstring = "TODO:moss_block", weight = 7, amount_min = 1, amount_max = 4 },
Shipwreck: --{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 },

View File

@ -395,7 +395,6 @@ function mcl_util.drop_items_from_meta_container(listname)
end end
inv = meta:get_inventory() inv = meta:get_inventory()
minetest.debug(inv:is_empty(listname))
-- Generate loot if not already done so -- Generate loot if not already done so
-- FIXME: If a player digs container, they are not recognised in loot context -- FIXME: If a player digs container, they are not recognised in loot context

View File

@ -79,15 +79,15 @@ local function load_single_resource(registry_path, subpath, namespace_table, fil
error("Invalid filename in datapack at " .. absolute_path) error("Invalid filename in datapack at " .. absolute_path)
end end
local raw_data = read_file_string(absolute_path) local raw_data = read_file_string(absolute_path)
local loaded_data, err local loaded_data
minetest.debug("Loading resource at " .. subpath .. " in " .. registry_path) minetest.debug("Loading resource at " .. subpath .. " in " .. registry_path)
if file_suffix == "json" then if file_suffix == "json" then
loaded_data, err = minetest.parse_json(raw_data) loaded_data= minetest.parse_json(raw_data)
if not loaded_data then if not loaded_data then
-- Not valid json -- Not valid json
error("Error while reading json file " .. filepath .. ": " .. err) error("Error while reading json file at " .. absolute_path)
end end
else else
error("Can't read file with format " .. file_suffix .. " at " .. absolute_path) error("Can't read file with format " .. file_suffix .. " at " .. absolute_path)

View File

@ -34,8 +34,11 @@ local function unpack_entry(entry_provider_table, loot_context)
if not vl_loot.predicate.check_predicates(entry_provider_table.conditions, loot_context) then return {} end if not vl_loot.predicate.check_predicates(entry_provider_table.conditions, loot_context) then return {} end
-- TODO: Support other types -- TODO: Support other types
if entry_provider_table.type == "item" then local entry_type = entry_provider_table.type
if entry_type == "item" or entry_type == "empty" then
return {entry_provider_table} return {entry_provider_table}
else
error("Invalid loot entry type: " .. tostring(entry_type))
end end
end end
@ -56,6 +59,10 @@ local function get_entry_loot(entry_table, loot_context)
if entry_table.type == "item" then if entry_table.type == "item" then
local itemstack = ItemStack(entry_table.name) local itemstack = ItemStack(entry_table.name)
table.insert(loot_stacks, itemstack) table.insert(loot_stacks, itemstack)
elseif entry_table.type == "empty" then
-- Add nothing to loot
else
error("Invalid loot entry type: " .. tostring(entry_table.type))
end end
-- Apply modifier -- Apply modifier
@ -130,12 +137,16 @@ local function get_pool_loot(pool_table, loot_context)
end end
local function get_loot(loot_table, loot_context) local function get_loot(loot_table, loot_context)
local start_time = minetest.get_us_time()
-- DEBUG ONLY ^^ REMOVE
local loot_stacks = {} local loot_stacks = {}
for _, pool_table in ipairs(loot_table.pools) do for _, pool_table in ipairs(loot_table.pools) do
local pool_loot_stacks = get_pool_loot(pool_table, loot_context, loot_stacks) local pool_loot_stacks = get_pool_loot(pool_table, loot_context, loot_stacks)
append_table(loot_stacks, pool_loot_stacks) append_table(loot_stacks, pool_loot_stacks)
end end
modify_stacks(loot_table.functions, loot_stacks, loot_context) modify_stacks(loot_table.functions, loot_stacks, loot_context)
minetest.debug("Generated loot in " .. tostring((minetest.get_us_time() - start_time)/1000) .. " milliseconds")
-- DEBUG ONLY ^^ REMOVE
return loot_stacks return loot_stacks
end end

View File

@ -70,13 +70,12 @@ end
local function generate_container_loot_if_exists(pos, opener, inventory, listname) local function generate_container_loot_if_exists(pos, opener, inventory, listname)
local container_meta = minetest.get_meta(pos) local container_meta = minetest.get_meta(pos)
local loot_table_name = container_meta:get_string("vl_loot:loot_table") local loot_table_name = container_meta:get_string("vl_loot:loot_table")
minetest.debug("Using loot table: " .. loot_table_name)
-- Do nothing if this container is not a loot container/has already been looted -- Do nothing if this container is not a loot container/has already been looted
if loot_table_name == "" then return end if loot_table_name == "" then return end
-- REMOVE ^^
-- Remove loot table metadata from this container -- Remove loot table metadata from this container
container_meta:set_string("vl_loot:loot_table", "") container_meta:set_string("vl_loot:loot_table", "")
-- Generate loot to fill this container with -- Generate loot to fill this container with
minetest.debug("Using loot table: " .. loot_table_name)
local loot_table = vl_datapacks.get_resource("loot_table", loot_table_name) local loot_table = vl_datapacks.get_resource("loot_table", loot_table_name)
-- If invalid loot table, don't populate -- If invalid loot table, don't populate
if not loot_table then if not loot_table then

View File

@ -75,6 +75,7 @@ end
-- Modify an itemstack based on an item modifier -- Modify an itemstack based on an item modifier
-- Returns the resulting itemstack -- Returns the resulting itemstack
local function apply_item_modifier(modifier_table, itemstack, loot_context) local function apply_item_modifier(modifier_table, itemstack, loot_context)
if modifier_table == nil then return itemstack end
for _, function_table in ipairs(modifier_table) do for _, function_table in ipairs(modifier_table) do
itemstack = apply_item_function(function_table, itemstack, loot_context) itemstack = apply_item_function(function_table, itemstack, loot_context)
end end

View File

@ -7,6 +7,7 @@ local function check_predicate(predicate_table, loot_context)
end end
local function check_predicates(predicate_tables, loot_context) local function check_predicates(predicate_tables, loot_context)
if predicate_tables == nil then return true end
for _, predicate_table in ipairs(predicate_tables) do for _, predicate_table in ipairs(predicate_tables) do
if not vl_loot.predicate.check_predicate(predicate_table, loot_context) then if not vl_loot.predicate.check_predicate(predicate_table, loot_context) then
return false return false