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"
This commit is contained in:
Treer 2021-08-28 04:23:20 +10:00 committed by GitHub
parent d36dca3aba
commit 149d8fc8d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 3 deletions

@ -175,6 +175,18 @@ function core.strip_param2_color(param2, paramtype2)
return param2 return param2
end 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) function core.get_node_drops(node, toolname)
-- Compatibility, if node is string -- Compatibility, if node is string
local nodename = node local nodename = node
@ -214,7 +226,7 @@ function core.get_node_drops(node, toolname)
if item.rarity ~= nil then if item.rarity ~= nil then
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1 good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
end end
if item.tools ~= nil then if item.tools ~= nil or item.tool_groups ~= nil then
good_tool = false good_tool = false
end end
if item.tools ~= nil and toolname then if item.tools ~= nil and toolname then
@ -229,6 +241,27 @@ function core.get_node_drops(node, toolname)
end end
end 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 if good_rarity and good_tool then
got_count = got_count + 1 got_count = got_count + 1
for _, add_item in ipairs(item.items) do for _, add_item in ipairs(item.items) do

@ -7798,14 +7798,24 @@ Used by `minetest.register_node`.
inherit_color = true, 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 -- "default:shovel_" (this item filtering by string matching
-- is deprecated). -- is deprecated, use tool_groups instead).
tools = {"~default:shovel_"}, tools = {"~default:shovel_"},
rarity = 2, rarity = 2,
-- The item list dropped. -- The item list dropped.
items = {"default:sand", "default:desert_sand"}, 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"},
},
}, },
}, },