From 149d8fc8d6d92e8e0d6908125ad8d3179695b1ea Mon Sep 17 00:00:00 2001 From: Treer Date: Sat, 28 Aug 2021 04:23:20 +1000 Subject: [PATCH] Add group-based tool filtering for node drops (#10141) Supports both AND and OR requirements, e.g. * "a tool that's in any of these groups" * "a tool that's in all of these groups" --- builtin/game/item.lua | 35 ++++++++++++++++++++++++++++++++++- doc/lua_api.txt | 14 ++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 99465e099..c495a67bd 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -175,6 +175,18 @@ function core.strip_param2_color(param2, paramtype2) return param2 end +local function has_all_groups(tbl, required_groups) + if type(required_groups) == "string" then + return (tbl[required_groups] or 0) ~= 0 + end + for _, group in ipairs(required_groups) do + if (tbl[group] or 0) == 0 then + return false + end + end + return true +end + function core.get_node_drops(node, toolname) -- Compatibility, if node is string local nodename = node @@ -214,7 +226,7 @@ function core.get_node_drops(node, toolname) if item.rarity ~= nil then good_rarity = item.rarity < 1 or math.random(item.rarity) == 1 end - if item.tools ~= nil then + if item.tools ~= nil or item.tool_groups ~= nil then good_tool = false end if item.tools ~= nil and toolname then @@ -229,6 +241,27 @@ function core.get_node_drops(node, toolname) end end end + if item.tool_groups ~= nil and toolname then + local tooldef = core.registered_items[toolname] + if tooldef ~= nil and type(tooldef.groups) == "table" then + if type(item.tool_groups) == "string" then + -- tool_groups can be a string which specifies the required group + good_tool = core.get_item_group(toolname, item.tool_groups) ~= 0 + else + -- tool_groups can be a list of sufficient requirements. + -- i.e. if any item in the list can be satisfied then the tool is good + assert(type(item.tool_groups) == "table") + for _, required_groups in ipairs(item.tool_groups) do + -- required_groups can be either a string (a single group), + -- or an array of strings where all must be in tooldef.groups + good_tool = has_all_groups(tooldef.groups, required_groups) + if good_tool then + break + end + end + end + end + end if good_rarity and good_tool then got_count = got_count + 1 for _, add_item in ipairs(item.items) do diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 327f64b21..e99c1d1e6 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -7798,14 +7798,24 @@ Used by `minetest.register_node`. inherit_color = true, }, { - -- Only drop if using a item whose name contains + -- Only drop if using an item whose name contains -- "default:shovel_" (this item filtering by string matching - -- is deprecated). + -- is deprecated, use tool_groups instead). tools = {"~default:shovel_"}, rarity = 2, -- The item list dropped. items = {"default:sand", "default:desert_sand"}, }, + { + -- Only drop if using an item in the "magicwand" group, or + -- an item that is in both the "pickaxe" and the "lucky" + -- groups. + tool_groups = { + "magicwand", + {"pickaxe", "lucky"} + }, + items = {"default:coal_lump"}, + }, }, },