Make changes to the mcl_autogroup API

Group levels are now specified as a list of names when registering a
digging group.  Digging groups which do not have specified levels will
support tools having two levels, 0 and 1 where 0 means the tool can dig
but not harvest the node and 1 means it can also harvest the node.  If
more levels are required one has to specifiy them when registering the
digging group.
This commit is contained in:
Elias Åström 2021-03-15 21:55:59 +01:00
parent 922bdbc601
commit e77473e800
5 changed files with 94 additions and 86 deletions

View file

@ -20,7 +20,9 @@ In MineClone 2, all diggable node have the hardness set in the custom field
"_mcl_hardness" (0 by default). Digging groups are registered using the "_mcl_hardness" (0 by default). Digging groups are registered using the
following code: following code:
mcl_autogroup.register_diggroup("pickaxey", { levels = 5 }) mcl_autogroup.register_diggroup("pickaxey", {
levels = { "wood", "gold", "stone", "iron", "diamond" }
})
mcl_autogroup.register_diggroup("shovely") mcl_autogroup.register_diggroup("shovely")
mcl_autogroup.register_diggroup("shovely") mcl_autogroup.register_diggroup("shovely")
@ -34,8 +36,8 @@ Nodes indicate that they belong to a particular digging group by being member of
the digging group in their node definition. "mcl_core:dirt" for example has the digging group in their node definition. "mcl_core:dirt" for example has
shovely=1 in its groups. If the digging group has multiple levels the value of shovely=1 in its groups. If the digging group has multiple levels the value of
the group indicates which digging level the node requires. the group indicates which digging level the node requires.
"mcl_core:stone_with_gold" for example has pickaxey=3 because it requires a "mcl_core:stone_with_gold" for example has pickaxey=4 because it requires a
pickaxe of level 3 to be mined. pickaxe of level 4 ("stone") to be mined.
For tools to be able to dig nodes of the digging groups they need to use the For tools to be able to dig nodes of the digging groups they need to use the
have the custom field "_mcl_autogroup_groupcaps" function to get the groupcaps. have the custom field "_mcl_autogroup_groupcaps" function to get the groupcaps.
@ -126,7 +128,7 @@ local function get_digtimes(group, can_harvest, tool_multiplier, efficiency)
efficiency = efficiency or 0 efficiency = efficiency or 0
tool_multiplier = tool_multiplier or 1 tool_multiplier = tool_multiplier or 1
speed_multiplier = tool_multiplier speed_multiplier = tool_multiplier
if efficiency > 0 then if efficiency then
speed_multiplier = speed_multiplier + efficiency * efficiency + 1 speed_multiplier = speed_multiplier + efficiency * efficiency + 1
end end
@ -160,46 +162,59 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
} }
end end
local function add_groupcaps(groupcaps, groupcaps_def) local function add_groupcaps(groupcaps, groupcaps_def, efficiency)
for g, capsdef in pairs(groupcaps_def) do for g, capsdef in pairs(groupcaps_def) do
local mult = capsdef.tool_multiplier or 1 local mult = capsdef.tool_multiplier or 1
local eff = capsdef.efficiency or 0
local uses = capsdef.uses local uses = capsdef.uses
local def = mcl_autogroup.registered_diggroups[g] local def = mcl_autogroup.registered_diggroups[g]
local level = capsdef.level or 1 local max_level = def.levels and #def.levels or 1
local max_level = def.levels or 0 local level = math.min(capsdef.level or max_level, max_level)
if max_level > 0 then if def.levels then
level = math.min(level, max_level) groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses)
groupcaps[g .. "_0_dig"] = get_groupcap(g, false, mult, eff, uses) if level > 0 then
groupcaps[g .. "_" .. level .. "_dig"] = get_groupcap(g, true, mult, eff, uses) groupcaps[g .. "_dig_" .. def.levels[level]] = get_groupcap(g, true, mult, efficiency, uses)
end
else else
groupcaps[g .. "_dig"] = get_groupcap(g, true, mult, eff, uses) groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses)
end end
end end
return groupcaps return groupcaps
end end
-- Checks if the given node would drop its useful drop if dug by a tool with the -- Checks if the given node would drop its useful drop if dug by a given tool.
-- given tool capabilities. Returns true if it will yield its useful drop, false -- Returns true if it will yield its useful drop, false otherwise.
-- otherwise. function mcl_autogroup.can_harvest(nodename, toolname)
function mcl_autogroup.can_harvest(nodename, tool_capabilities)
local ndef = minetest.registered_nodes[nodename] local ndef = minetest.registered_nodes[nodename]
local groupcaps = tool_capabilities.groupcaps
local handy = minetest.get_item_group(nodename, "handy") if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
local dig_immediate = minetest.get_item_group(nodename, "handy")
if handy > 0 or dig_immediate >= 2 then
return true return true
end end
for g, _ in pairs(groupcaps) do -- Check if it can be dug by tool
local tdef = minetest.registered_tools[toolname]
if tdef then
for g, gdef in pairs(tdef._mcl_autogroup_groupcaps) do
if ndef.groups[g] then if ndef.groups[g] then
if not string.find(g, "_0_dig$") and string.find(g, "_dig$") then if not gdef.level or ndef.groups[g] <= gdef.level then
return true return true
end end
end end
end end
end
-- Check if it can be dug by hand
local tdef = minetest.registered_tools[""]
if tdef then
for g, gdef in pairs(tdef._mcl_autogroup_groupcaps) do
if ndef.groups[g] then
if not gdef.level or ndef.groups[g] <= gdef.level then
return true
end
end
end
end
return false return false
end end
@ -212,25 +227,6 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
} }
end end
local function add_groupcaps(groupcaps, groupcaps_def, efficiency)
for g, capsdef in pairs(groupcaps_def) do
local mult = capsdef.tool_multiplier or 1
local eff = efficiency or 0
local uses = capsdef.uses
local def = mcl_autogroup.registered_diggroups[g]
local level = capsdef.level or 1
local max_level = def.levels or 0
if max_level > 0 then
level = math.min(level, max_level)
groupcaps[g .. "_0_dig"] = get_groupcap(g, false, mult, eff, uses)
groupcaps[g .. "_" .. level .. "_dig"] = get_groupcap(g, true, mult, eff, uses)
else
groupcaps[g .. "_dig"] = get_groupcap(g, true, mult, eff, uses)
end
end
end
-- Get the groupcaps for a tool. This function returns "groupcaps" table of -- Get the groupcaps for a tool. This function returns "groupcaps" table of
-- digging which should be put in the "tool_capabilities" of the tool definition -- digging which should be put in the "tool_capabilities" of the tool definition
-- or in the metadata of an enchanted tool. -- or in the metadata of an enchanted tool.
@ -289,9 +285,10 @@ local overwrite = function()
local index = hardness_lookup[g][ndef._mcl_hardness or 0] local index = hardness_lookup[g][ndef._mcl_hardness or 0]
if ndef.groups[g] then if ndef.groups[g] then
if gdef.levels then if gdef.levels then
newgroups[g .. "_0_dig"] = index newgroups[g .. "_dig_default"] = index
for i = ndef.groups.pickaxey, gdef.levels do
newgroups[g .. "_" .. i .. "_dig"] = index for i = ndef.groups[g], #gdef.levels do
newgroups[g .. "_dig_" .. gdef.levels[i]] = index
end end
else else
newgroups[g .. "_dig"] = index newgroups[g .. "_dig"] = index

