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

@ -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
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")
@ -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
shovely=1 in its groups. If the digging group has multiple levels the value of
the group indicates which digging level the node requires.
"mcl_core:stone_with_gold" for example has pickaxey=3 because it requires a
pickaxe of level 3 to be mined.
"mcl_core:stone_with_gold" for example has pickaxey=4 because it requires a
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
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
tool_multiplier = tool_multiplier or 1
speed_multiplier = tool_multiplier
if efficiency > 0 then
if efficiency then
speed_multiplier = speed_multiplier + efficiency * efficiency + 1
end
@ -160,46 +162,59 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
}
end
local function add_groupcaps(groupcaps, groupcaps_def)
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 = capsdef.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
local max_level = def.levels and #def.levels or 1
local level = math.min(capsdef.level or max_level, max_level)
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)
if def.levels then
groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses)
if level > 0 then
groupcaps[g .. "_dig_" .. def.levels[level]] = get_groupcap(g, true, mult, efficiency, uses)
end
else
groupcaps[g .. "_dig"] = get_groupcap(g, true, mult, eff, uses)
groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses)
end
end
return groupcaps
end
-- Checks if the given node would drop its useful drop if dug by a tool with the
-- given tool capabilities. Returns true if it will yield its useful drop, false
-- otherwise.
function mcl_autogroup.can_harvest(nodename, tool_capabilities)
-- Checks if the given node would drop its useful drop if dug by a given tool.
-- Returns true if it will yield its useful drop, false otherwise.
function mcl_autogroup.can_harvest(nodename, toolname)
local ndef = minetest.registered_nodes[nodename]
local groupcaps = tool_capabilities.groupcaps
local handy = minetest.get_item_group(nodename, "handy")
local dig_immediate = minetest.get_item_group(nodename, "handy")
if handy > 0 or dig_immediate >= 2 then
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
return true
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 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
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
end
@ -212,25 +227,6 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
}
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
-- digging which should be put in the "tool_capabilities" of the tool definition
-- 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]
if ndef.groups[g] then
if gdef.levels then
newgroups[g .. "_0_dig"] = index
for i = ndef.groups.pickaxey, gdef.levels do
newgroups[g .. "_" .. i .. "_dig"] = index
newgroups[g .. "_dig_default"] = index
for i = ndef.groups[g], #gdef.levels do
newgroups[g .. "_dig_" .. gdef.levels[i]] = index
end
else
newgroups[g .. "_dig"] = index

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

@ -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
local dug_node = minetest.get_node(pos)
local toolcaps
local tooldef
local tool
if digger ~= nil then
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
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
from the node definition.
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 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
drops = { dug_node.name }
else

@ -4,7 +4,9 @@ mcl_core = {}
mcl_core.repair = 0.05
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("shovely")
mcl_autogroup.register_diggroup("shearsy")

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