Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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"
  • Loading branch information
Treer committed Aug 27, 2021
1 parent d36dca3 commit 149d8fc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
35 changes: 34 additions & 1 deletion builtin/game/item.lua
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
14 changes: 12 additions & 2 deletions doc/lua_api.txt
Expand Up @@ -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"},
},
},
},

Expand Down

0 comments on commit 149d8fc

Please sign in to comment.