View file

@ -18,9 +18,9 @@ mcl_autogroup.registered_diggroups = {}
-- def - Table with information about the diggroup (defaults to {} if unspecified) -- def - Table with information about the diggroup (defaults to {} if unspecified)
-- --
-- Values in def: -- Values in def:
-- level - If this value is 0 or unspecified, then the group does not have -- level - If this value is unspecified then the group does not have
-- levels, otherwise it is an integer greater than 0 which indicates how -- levels, otherwise it is an array containing the names of the
-- many digging levels the group supports. -- different digging levels the digging group supports.
function mcl_autogroup.register_diggroup(group, def) function mcl_autogroup.register_diggroup(group, def)
mcl_autogroup.registered_diggroups[group] = def or {} mcl_autogroup.registered_diggroups[group] = def or {}
end end

View file

@ -225,17 +225,20 @@ function minetest.handle_node_drops(pos, drops, digger)
-- Check if node will yield its useful drop by the digger's tool -- Check if node will yield its useful drop by the digger's tool
local dug_node = minetest.get_node(pos) local dug_node = minetest.get_node(pos)
local toolcaps local tooldef
local tool local tool
if digger ~= nil then if digger ~= nil then
tool = digger:get_wielded_item() tool = digger:get_wielded_item()
toolcaps = tool:get_tool_capabilities() tooldef = minetest.registered_tools[tool:get_name()]
if not mcl_autogroup.can_harvest(dug_node.name, toolcaps) then if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name()) then
return return
end end
end end
local diggroups = tooldef and tooldef._mcl_autogroup_groupcaps
local shearsy_level = diggroups and diggroups.shearsy and diggroups.shearsy.level
--[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop --[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop
from the node definition. from the node definition.
Definition of _mcl_shears_drop / _mcl_silk_touch_drop: Definition of _mcl_shears_drop / _mcl_silk_touch_drop:
@ -247,7 +250,7 @@ function minetest.handle_node_drops(pos, drops, digger)
local silk_touch_drop = false local silk_touch_drop = false
local nodedef = minetest.registered_nodes[dug_node.name] local nodedef = minetest.registered_nodes[dug_node.name]
if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then
if nodedef._mcl_shears_drop == true then if nodedef._mcl_shears_drop == true then
drops = { dug_node.name } drops = { dug_node.name }
else else

View file

@ -4,7 +4,9 @@ mcl_core = {}
mcl_core.repair = 0.05 mcl_core.repair = 0.05
mcl_autogroup.register_diggroup("handy") mcl_autogroup.register_diggroup("handy")
mcl_autogroup.register_diggroup("pickaxey", { levels = 5 }) mcl_autogroup.register_diggroup("pickaxey", {
levels = { "wood", "gold", "stone", "iron", "diamond" }
})
mcl_autogroup.register_diggroup("axey") mcl_autogroup.register_diggroup("axey")
mcl_autogroup.register_diggroup("shovely") mcl_autogroup.register_diggroup("shovely")
mcl_autogroup.register_diggroup("shearsy") mcl_autogroup.register_diggroup("shearsy")

View file

@ -6,14 +6,7 @@ local S = minetest.get_translator("mcl_tools")
-- Tool definition -- Tool definition
-- --
--[[ Maximum drop level definitions: --[[
- 0: Hand
- 1: Wood / Shears
- 2: Gold
- 3: Stone
- 4: Iron
- 5: Diamond
dig_speed_class group: dig_speed_class group:
- 1: Painfully slow - 1: Painfully slow
- 2: Very slow - 2: Very slow
@ -32,15 +25,28 @@ if minetest.is_creative_enabled("") then
hand_range = 10 hand_range = 10
hand_groups = { dig_speed_class = 7 } hand_groups = { dig_speed_class = 7 }
hand_autogroup_groupcaps = { hand_autogroup_groupcaps = {
creative_breakable = { tool_multiplier = 1000000, level = 0, uses = 0 }, handy = { tool_multiplier = 1000, level = 1, uses = 0 },
handy = { tool_multiplier = 1000000, level = 0, uses = 0 }, axey = { tool_multiplier = 1000, level = 1, uses = 0 },
pickaxey = { tool_multiplier = 1000000, level = 0, uses = 0 } pickaxey = { tool_multiplier = 1000, level = 5, uses = 0 },
shovely = { tool_multiplier = 1000, level = 1, uses = 0 },
swordy = { tool_multiplier = 1000, level = 1, uses = 0 },
swordy_cobweb = { tool_multiplier = 1000, level = 1, uses = 0 },
shearsy = { tool_multiplier = 1000, level = 1, uses = 0 },
shearsy_wool = { tool_multiplier = 1000, level = 1, uses = 0 },
shearsy_cobweb = { tool_multiplier = 1000, level = 1, uses = 0 },
} }
else else
groupcaps = {} groupcaps = {}
hand_autogroup_groupcaps = { hand_autogroup_groupcaps = {
handy = { tool_multiplier = 1, level = 0, uses = 0 }, handy = { tool_multiplier = 1, level = 1, uses = 0 },
pickaxey = { tool_multiplier = 1, level = 0, uses = 0 } axey = { tool_multiplier = 1, level = 1, uses = 0 },
shovely = { tool_multiplier = 1, level = 1, uses = 0 },
pickaxey = { tool_multiplier = 1, level = 0, uses = 0 },
swordy = { tool_multiplier = 1, level = 0, uses = 0 },
swordy_cobweb = { tool_multiplier = 1, level = 0, uses = 0 },
shearsy = { tool_multiplier = 1, level = 0, uses = 0 },
shearsy_wool = { tool_multiplier = 1, level = 0, uses = 0 },
shearsy_cobweb = { tool_multiplier = 1, level = 0, uses = 0 },
} }
hand_range = 4 hand_range = 4
hand_groups = { dig_speed_class = 1 } hand_groups = { dig_speed_class = 1 }
@ -267,7 +273,7 @@ minetest.register_tool("mcl_tools:shovel_wood", {
_repair_material = "group:wood", _repair_material = "group:wood",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
shovely = { tool_multiplier = 2, level = 1, uses = 60 } shovely = { tool_multiplier = 2, uses = 60 }
}, },
}) })
minetest.register_tool("mcl_tools:shovel_stone", { minetest.register_tool("mcl_tools:shovel_stone", {
@ -288,7 +294,7 @@ minetest.register_tool("mcl_tools:shovel_stone", {
_repair_material = "mcl_core:cobble", _repair_material = "mcl_core:cobble",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
shovely = { tool_multiplier = 4, level = 3, uses = 132 } shovely = { tool_multiplier = 4, uses = 132 }
}, },
}) })
minetest.register_tool("mcl_tools:shovel_iron", { minetest.register_tool("mcl_tools:shovel_iron", {
@ -309,7 +315,7 @@ minetest.register_tool("mcl_tools:shovel_iron", {
_repair_material = "mcl_core:iron_ingot", _repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
shovely = { tool_multiplier = 6, level = 4, uses = 251 } shovely = { tool_multiplier = 6, uses = 251 }
}, },
}) })
minetest.register_tool("mcl_tools:shovel_gold", { minetest.register_tool("mcl_tools:shovel_gold", {
@ -330,7 +336,7 @@ minetest.register_tool("mcl_tools:shovel_gold", {
_repair_material = "mcl_core:gold_ingot", _repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
shovely = { tool_multiplier = 12, level = 2, uses = 33 } shovely = { tool_multiplier = 12, uses = 33 }
}, },
}) })
minetest.register_tool("mcl_tools:shovel_diamond", { minetest.register_tool("mcl_tools:shovel_diamond", {
@ -351,7 +357,7 @@ minetest.register_tool("mcl_tools:shovel_diamond", {
_repair_material = "mcl_core:diamond", _repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
shovely = { tool_multiplier = 8, level = 5, uses = 1562 } shovely = { tool_multiplier = 8, uses = 1562 }
}, },
}) })
@ -373,7 +379,7 @@ minetest.register_tool("mcl_tools:axe_wood", {
_repair_material = "group:wood", _repair_material = "group:wood",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
axey = { tool_multiplier = 2, level = 1, uses = 60 } axey = { tool_multiplier = 2, uses = 60 }
}, },
}) })
minetest.register_tool("mcl_tools:axe_stone", { minetest.register_tool("mcl_tools:axe_stone", {
@ -392,7 +398,7 @@ minetest.register_tool("mcl_tools:axe_stone", {
_repair_material = "mcl_core:cobble", _repair_material = "mcl_core:cobble",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
axey = { tool_multiplier = 4, level = 3, uses = 132 } axey = { tool_multiplier = 4, uses = 132 }
}, },
}) })
minetest.register_tool("mcl_tools:axe_iron", { minetest.register_tool("mcl_tools:axe_iron", {
@ -412,7 +418,7 @@ minetest.register_tool("mcl_tools:axe_iron", {
_repair_material = "mcl_core:iron_ingot", _repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
axey = { tool_multiplier = 6, level = 4, uses = 251 } axey = { tool_multiplier = 6, uses = 251 }
}, },
}) })
minetest.register_tool("mcl_tools:axe_gold", { minetest.register_tool("mcl_tools:axe_gold", {
@ -431,7 +437,7 @@ minetest.register_tool("mcl_tools:axe_gold", {
_repair_material = "mcl_core:gold_ingot", _repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
axey = { tool_multiplier = 12, level = 2, uses = 33 } axey = { tool_multiplier = 12, uses = 33 }
}, },
}) })
minetest.register_tool("mcl_tools:axe_diamond", { minetest.register_tool("mcl_tools:axe_diamond", {
@ -450,7 +456,7 @@ minetest.register_tool("mcl_tools:axe_diamond", {
_repair_material = "mcl_core:diamond", _repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
axey = { tool_multiplier = 8, level = 5, uses = 1562 } axey = { tool_multiplier = 8, uses = 1562 }
}, },
}) })
@ -492,8 +498,8 @@ minetest.register_tool("mcl_tools:sword_stone", {
_repair_material = "mcl_core:cobble", _repair_material = "mcl_core:cobble",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
swordy = { tool_multiplier = 4, level = 3, uses = 132 }, swordy = { tool_multiplier = 4, level = 1, uses = 132 },
swordy_cobweb = { tool_multiplier = 4, level = 3, uses = 132 } swordy_cobweb = { tool_multiplier = 4, level = 1, uses = 132 }
}, },
}) })
minetest.register_tool("mcl_tools:sword_iron", { minetest.register_tool("mcl_tools:sword_iron", {
@ -512,8 +518,8 @@ minetest.register_tool("mcl_tools:sword_iron", {
_repair_material = "mcl_core:iron_ingot", _repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
swordy = { tool_multiplier = 6, level = 4, uses = 251 }, swordy = { tool_multiplier = 6, level = 1, uses = 251 },
swordy_cobweb = { tool_multiplier = 6, level = 4, uses = 251 } swordy_cobweb = { tool_multiplier = 6, level = 1, uses = 251 }
}, },
}) })
minetest.register_tool("mcl_tools:sword_gold", { minetest.register_tool("mcl_tools:sword_gold", {
@ -532,8 +538,8 @@ minetest.register_tool("mcl_tools:sword_gold", {
_repair_material = "mcl_core:gold_ingot", _repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
swordy = { tool_multiplier = 12, level = 2, uses = 33 }, swordy = { tool_multiplier = 12, level = 1, uses = 33 },
swordy_cobweb = { tool_multiplier = 12, level = 2, uses = 33 } swordy_cobweb = { tool_multiplier = 12, level = 1, uses = 33 }
}, },
}) })
minetest.register_tool("mcl_tools:sword_diamond", { minetest.register_tool("mcl_tools:sword_diamond", {
@ -552,8 +558,8 @@ minetest.register_tool("mcl_tools:sword_diamond", {
_repair_material = "mcl_core:diamond", _repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_autogroup_groupcaps = { _mcl_autogroup_groupcaps = {
swordy = { tool_multiplier = 8, level = 5, uses = 1562 }, swordy = { tool_multiplier = 8, level = 1, uses = 1562 },
swordy_cobweb = { tool_multiplier = 8, level = 5, uses = 1562 } swordy_cobweb = { tool_multiplier = 8, level = 1, uses = 1562 }
}, },
}) })