From fb6f5eae7a4a92e8bb2abd0924ddafebc011ceb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 9 Mar 2021 21:43:25 +0100 Subject: [PATCH 01/25] Rewrite mcl_autogroup These changes are primarly made to make mcl_autogroup more efficient. Previously enchanted tools required storing around 21 kB of metadata due to the way the previous version of the mod was implemented. This caused a lot of lag and a huge amount of network traffic. With the changes enchanted tools won't require more than 1 kB of metadata. The mod is also rewritten to use an API to register digging groups and compute the groupcaps for tools. This will make it easier for modders to register custom digging groups. The mod is now split up into two parts. One part called "mcl_autogroup" to implement the API for registering custom digging groups, and the other part called "_mcl_autogroup" which contains most of the code which has to be loaded after most mods. --- mods/CORE/_mcl_autogroup/depends.txt | 1 + mods/CORE/_mcl_autogroup/init.lua | 360 ++++++++++++++++--------- mods/CORE/mcl_autogroup/init.lua | 15 ++ mods/ENTITIES/mcl_item_entity/init.lua | 58 +--- mods/ITEMS/mcl_core/depends.txt | 1 + mods/ITEMS/mcl_core/init.lua | 11 + mods/ITEMS/mcl_core/nodes_misc.lua | 2 +- mods/ITEMS/mcl_tools/init.lua | 114 ++++---- 8 files changed, 319 insertions(+), 243 deletions(-) create mode 100644 mods/CORE/mcl_autogroup/init.lua diff --git a/mods/CORE/_mcl_autogroup/depends.txt b/mods/CORE/_mcl_autogroup/depends.txt index e69de29bb..2c9bbaec7 100644 --- a/mods/CORE/_mcl_autogroup/depends.txt +++ b/mods/CORE/_mcl_autogroup/depends.txt @@ -0,0 +1 @@ +mcl_autogroup diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index aabfa5906..7c1deecf4 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -1,169 +1,273 @@ ---[[ Mining times. Yeah, mining times … Alright, this is going to be FUN! +--[[ +This mod implements a HACK to make 100% sure the digging times of all tools +match Minecraft's perfectly. The digging times system of Minetest is very +different, so this weird group trickery has to be used. In Minecraft, each +block has a hardness and the actual Minecraft digging time is determined by +this: -This mod does include a HACK to make 100% sure the digging times of all tools match Minecraft's perfectly. -The digging times system of Minetest is very different, so this weird group trickery has to be used. -In Minecraft, each block has a hardness and the actual Minecraft digging time is determined by this: 1) The block's hardness -2) The tool being used -3) Whether the tool is considered as “eligible” for the block +2) The tool being used (the tool_multiplier and its efficiency level) +3) Whether the tool is considered as "eligible" for the block (e.g. only diamond pick eligible for obsidian) -See Minecraft Wiki for more information. -In MineClone 2, all diggable node have the hardness set in the custom field “_mcl_hardness” (0 by default). -The nodes are also required to specify the “eligible” tools in groups like “pickaxey”, “shovely”, etc. -This mod then calculates the real digging time based on the node meta data. The real digging times -are then added into mcl_autogroup.digtimes where the table indices are group rating and the values are the -digging times in seconds. These digging times can be then added verbatim into the tool definitions. +See Minecraft Wiki for more +information. -Example: -mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2 +How the mod is used +=================== -→ This means that when a node has been assigned the group “pickaxey_dig_diamond=1”, it can be dug by the -diamond pickaxe in 0.2 seconds. +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_digtime_group("pickaxey", { levels = 5 }) + mcl_autogroup.register_digtime_group("shovely") + mcl_autogroup.register_digtime_group("shovely") +The first line registers "pickaxey" as a digging group. The "levels" field +indicates that the digging group have 5 levels (in this case one for each +material of a pickaxe). The second line registers "shovely" as a digging group +which does not have separate levels (if the "levels" field is not set it +defaults to 0). -This strange setup with mcl_autogroup has been done to minimize the amount of required digging times -a single tool needs to use. If this is not being done, the loading time will increase considerably -(>10s). +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. -]] +For tools to be able to dig nodes of the digging groups they need to use the +"mcl_autogroups.get_groupcaps" function to get the groupcaps. See +"mcl_tools/init.lua" for examples of this. -local materials = { "wood", "gold", "stone", "iron", "diamond" } -local basegroups = { "pickaxey", "axey", "shovely" } -local minigroups = { "handy", "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } -local divisors = { - ["wood"] = 2, - ["gold"] = 12, - ["stone"] = 4, - ["iron"] = 6, - ["diamond"] = 8, - ["handy"] = 1, - ["shearsy"] = 15, - ["swordy"] = 1.5, - ["shearsy_wool"] = 5, - ["swordy_cobweb"] = 15, -} -local max_efficiency_level = 5 +Information about the mod +========================= -mcl_autogroup = {} -mcl_autogroup.digtimes = {} -mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode +The mod is also split up into two mods, mcl_autogroups and _mcl_autogroups. +mcl_autogroups contains the API functions used to register custom digging +groups. _mcl_autogroups contains parts of the mod which need to be executed +after loading all other mods. +--]] -for m=1, #materials do - for g=1, #basegroups do - mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m]] = {} - mcl_autogroup.creativetimes[basegroups[g].."_dig_"..materials[m]] = {} - for e=1, max_efficiency_level do - mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m].."_efficiency_"..e] = {} +-- The groups which affect dig times +local basegroups = {} +for group, _ in pairs(mcl_autogroup.registered_digtime_groups) do + table.insert(basegroups, group) +end + +-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to +-- each basegroup. +local function get_hardness_values_for_groups() + local maps = {} + local values = {} + for _, g in pairs(basegroups) do + maps[g] = {} + values[g] = {} + end + + for _, ndef in pairs(minetest.registered_nodes) do + for _, g in pairs(basegroups) do + if ndef.groups[g] ~= nil then + maps[g][ndef._mcl_hardness or 0] = true + end end end -end -for g=1, #minigroups do - mcl_autogroup.digtimes[minigroups[g].."_dig"] = {} - mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {} - for e=1, max_efficiency_level do - mcl_autogroup.digtimes[minigroups[g].."_dig_efficiency_"..e] = {} - mcl_autogroup.creativetimes[minigroups[g].."_dig_efficiency_"..e] = {} + + for g, map in pairs(maps) do + for k, _ in pairs(map) do + table.insert(values[g], k) + end end + + for _, g in pairs(basegroups) do + table.sort(values[g]) + end + return values end +-- Returns a table containing a table indexed by "_mcl_hardness_value" to get +-- its index in the list of unique hardnesses for each basegroup. +local function get_hardness_lookup_for_groups(hardness_values) + map = {} + for g, values in pairs(hardness_values) do + map[g] = {} + for k, v in pairs(values) do + map[g][v] = k + end + end + return map +end + +-- Array of unique hardness values for each group which affects dig time. +local hardness_values = get_hardness_values_for_groups() + +-- Map indexed by hardness values which return the index of that value in +-- hardness_value. Used for quick lookup. +local hardness_lookup = get_hardness_lookup_for_groups(hardness_values) + +local function compute_creativetimes(group) + local creativetimes = {} + + for index, hardness in pairs(hardness_values[group]) do + table.insert(creativetimes, 0) + end + + return creativetimes +end + +-- Get the list of digging times for using a specific tool on a specific group. +-- +-- Parameters: +-- group - the group which it is digging +-- can_harvest - if the tool can harvest the block +-- tool_multiplier - dig speed multiplier for tool (default 1) +-- efficiency - efficiency level for the tool (default 0) +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 + speed_multiplier = speed_multiplier + efficiency * efficiency + 1 + end + + local digtimes = {} + + for index, hardness in pairs(hardness_values[group]) do + local digtime = (hardness or 0) / speed_multiplier + if can_harvest then + digtime = digtime * 1.5 + else + digtime = digtime * 5 + end + + if digtime <= 0.05 then + digtime = 0 + else + digtime = math.ceil(digtime * 20) / 20 + end + table.insert(digtimes, digtime) + end + + return digtimes +end + +-- Get one groupcap field for using a specific tool on a specific group. +local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) + return { + times = get_digtimes(group, can_harvest, multiplier, efficiency), + uses = uses, + maxlevel = 0, + } +end + +-- Get the groupcaps for a tool on the specified digging groups. groupcaps_def +-- contains a table with keys being the digging group and values being the tools +-- properties for that digging group. +-- +-- The tool properties can have the following values: +-- +-- tool_multiplier - the digging speed multiplier for this tool (default 1) +-- efficiency - the efficiency level for this tool (default 0) +-- level - the maximum level of the group the tool can harvest (default 1) +-- uses - the number of uses the tool has for this group +-- +-- A level of 0 means that the tool will be able to dig that group but will +-- never be able to harvest the nodes of that group and will always get a +-- digging time penalty. This is useful for implementing the hand. +-- +-- Example usage: +-- +-- mcl_autogroup.get_groupcaps { +-- pickaxey = { tool_multiplier = 4, level = 3, uses = 132 } +-- } +-- +-- This computes the groupcaps for a tool mining "pickaxey" blocks. The tool +-- has a digging speed multiplier of 4, can mine nodes of level >= 3 and has 132 +-- uses. +function mcl_autogroup.get_groupcaps(groupcaps_def) + local groupcaps = {} + + for g, capsdef in pairs(groupcaps_def) do + local mult = capsdef.tool_multiplier or 1 + local eff = capsdef.efficiency or 0 + local def = mcl_autogroup.registered_digtime_groups[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) + groupcaps[g .. "_" .. level .. "_dig"] = get_groupcap(g, true, mult, eff) + else + groupcaps[g .. "_dig"] = get_groupcap(g, true, mult, eff) + 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) + 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 + return true + end + + for g, _ in pairs(groupcaps) do + if ndef.groups[g] then + if not string.find(g, "_0_dig$") and string.find(g, "_dig$") then + return true + end + end + end + return false +end + +-- This function automatically assigns the "solid" and "opaque" groups to all +-- registered nodes and assigns groups to get the correct digging times for +-- groups registered with "mcl_autogroup.register_digtime_group". local overwrite = function() for nname, ndef in pairs(minetest.registered_nodes) do - local groups_changed = false local newgroups = table.copy(ndef.groups) if (nname ~= "ignore" and ndef.diggable) then - -- Automatically assign the “solid” group for solid nodes + -- Automatically assign the "solid" group for solid nodes if (ndef.walkable == nil or ndef.walkable == true) and (ndef.collision_box == nil or ndef.collision_box.type == "regular") and (ndef.node_box == nil or ndef.node_box.type == "regular") and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then newgroups.solid = 1 - groups_changed = true end - -- Automatically assign the “opaque” group for opaque nodes + -- Automatically assign the "opaque" group for opaque nodes if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and (ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then newgroups.opaque = 1 - groups_changed = true end - local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating, efficiency) - local time, validity_factor - if actual_rating >= expected_rating then - -- Valid tool - validity_factor = 1.5 - else - -- Wrong tool (higher digging time) - validity_factor = 5 - end - local speed_multiplier = divisors[material] - if efficiency then - speed_multiplier = speed_multiplier + efficiency * efficiency + 1 - end - time = (hardness * validity_factor) / speed_multiplier - if time <= 0.05 then - time = 0 - else - time = math.ceil(time * 20) / 20 - end - table.insert(mcl_autogroup.digtimes[diggroup], time) - if not efficiency then - table.insert(mcl_autogroup.creativetimes[diggroup], 0) - end - newgroups[diggroup] = #mcl_autogroup.digtimes[diggroup] - return newgroups - end - - -- Hack in digging times - local hardness = ndef._mcl_hardness - if not hardness then - hardness = 0 - end - - -- Handle pickaxey, axey and shovely - for _, basegroup in pairs(basegroups) do - if (hardness ~= -1 and ndef.groups[basegroup]) then - for g=1,#materials do - local diggroup = basegroup.."_dig_"..materials[g] - newgroups = calculate_group(hardness, materials[g], diggroup, newgroups, g, ndef.groups[basegroup]) - for e=1,max_efficiency_level do - newgroups = calculate_group(hardness, materials[g], diggroup .. "_efficiency_" .. e, newgroups, g, ndef.groups[basegroup], e) + for g, gdef in pairs(mcl_autogroup.registered_digtime_groups) do + local index = hardness_lookup[g][ndef._mcl_hardness] + 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 end - groups_changed = true - end - end - end - for m=1, #minigroups do - local minigroup = minigroups[m] - if hardness ~= -1 then - local diggroup = minigroup.."_dig" - -- actual rating - local ar = ndef.groups[minigroup] - if ar == nil then - ar = 0 - end - if (minigroup == "handy") - or - (ndef.groups.shearsy_wool and minigroup == "shearsy_wool" and ndef.groups.wool) - or - (ndef.groups.swordy_cobweb and minigroup == "swordy_cobweb" and nname == "mcl_core:cobweb") - or - (ndef.groups[minigroup] and minigroup ~= "swordy_cobweb" and minigroup ~= "shearsy_wool") then - newgroups = calculate_group(hardness, minigroup, diggroup, newgroups, ar, 1) - for e=1,max_efficiency_level do - newgroups = calculate_group(hardness, minigroup, diggroup .. "_efficiency_" .. e, newgroups, ar, 1, e) - end - groups_changed = true + else + local index = hardness_lookup[g][ndef._mcl_hardness] + newgroups[g .. "_dig"] = index end end end - if groups_changed then - minetest.override_item(nname, { - groups = newgroups - }) - end + minetest.override_item(nname, { + groups = newgroups + }) end end end diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua new file mode 100644 index 000000000..ff1c90cd0 --- /dev/null +++ b/mods/CORE/mcl_autogroup/init.lua @@ -0,0 +1,15 @@ +--[[ +This mod implements the API to register digging groups for mcl_autogroups. The +rest of the mod is implemented and documented in the mod "_mcl_autogroup". + +The mcl_autogroups mod is split up into two mods, mcl_autogroups and +_mcl_autogroups. mcl_autogroups contains the API functions used to register +custom digging groups. _mcl_autogroups contains parts of the mod which need to +be executed after loading all other mods. +--]] +mcl_autogroup = {} +mcl_autogroup.registered_digtime_groups = {} + +function mcl_autogroup.register_digtime_group(group, def) + mcl_autogroup.registered_digtime_groups[group] = def or {} +end diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index e5863abbc..f0aa289f2 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -169,62 +169,6 @@ local minigroups = { "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } local basegroups = { "pickaxey", "axey", "shovely" } local materials = { "wood", "gold", "stone", "iron", "diamond" } --- 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. -local check_can_drop = function(node_name, tool_capabilities) - local handy = minetest.get_item_group(node_name, "handy") - local dig_immediate = minetest.get_item_group(node_name, "dig_immediate") - if handy == 1 or dig_immediate == 2 or dig_immediate == 3 then - return true - else - local toolgroupcaps - if tool_capabilities then - toolgroupcaps = tool_capabilities.groupcaps - else - return false - end - - -- Compare node groups with tool capabilities - for m=1, #minigroups do - local minigroup = minigroups[m] - local g = minetest.get_item_group(node_name, minigroup) - if g ~= 0 then - local plus = minigroup .. "_dig" - if toolgroupcaps[plus] then - return true - end - for e=1,5 do - local effplus = plus .. "_efficiency_" .. e - if toolgroupcaps[effplus] then - return true - end - end - end - end - for b=1, #basegroups do - local basegroup = basegroups[b] - local g = minetest.get_item_group(node_name, basegroup) - if g ~= 0 then - for m=g, #materials do - local plus = basegroup .. "_dig_"..materials[m] - if toolgroupcaps[plus] then - return true - end - for e=1,5 do - local effplus = plus .. "_efficiency_" .. e - if toolgroupcaps[effplus] then - return true - end - end - end - end - end - - return false - end -end - -- Stupid workaround to get drops from a drop table: -- Create a temporary table in minetest.registered_nodes that contains the proper drops, -- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition @@ -287,7 +231,7 @@ function minetest.handle_node_drops(pos, drops, digger) tool = digger:get_wielded_item() toolcaps = tool:get_tool_capabilities() - if not check_can_drop(dug_node.name, toolcaps) then + if not mcl_autogroup.can_harvest(dug_node.name, toolcaps) then return end end diff --git a/mods/ITEMS/mcl_core/depends.txt b/mods/ITEMS/mcl_core/depends.txt index fb9861814..4e3912e1d 100644 --- a/mods/ITEMS/mcl_core/depends.txt +++ b/mods/ITEMS/mcl_core/depends.txt @@ -1,3 +1,4 @@ +mcl_autogroup mcl_init mcl_sounds mcl_particles diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 520f158bd..91e82be6e 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -3,6 +3,17 @@ mcl_core = {} -- Repair percentage for toolrepair mcl_core.repair = 0.05 +mcl_autogroup.register_digtime_group("handy") +mcl_autogroup.register_digtime_group("pickaxey", { levels = 5 }) +mcl_autogroup.register_digtime_group("axey") +mcl_autogroup.register_digtime_group("shovely") +mcl_autogroup.register_digtime_group("shearsy") +mcl_autogroup.register_digtime_group("shearsy_wool") +mcl_autogroup.register_digtime_group("shearsy_cobweb") +mcl_autogroup.register_digtime_group("swordy") +mcl_autogroup.register_digtime_group("swordy_cobweb") +mcl_autogroup.register_digtime_group("creative_breakable") + -- Load files local modpath = minetest.get_modpath("mcl_core") dofile(modpath.."/functions.lua") diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index 305682244..083aa0b85 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -108,7 +108,7 @@ minetest.register_node("mcl_core:cobweb", { liquid_renewable = false, liquid_range = 0, walkable = false, - groups = {swordy_cobweb=1,shearsy=1, fake_liquid=1, disable_jump=1, deco_block=1, dig_by_piston=1, dig_by_water=1,destroy_by_lava_flow=1,}, + groups = {swordy_cobweb=1, shearsy_cobweb=1, fake_liquid=1, disable_jump=1, deco_block=1, dig_by_piston=1, dig_by_water=1,destroy_by_lava_flow=1,}, drop = "mcl_mobitems:string", _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index d40b8e01b..c8263ef73 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -28,18 +28,17 @@ dig_speed_class group: local groupcaps, hand_range, hand_groups if minetest.is_creative_enabled("") then -- Instant breaking in creative mode - groupcaps = { - creative_breakable = {times={[1]=0}, uses=0}, + groupcaps = mcl_autogroup.get_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 } } - -- mcl_autogroup provides the creative digging times for all digging groups - for k,v in pairs(mcl_autogroup.creativetimes) do - groupcaps[k] = { times = v, uses = 0 } - end hand_range = 10 hand_groups = { dig_speed_class = 7 } else - groupcaps = { - handy_dig = {times=mcl_autogroup.digtimes.handy_dig, uses=0}, + groupcaps = mcl_autogroup.get_groupcaps { + handy = { tool_multiplier = 1, level = 0, uses = 0 }, + pickaxey = { tool_multiplier = 1, level = 0, uses = 0 } } hand_range = 4 hand_groups = { dig_speed_class = 1 } @@ -86,8 +85,8 @@ minetest.register_tool("mcl_tools:pick_wood", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=1, - groupcaps={ - pickaxey_dig_wood = {times=mcl_autogroup.digtimes.pickaxey_dig_wood, uses=60, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + pickaxey = { tool_multiplier = 2, level = 1, uses = 60 } }, damage_groups = {fleshy=2}, punch_attack_uses = 30, @@ -106,8 +105,8 @@ minetest.register_tool("mcl_tools:pick_stone", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=3, - groupcaps={ - pickaxey_dig_stone = {times=mcl_autogroup.digtimes.pickaxey_dig_stone, uses=132, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + pickaxey = { tool_multiplier = 4, level = 3, uses = 132 } }, damage_groups = {fleshy=3}, punch_attack_uses = 66, @@ -126,8 +125,8 @@ minetest.register_tool("mcl_tools:pick_iron", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=4, - groupcaps={ - pickaxey_dig_iron = {times=mcl_autogroup.digtimes.pickaxey_dig_iron , uses=251, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + pickaxey = { tool_multiplier = 6, level = 4, uses = 251 } }, damage_groups = {fleshy=4}, punch_attack_uses = 126, @@ -146,8 +145,8 @@ minetest.register_tool("mcl_tools:pick_gold", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=2, - groupcaps={ - pickaxey_dig_gold = {times=mcl_autogroup.digtimes.pickaxey_dig_gold , uses=33, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + pickaxey = { tool_multiplier = 12, level = 2, uses = 33 } }, damage_groups = {fleshy=2}, punch_attack_uses = 17, @@ -166,8 +165,8 @@ minetest.register_tool("mcl_tools:pick_diamond", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=5, - groupcaps={ - pickaxey_dig_diamond = {times=mcl_autogroup.digtimes.pickaxey_dig_diamond, uses=1562, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + pickaxey = { tool_multiplier = 8, level = 5, uses = 1562 } }, damage_groups = {fleshy=5}, punch_attack_uses = 781, @@ -288,8 +287,8 @@ minetest.register_tool("mcl_tools:shovel_wood", { tool_capabilities = { full_punch_interval = 1, max_drop_level=1, - groupcaps={ - shovely_dig_wood = {times=mcl_autogroup.digtimes.shovely_dig_wood, uses=60, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + shovely = { tool_multiplier = 2, level = 1, uses = 60 } }, damage_groups = {fleshy=2}, punch_attack_uses = 30, @@ -309,8 +308,8 @@ minetest.register_tool("mcl_tools:shovel_stone", { tool_capabilities = { full_punch_interval = 1, max_drop_level=3, - groupcaps={ - shovely_dig_stone = {times=mcl_autogroup.digtimes.shovely_dig_stone, uses=132, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + shovely = { tool_multiplier = 4, level = 3, uses = 132 } }, damage_groups = {fleshy=3}, punch_attack_uses = 66, @@ -330,8 +329,8 @@ minetest.register_tool("mcl_tools:shovel_iron", { tool_capabilities = { full_punch_interval = 1, max_drop_level=4, - groupcaps={ - shovely_dig_iron = {times=mcl_autogroup.digtimes.shovely_dig_iron, uses=251, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + shovely = { tool_multiplier = 6, level = 4, uses = 251 } }, damage_groups = {fleshy=4}, punch_attack_uses = 126, @@ -351,8 +350,8 @@ minetest.register_tool("mcl_tools:shovel_gold", { tool_capabilities = { full_punch_interval = 1, max_drop_level=2, - groupcaps={ - shovely_dig_gold = {times=mcl_autogroup.digtimes.shovely_dig_gold, uses=33, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + shovely = { tool_multiplier = 12, level = 2, uses = 33 } }, damage_groups = {fleshy=2}, punch_attack_uses = 17, @@ -372,8 +371,8 @@ minetest.register_tool("mcl_tools:shovel_diamond", { tool_capabilities = { full_punch_interval = 1, max_drop_level=5, - groupcaps={ - shovely_dig_diamond = {times=mcl_autogroup.digtimes.shovely_dig_diamond, uses=1562, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + shovely = { tool_multiplier = 8, level = 5, uses = 1562 } }, damage_groups = {fleshy=5}, punch_attack_uses = 781, @@ -395,8 +394,8 @@ minetest.register_tool("mcl_tools:axe_wood", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=1, - groupcaps={ - axey_dig_wood = {times=mcl_autogroup.digtimes.axey_dig_wood, uses=60, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + axey = { tool_multiplier = 2, level = 1, uses = 60 } }, damage_groups = {fleshy=7}, punch_attack_uses = 30, @@ -414,8 +413,8 @@ minetest.register_tool("mcl_tools:axe_stone", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=3, - groupcaps={ - axey_dig_stone = {times=mcl_autogroup.digtimes.axey_dig_stone, uses=132, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + axey = { tool_multiplier = 4, level = 3, uses = 132 } }, damage_groups = {fleshy=9}, punch_attack_uses = 66, @@ -434,8 +433,8 @@ minetest.register_tool("mcl_tools:axe_iron", { -- 1/0.9 full_punch_interval = 1.11111111, max_drop_level=4, - groupcaps={ - axey_dig_iron = {times=mcl_autogroup.digtimes.axey_dig_iron, uses=251, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + axey = { tool_multiplier = 6, level = 4, uses = 251 } }, damage_groups = {fleshy=9}, punch_attack_uses = 126, @@ -453,8 +452,8 @@ minetest.register_tool("mcl_tools:axe_gold", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=2, - groupcaps={ - axey_dig_gold= {times=mcl_autogroup.digtimes.axey_dig_gold, uses=33, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + axey = { tool_multiplier = 12, level = 2, uses = 33 } }, damage_groups = {fleshy=7}, punch_attack_uses = 17, @@ -472,8 +471,8 @@ minetest.register_tool("mcl_tools:axe_diamond", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=5, - groupcaps={ - axey_dig_diamond = {times=mcl_autogroup.digtimes.axey_dig_diamond, uses=1562, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + axey = { tool_multiplier = 8, level = 5, uses = 1562 } }, damage_groups = {fleshy=9}, punch_attack_uses = 781, @@ -494,9 +493,9 @@ minetest.register_tool("mcl_tools:sword_wood", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=1, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig , uses=60, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=60, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + swordy = { tool_multiplier = 2, level = 1, uses = 60 }, + swordy_cobweb = { tool_multiplier = 2, level = 1, uses = 60 } }, damage_groups = {fleshy=4}, punch_attack_uses = 60, @@ -514,9 +513,9 @@ minetest.register_tool("mcl_tools:sword_stone", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=3, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig , uses=132, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=132, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + swordy = { tool_multiplier = 4, level = 3, uses = 132 }, + swordy_cobweb = { tool_multiplier = 4, level = 3, uses = 132 } }, damage_groups = {fleshy=5}, punch_attack_uses = 132, @@ -534,9 +533,9 @@ minetest.register_tool("mcl_tools:sword_iron", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=4, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=251, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=251, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + swordy = { tool_multiplier = 6, level = 4, uses = 251 }, + swordy_cobweb = { tool_multiplier = 6, level = 4, uses = 251 } }, damage_groups = {fleshy=6}, punch_attack_uses = 251, @@ -554,9 +553,9 @@ minetest.register_tool("mcl_tools:sword_gold", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=2, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=33, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig, uses=33, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + swordy = { tool_multiplier = 12, level = 2, uses = 33 }, + swordy_cobweb = { tool_multiplier = 12, level = 2, uses = 33 } }, damage_groups = {fleshy=4}, punch_attack_uses = 33, @@ -574,9 +573,9 @@ minetest.register_tool("mcl_tools:sword_diamond", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=5, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=1562, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig, uses=1562, maxlevel=0}, + groupcaps = mcl_autogroup.get_groupcaps { + swordy = { tool_multiplier = 8, level = 5, uses = 1562 }, + swordy_cobweb = { tool_multiplier = 8, level = 5, uses = 1562 } }, damage_groups = {fleshy=7}, punch_attack_uses = 1562, @@ -598,10 +597,11 @@ minetest.register_tool("mcl_tools:shears", { tool_capabilities = { full_punch_interval = 0.5, max_drop_level=1, - groupcaps={ - shearsy_dig = {times=mcl_autogroup.digtimes.shearsy_dig, uses=238, maxlevel=0}, - shearsy_wool_dig = {times=mcl_autogroup.digtimes.shearsy_wool_dig, uses=238, maxlevel=0}, - } + groupcaps = mcl_autogroup.get_groupcaps { + shearsy = { tool_multiplier = 1.5, level = 1, uses = 238 }, + shearsy_wool = { tool_multiplier = 5, level = 1, uses = 238 }, + shearsy_cobweb = { tool_multiplier = 15, level = 1, uses = 238 } + }, }, on_place = carve_pumpkin, sound = { breaks = "default_tool_breaks" }, From f8461d5e90ae8b05aab0606c3a56d4c0b14dfdc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 11 Mar 2021 14:49:09 +0100 Subject: [PATCH 02/25] Remove mcl_autogroups.get_groupcaps Requiring tool definitions to call a function in _mcl_autogroup means that they need to be loaded after _mcl_autogroup. This can cause problems because _mcl_autogroup needs to be loaded after all tool and node definitions are completed. Because of this the API is changed so tool definitions instead put the data used to generate groupcaps in the custom field _mcl_autogroup_groupcaps. _mcl_autogroup will then go through all registered tools and update the groupcaps for every tool where this field is present. This means that no mod ever has to depend on _mcl_autogroup. --- mods/CORE/_mcl_autogroup/init.lua | 30 ++++-- mods/ITEMS/mcl_tools/depends.txt | 1 - mods/ITEMS/mcl_tools/init.lua | 153 +++++++++++++++--------------- 3 files changed, 99 insertions(+), 85 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 7c1deecf4..788cb1164 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -38,8 +38,8 @@ the group indicates which digging level the node requires. pickaxe of level 3 to be mined. For tools to be able to dig nodes of the digging groups they need to use the -"mcl_autogroups.get_groupcaps" function to get the groupcaps. See -"mcl_tools/init.lua" for examples of this. +have the custom field "_mcl_autogroup_groupcaps" function to get the groupcaps. +See "mcl_tools/init.lua" for examples of this. Information about the mod ========================= @@ -185,9 +185,7 @@ end -- This computes the groupcaps for a tool mining "pickaxey" blocks. The tool -- has a digging speed multiplier of 4, can mine nodes of level >= 3 and has 132 -- uses. -function mcl_autogroup.get_groupcaps(groupcaps_def) - local groupcaps = {} - +local function add_groupcaps(groupcaps, groupcaps_def) for g, capsdef in pairs(groupcaps_def) do local mult = capsdef.tool_multiplier or 1 local eff = capsdef.efficiency or 0 @@ -203,7 +201,6 @@ function mcl_autogroup.get_groupcaps(groupcaps_def) groupcaps[g .. "_dig"] = get_groupcap(g, true, mult, eff) end end - return groupcaps end @@ -230,9 +227,6 @@ function mcl_autogroup.can_harvest(nodename, tool_capabilities) return false end --- This function automatically assigns the "solid" and "opaque" groups to all --- registered nodes and assigns groups to get the correct digging times for --- groups registered with "mcl_autogroup.register_digtime_group". local overwrite = function() for nname, ndef in pairs(minetest.registered_nodes) do local newgroups = table.copy(ndef.groups) @@ -250,6 +244,8 @@ local overwrite = function() newgroups.opaque = 1 end + -- Assign groups used for digging this node depending on + -- the registered digging groups for g, gdef in pairs(mcl_autogroup.registered_digtime_groups) do local index = hardness_lookup[g][ndef._mcl_hardness] if ndef.groups[g] then @@ -270,6 +266,22 @@ local overwrite = function() }) end end + + for tname, tdef in pairs(minetest.registered_tools) do + -- Assign groupcaps for digging the registered digging groups + -- depending on the _mcl_autogroups_groupcaps in the tool + -- definition + if tdef._mcl_autogroup_groupcaps then + local toolcaps = table.copy(tdef.tool_capabilities) or {} + local groupcaps = toolcaps.groupcaps or {} + groupcaps = add_groupcaps(groupcaps, tdef._mcl_autogroup_groupcaps) + toolcaps.groupcaps = groupcaps + + minetest.override_item(tname, { + tool_capabilities = toolcaps + }) + end + end end overwrite() diff --git a/mods/ITEMS/mcl_tools/depends.txt b/mods/ITEMS/mcl_tools/depends.txt index 5ce101eda..3d96266de 100644 --- a/mods/ITEMS/mcl_tools/depends.txt +++ b/mods/ITEMS/mcl_tools/depends.txt @@ -1,2 +1 @@ mcl_sounds -_mcl_autogroup diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index c8263ef73..85119d18a 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -28,22 +28,24 @@ dig_speed_class group: local groupcaps, hand_range, hand_groups if minetest.is_creative_enabled("") then -- Instant breaking in creative mode - groupcaps = mcl_autogroup.get_groupcaps { + groupcaps = {} + 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 } } - hand_range = 10 - hand_groups = { dig_speed_class = 7 } else - groupcaps = mcl_autogroup.get_groupcaps { + groupcaps = {} + hand_autogroup_groupcaps = { handy = { tool_multiplier = 1, level = 0, uses = 0 }, pickaxey = { tool_multiplier = 1, level = 0, uses = 0 } } hand_range = 4 hand_groups = { dig_speed_class = 1 } end -minetest.register_item(":", { +minetest.register_tool(":", { type = "none", _doc_items_longdesc = S("You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.").."\n".. S("When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.").."\n".. @@ -60,6 +62,7 @@ minetest.register_item(":", { damage_groups = {fleshy=1}, }, groups = hand_groups, + _mcl_autogroup_groupcaps = hand_autogroup_groupcaps, }) -- Help texts @@ -85,15 +88,15 @@ minetest.register_tool("mcl_tools:pick_wood", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=1, - groupcaps = mcl_autogroup.get_groupcaps { - pickaxey = { tool_multiplier = 2, level = 1, uses = 60 } - }, damage_groups = {fleshy=2}, punch_attack_uses = 30, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + pickaxey = { tool_multiplier = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:pick_stone", { description = S("Stone Pickaxe"), @@ -105,15 +108,15 @@ minetest.register_tool("mcl_tools:pick_stone", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=3, - groupcaps = mcl_autogroup.get_groupcaps { - pickaxey = { tool_multiplier = 4, level = 3, uses = 132 } - }, damage_groups = {fleshy=3}, punch_attack_uses = 66, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + pickaxey = { tool_multiplier = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:pick_iron", { description = S("Iron Pickaxe"), @@ -125,15 +128,15 @@ minetest.register_tool("mcl_tools:pick_iron", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=4, - groupcaps = mcl_autogroup.get_groupcaps { - pickaxey = { tool_multiplier = 6, level = 4, uses = 251 } - }, damage_groups = {fleshy=4}, punch_attack_uses = 126, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + pickaxey = { tool_multiplier = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:pick_gold", { description = S("Golden Pickaxe"), @@ -145,15 +148,15 @@ minetest.register_tool("mcl_tools:pick_gold", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=2, - groupcaps = mcl_autogroup.get_groupcaps { - pickaxey = { tool_multiplier = 12, level = 2, uses = 33 } - }, damage_groups = {fleshy=2}, punch_attack_uses = 17, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + pickaxey = { tool_multiplier = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:pick_diamond", { description = S("Diamond Pickaxe"), @@ -165,15 +168,15 @@ minetest.register_tool("mcl_tools:pick_diamond", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=5, - groupcaps = mcl_autogroup.get_groupcaps { - pickaxey = { tool_multiplier = 8, level = 5, uses = 1562 } - }, damage_groups = {fleshy=5}, punch_attack_uses = 781, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + pickaxey = { tool_multiplier = 8, level = 5, uses = 1562 } + }, }) local get_shovel_dig_group = function(itemstack) @@ -287,9 +290,6 @@ minetest.register_tool("mcl_tools:shovel_wood", { tool_capabilities = { full_punch_interval = 1, max_drop_level=1, - groupcaps = mcl_autogroup.get_groupcaps { - shovely = { tool_multiplier = 2, level = 1, uses = 60 } - }, damage_groups = {fleshy=2}, punch_attack_uses = 30, }, @@ -297,6 +297,9 @@ minetest.register_tool("mcl_tools:shovel_wood", { sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + shovely = { tool_multiplier = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:shovel_stone", { description = S("Stone Shovel"), @@ -308,9 +311,6 @@ minetest.register_tool("mcl_tools:shovel_stone", { tool_capabilities = { full_punch_interval = 1, max_drop_level=3, - groupcaps = mcl_autogroup.get_groupcaps { - shovely = { tool_multiplier = 4, level = 3, uses = 132 } - }, damage_groups = {fleshy=3}, punch_attack_uses = 66, }, @@ -318,6 +318,9 @@ minetest.register_tool("mcl_tools:shovel_stone", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + shovely = { tool_multiplier = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:shovel_iron", { description = S("Iron Shovel"), @@ -329,9 +332,6 @@ minetest.register_tool("mcl_tools:shovel_iron", { tool_capabilities = { full_punch_interval = 1, max_drop_level=4, - groupcaps = mcl_autogroup.get_groupcaps { - shovely = { tool_multiplier = 6, level = 4, uses = 251 } - }, damage_groups = {fleshy=4}, punch_attack_uses = 126, }, @@ -339,6 +339,9 @@ minetest.register_tool("mcl_tools:shovel_iron", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + shovely = { tool_multiplier = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:shovel_gold", { description = S("Golden Shovel"), @@ -350,9 +353,6 @@ minetest.register_tool("mcl_tools:shovel_gold", { tool_capabilities = { full_punch_interval = 1, max_drop_level=2, - groupcaps = mcl_autogroup.get_groupcaps { - shovely = { tool_multiplier = 12, level = 2, uses = 33 } - }, damage_groups = {fleshy=2}, punch_attack_uses = 17, }, @@ -360,6 +360,9 @@ minetest.register_tool("mcl_tools:shovel_gold", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + shovely = { tool_multiplier = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:shovel_diamond", { description = S("Diamond Shovel"), @@ -371,9 +374,6 @@ minetest.register_tool("mcl_tools:shovel_diamond", { tool_capabilities = { full_punch_interval = 1, max_drop_level=5, - groupcaps = mcl_autogroup.get_groupcaps { - shovely = { tool_multiplier = 8, level = 5, uses = 1562 } - }, damage_groups = {fleshy=5}, punch_attack_uses = 781, }, @@ -381,6 +381,9 @@ minetest.register_tool("mcl_tools:shovel_diamond", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + shovely = { tool_multiplier = 8, level = 5, uses = 1562 } + }, }) -- Axes @@ -394,15 +397,15 @@ minetest.register_tool("mcl_tools:axe_wood", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=1, - groupcaps = mcl_autogroup.get_groupcaps { - axey = { tool_multiplier = 2, level = 1, uses = 60 } - }, damage_groups = {fleshy=7}, punch_attack_uses = 30, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + axey = { tool_multiplier = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:axe_stone", { description = S("Stone Axe"), @@ -413,15 +416,15 @@ minetest.register_tool("mcl_tools:axe_stone", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=3, - groupcaps = mcl_autogroup.get_groupcaps { - axey = { tool_multiplier = 4, level = 3, uses = 132 } - }, damage_groups = {fleshy=9}, punch_attack_uses = 66, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + axey = { tool_multiplier = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:axe_iron", { description = S("Iron Axe"), @@ -433,15 +436,15 @@ minetest.register_tool("mcl_tools:axe_iron", { -- 1/0.9 full_punch_interval = 1.11111111, max_drop_level=4, - groupcaps = mcl_autogroup.get_groupcaps { - axey = { tool_multiplier = 6, level = 4, uses = 251 } - }, damage_groups = {fleshy=9}, punch_attack_uses = 126, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + axey = { tool_multiplier = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:axe_gold", { description = S("Golden Axe"), @@ -452,15 +455,15 @@ minetest.register_tool("mcl_tools:axe_gold", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=2, - groupcaps = mcl_autogroup.get_groupcaps { - axey = { tool_multiplier = 12, level = 2, uses = 33 } - }, damage_groups = {fleshy=7}, punch_attack_uses = 17, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + axey = { tool_multiplier = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:axe_diamond", { description = S("Diamond Axe"), @@ -471,15 +474,15 @@ minetest.register_tool("mcl_tools:axe_diamond", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=5, - groupcaps = mcl_autogroup.get_groupcaps { - axey = { tool_multiplier = 8, level = 5, uses = 1562 } - }, damage_groups = {fleshy=9}, punch_attack_uses = 781, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + axey = { tool_multiplier = 8, level = 5, uses = 1562 } + }, }) -- Swords @@ -493,16 +496,16 @@ minetest.register_tool("mcl_tools:sword_wood", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=1, - groupcaps = mcl_autogroup.get_groupcaps { - swordy = { tool_multiplier = 2, level = 1, uses = 60 }, - swordy_cobweb = { tool_multiplier = 2, level = 1, uses = 60 } - }, damage_groups = {fleshy=4}, punch_attack_uses = 60, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + swordy = { tool_multiplier = 2, level = 1, uses = 60 }, + swordy_cobweb = { tool_multiplier = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:sword_stone", { description = S("Stone Sword"), @@ -513,16 +516,16 @@ minetest.register_tool("mcl_tools:sword_stone", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=3, - groupcaps = mcl_autogroup.get_groupcaps { - swordy = { tool_multiplier = 4, level = 3, uses = 132 }, - swordy_cobweb = { tool_multiplier = 4, level = 3, uses = 132 } - }, damage_groups = {fleshy=5}, punch_attack_uses = 132, }, sound = { breaks = "default_tool_breaks" }, _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 } + }, }) minetest.register_tool("mcl_tools:sword_iron", { description = S("Iron Sword"), @@ -533,16 +536,16 @@ minetest.register_tool("mcl_tools:sword_iron", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=4, - groupcaps = mcl_autogroup.get_groupcaps { - swordy = { tool_multiplier = 6, level = 4, uses = 251 }, - swordy_cobweb = { tool_multiplier = 6, level = 4, uses = 251 } - }, damage_groups = {fleshy=6}, punch_attack_uses = 251, }, sound = { breaks = "default_tool_breaks" }, _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 } + }, }) minetest.register_tool("mcl_tools:sword_gold", { description = S("Golden Sword"), @@ -553,16 +556,16 @@ minetest.register_tool("mcl_tools:sword_gold", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=2, - groupcaps = mcl_autogroup.get_groupcaps { - swordy = { tool_multiplier = 12, level = 2, uses = 33 }, - swordy_cobweb = { tool_multiplier = 12, level = 2, uses = 33 } - }, damage_groups = {fleshy=4}, punch_attack_uses = 33, }, sound = { breaks = "default_tool_breaks" }, _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 } + }, }) minetest.register_tool("mcl_tools:sword_diamond", { description = S("Diamond Sword"), @@ -573,16 +576,16 @@ minetest.register_tool("mcl_tools:sword_diamond", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=5, - groupcaps = mcl_autogroup.get_groupcaps { - swordy = { tool_multiplier = 8, level = 5, uses = 1562 }, - swordy_cobweb = { tool_multiplier = 8, level = 5, uses = 1562 } - }, damage_groups = {fleshy=7}, punch_attack_uses = 1562, }, sound = { breaks = "default_tool_breaks" }, _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 } + }, }) --Shears @@ -597,15 +600,15 @@ minetest.register_tool("mcl_tools:shears", { tool_capabilities = { full_punch_interval = 0.5, max_drop_level=1, - groupcaps = mcl_autogroup.get_groupcaps { - shearsy = { tool_multiplier = 1.5, level = 1, uses = 238 }, - shearsy_wool = { tool_multiplier = 5, level = 1, uses = 238 }, - shearsy_cobweb = { tool_multiplier = 15, level = 1, uses = 238 } - }, }, on_place = carve_pumpkin, sound = { breaks = "default_tool_breaks" }, _mcl_toollike_wield = true, + _mcl_autogroup_groupcaps = { + shearsy = { tool_multiplier = 1.5, level = 1, uses = 238 }, + shearsy_wool = { tool_multiplier = 5, level = 1, uses = 238 }, + shearsy_cobweb = { tool_multiplier = 15, level = 1, uses = 238 } + }, }) From fa86d4e5ebc8dc5ecd4241a8a6291649f7b8c390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 18 Mar 2021 11:34:20 +0100 Subject: [PATCH 03/25] Change comments for mcl_autogroup --- mods/CORE/_mcl_autogroup/init.lua | 11 ++++++----- mods/CORE/mcl_autogroup/init.lua | 13 +++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 788cb1164..92c4f4c1d 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -44,10 +44,11 @@ See "mcl_tools/init.lua" for examples of this. Information about the mod ========================= -The mod is also split up into two mods, mcl_autogroups and _mcl_autogroups. -mcl_autogroups contains the API functions used to register custom digging -groups. _mcl_autogroups contains parts of the mod which need to be executed -after loading all other mods. +The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. +mcl_autogroup contains the API functions used to register custom digging groups. +_mcl_autogroup contains most of the code. The leading underscore in the name +"_mcl_autogroup" is used to force Minetest to load that part of the mod as late +as possible. Minetest loads mods in reverse alphabetical order. --]] -- The groups which affect dig times @@ -269,7 +270,7 @@ local overwrite = function() for tname, tdef in pairs(minetest.registered_tools) do -- Assign groupcaps for digging the registered digging groups - -- depending on the _mcl_autogroups_groupcaps in the tool + -- depending on the _mcl_autogroup_groupcaps in the tool -- definition if tdef._mcl_autogroup_groupcaps then local toolcaps = table.copy(tdef.tool_capabilities) or {} diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua index ff1c90cd0..52ec81505 100644 --- a/mods/CORE/mcl_autogroup/init.lua +++ b/mods/CORE/mcl_autogroup/init.lua @@ -1,11 +1,12 @@ --[[ -This mod implements the API to register digging groups for mcl_autogroups. The -rest of the mod is implemented and documented in the mod "_mcl_autogroup". +This mod implements the API to register digging groups for mcl_autogroup. The +rest of the mod is implemented and documented in the mod _mcl_autogroup. -The mcl_autogroups mod is split up into two mods, mcl_autogroups and -_mcl_autogroups. mcl_autogroups contains the API functions used to register -custom digging groups. _mcl_autogroups contains parts of the mod which need to -be executed after loading all other mods. +The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. +mcl_autogroup contains the API functions used to register custom digging groups. +_mcl_autogroup contains most of the code. The leading underscore in the name +"_mcl_autogroup" is used to force Minetest to load that part of the mod as late +as possible. Minetest loads mods in reverse alphabetical order. --]] mcl_autogroup = {} mcl_autogroup.registered_digtime_groups = {} From 0c90dda04c013d8ba95ef82eee0e0263eb5f972c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 11 Mar 2021 15:06:30 +0100 Subject: [PATCH 04/25] Rename register_digtime_group to register_diggroup --- mods/CORE/_mcl_autogroup/init.lua | 29 ++++++++++++----------------- mods/CORE/mcl_autogroup/init.lua | 6 +++--- mods/ITEMS/mcl_core/init.lua | 20 ++++++++++---------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 92c4f4c1d..1d13c23a9 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -20,9 +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_digtime_group("pickaxey", { levels = 5 }) - mcl_autogroup.register_digtime_group("shovely") - mcl_autogroup.register_digtime_group("shovely") + mcl_autogroup.register_diggroup("pickaxey", { levels = 5 }) + mcl_autogroup.register_diggroup("shovely") + mcl_autogroup.register_diggroup("shovely") The first line registers "pickaxey" as a digging group. The "levels" field indicates that the digging group have 5 levels (in this case one for each @@ -51,24 +51,18 @@ _mcl_autogroup contains most of the code. The leading underscore in the name as possible. Minetest loads mods in reverse alphabetical order. --]] --- The groups which affect dig times -local basegroups = {} -for group, _ in pairs(mcl_autogroup.registered_digtime_groups) do - table.insert(basegroups, group) -end - -- Returns a table containing the unique "_mcl_hardness" for nodes belonging to --- each basegroup. +-- each diggroup. local function get_hardness_values_for_groups() local maps = {} local values = {} - for _, g in pairs(basegroups) do + for g, _ in pairs(mcl_autogroup.registered_diggroups) do maps[g] = {} values[g] = {} end for _, ndef in pairs(minetest.registered_nodes) do - for _, g in pairs(basegroups) do + for g, _ in pairs(mcl_autogroup.registered_diggroups) do if ndef.groups[g] ~= nil then maps[g][ndef._mcl_hardness or 0] = true end @@ -81,14 +75,14 @@ local function get_hardness_values_for_groups() end end - for _, g in pairs(basegroups) do + for g, _ in pairs(mcl_autogroup.registered_diggroups) do table.sort(values[g]) end return values end -- Returns a table containing a table indexed by "_mcl_hardness_value" to get --- its index in the list of unique hardnesses for each basegroup. +-- its index in the list of unique hardnesses for each diggroup. local function get_hardness_lookup_for_groups(hardness_values) map = {} for g, values in pairs(hardness_values) do @@ -117,7 +111,8 @@ local function compute_creativetimes(group) return creativetimes end --- Get the list of digging times for using a specific tool on a specific group. +-- Get the list of digging times for using a specific tool on a specific +-- diggroup. -- -- Parameters: -- group - the group which it is digging @@ -190,7 +185,7 @@ local function add_groupcaps(groupcaps, groupcaps_def) for g, capsdef in pairs(groupcaps_def) do local mult = capsdef.tool_multiplier or 1 local eff = capsdef.efficiency or 0 - local def = mcl_autogroup.registered_digtime_groups[g] + local def = mcl_autogroup.registered_diggroups[g] local level = capsdef.level or 1 local max_level = def.levels or 0 @@ -247,7 +242,7 @@ local overwrite = function() -- Assign groups used for digging this node depending on -- the registered digging groups - for g, gdef in pairs(mcl_autogroup.registered_digtime_groups) do + for g, gdef in pairs(mcl_autogroup.registered_diggroups) do local index = hardness_lookup[g][ndef._mcl_hardness] if ndef.groups[g] then if gdef.levels then diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua index 52ec81505..5068881c8 100644 --- a/mods/CORE/mcl_autogroup/init.lua +++ b/mods/CORE/mcl_autogroup/init.lua @@ -9,8 +9,8 @@ _mcl_autogroup contains most of the code. The leading underscore in the name as possible. Minetest loads mods in reverse alphabetical order. --]] mcl_autogroup = {} -mcl_autogroup.registered_digtime_groups = {} +mcl_autogroup.registered_diggroups = {} -function mcl_autogroup.register_digtime_group(group, def) - mcl_autogroup.registered_digtime_groups[group] = def or {} +function mcl_autogroup.register_diggroup(group, def) + mcl_autogroup.registered_diggroups[group] = def or {} end diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 91e82be6e..8ef964825 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -3,16 +3,16 @@ mcl_core = {} -- Repair percentage for toolrepair mcl_core.repair = 0.05 -mcl_autogroup.register_digtime_group("handy") -mcl_autogroup.register_digtime_group("pickaxey", { levels = 5 }) -mcl_autogroup.register_digtime_group("axey") -mcl_autogroup.register_digtime_group("shovely") -mcl_autogroup.register_digtime_group("shearsy") -mcl_autogroup.register_digtime_group("shearsy_wool") -mcl_autogroup.register_digtime_group("shearsy_cobweb") -mcl_autogroup.register_digtime_group("swordy") -mcl_autogroup.register_digtime_group("swordy_cobweb") -mcl_autogroup.register_digtime_group("creative_breakable") +mcl_autogroup.register_diggroup("handy") +mcl_autogroup.register_diggroup("pickaxey", { levels = 5 }) +mcl_autogroup.register_diggroup("axey") +mcl_autogroup.register_diggroup("shovely") +mcl_autogroup.register_diggroup("shearsy") +mcl_autogroup.register_diggroup("shearsy_wool") +mcl_autogroup.register_diggroup("shearsy_cobweb") +mcl_autogroup.register_diggroup("swordy") +mcl_autogroup.register_diggroup("swordy_cobweb") +mcl_autogroup.register_diggroup("creative_breakable") -- Load files local modpath = minetest.get_modpath("mcl_core") From 5b5a254b1afecc7c28048f81ee601f688e6f720e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 11 Mar 2021 15:11:11 +0100 Subject: [PATCH 05/25] Fix tool uses not being set in _mcl_autogroups --- mods/CORE/_mcl_autogroup/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 1d13c23a9..bd8e249c4 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -185,16 +185,17 @@ local function add_groupcaps(groupcaps, groupcaps_def) 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 if max_level > 0 then level = math.min(level, max_level) - groupcaps[g .. "_0_dig"] = get_groupcap(g, false, mult, eff) - groupcaps[g .. "_" .. level .. "_dig"] = get_groupcap(g, true, mult, eff) + 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) + groupcaps[g .. "_dig"] = get_groupcap(g, true, mult, eff, uses) end end return groupcaps From 503b3a81490a3a8b66db836d3c1574b0b9e8341e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 11 Mar 2021 21:07:51 +0100 Subject: [PATCH 06/25] Fix some nodes not being diggable Previously some nodes like "mcl_flowers:double_grass_top" would be undiggable. This was because they did not define _mcl_hardness and it was not defaulted to 0 in all parts of _mcl_autogroup. --- mods/CORE/_mcl_autogroup/init.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index bd8e249c4..e6e800aa1 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -244,7 +244,7 @@ local overwrite = function() -- Assign groups used for digging this node depending on -- the registered digging groups for g, gdef in pairs(mcl_autogroup.registered_diggroups) do - local index = hardness_lookup[g][ndef._mcl_hardness] + local index = hardness_lookup[g][ndef._mcl_hardness or 0] if ndef.groups[g] then if gdef.levels then newgroups[g .. "_0_dig"] = index @@ -252,7 +252,6 @@ local overwrite = function() newgroups[g .. "_" .. i .. "_dig"] = index end else - local index = hardness_lookup[g][ndef._mcl_hardness] newgroups[g .. "_dig"] = index end end From f0528b11d78f46031f39239930d79cb5c7f5d42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 11 Mar 2021 21:52:00 +0100 Subject: [PATCH 07/25] Make mcl_enchanting use the new mcl_autogroups The function mcl_autogroups.get_groupcaps is used by mods to get the groupcaps for tools with efficiency enchantments. This function is used by mcl_enchanting when enchanting tools with efficiency. --- mods/CORE/_mcl_autogroup/init.lua | 76 ++++++++++++++-------- mods/CORE/mcl_autogroup/init.lua | 10 +++ mods/ITEMS/mcl_enchanting/enchantments.lua | 8 +-- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index e6e800aa1..cf7e53112 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -157,30 +157,6 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) } end --- Get the groupcaps for a tool on the specified digging groups. groupcaps_def --- contains a table with keys being the digging group and values being the tools --- properties for that digging group. --- --- The tool properties can have the following values: --- --- tool_multiplier - the digging speed multiplier for this tool (default 1) --- efficiency - the efficiency level for this tool (default 0) --- level - the maximum level of the group the tool can harvest (default 1) --- uses - the number of uses the tool has for this group --- --- A level of 0 means that the tool will be able to dig that group but will --- never be able to harvest the nodes of that group and will always get a --- digging time penalty. This is useful for implementing the hand. --- --- Example usage: --- --- mcl_autogroup.get_groupcaps { --- pickaxey = { tool_multiplier = 4, level = 3, uses = 132 } --- } --- --- This computes the groupcaps for a tool mining "pickaxey" blocks. The tool --- has a digging speed multiplier of 4, can mine nodes of level >= 3 and has 132 --- uses. local function add_groupcaps(groupcaps, groupcaps_def) for g, capsdef in pairs(groupcaps_def) do local mult = capsdef.tool_multiplier or 1 @@ -224,6 +200,54 @@ function mcl_autogroup.can_harvest(nodename, tool_capabilities) return false end +-- Get one groupcap field for using a specific tool on a specific group. +local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) + return { + times = get_digtimes(group, can_harvest, multiplier, efficiency), + uses = uses, + maxlevel = 0, + } +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. +-- +-- Parameters: +-- tool_name - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") +-- efficiency - The efficiency level the tool is enchanted with (default 0) +-- +-- NOTE: +-- Mods calling this function (like mcl_enchanting) should _not_ have +-- _mcl_autogroups as a dependency. It is very important that this mod is +-- loaded last. This also means this function can only be called by other mods +-- after all mods have been initialized. +function mcl_autogroup.get_groupcaps(tool_name, efficiency) + local tdef = minetest.registered_tools[tool_name] + local groupcaps = table.copy(tdef.tool_capabilities.groupcaps or {}) + add_groupcaps(groupcaps, tdef._mcl_autogroup_groupcaps, efficiency) + return groupcaps +end + local overwrite = function() for nname, ndef in pairs(minetest.registered_nodes) do local newgroups = table.copy(ndef.groups) @@ -269,9 +293,7 @@ local overwrite = function() -- definition if tdef._mcl_autogroup_groupcaps then local toolcaps = table.copy(tdef.tool_capabilities) or {} - local groupcaps = toolcaps.groupcaps or {} - groupcaps = add_groupcaps(groupcaps, tdef._mcl_autogroup_groupcaps) - toolcaps.groupcaps = groupcaps + toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname) minetest.override_item(tname, { tool_capabilities = toolcaps diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua index 5068881c8..0bbc44495 100644 --- a/mods/CORE/mcl_autogroup/init.lua +++ b/mods/CORE/mcl_autogroup/init.lua @@ -11,6 +11,16 @@ as possible. Minetest loads mods in reverse alphabetical order. mcl_autogroup = {} mcl_autogroup.registered_diggroups = {} +-- Register a group as a digging group. +-- +-- Parameters: +-- group - Name of the group to register as a digging group +-- 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. function mcl_autogroup.register_diggroup(group, def) mcl_autogroup.registered_diggroups[group] = def or {} end diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 893ce58d4..44eeeef11 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -156,13 +156,7 @@ mcl_enchanting.enchantments.efficiency = { curse = false, on_enchant = function(itemstack, level) local tool_capabilities = itemstack:get_tool_capabilities() - local groupcaps = {} - for group, capability in pairs(tool_capabilities.groupcaps) do - local groupname = group .. "_efficiency_" .. level - capability.times = mcl_autogroup.digtimes[groupname] - groupcaps[groupname] = capability - end - tool_capabilities.groupcaps = groupcaps + tool_capabilities.groupcaps = mcl_autogroup.get_groupcaps(itemstack:get_name(), level) itemstack:get_meta():set_tool_capabilities(tool_capabilities) end, requires_tool = false, From b47733507d585f68cbea8bf4568f848554cabc09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 18 Mar 2021 11:35:29 +0100 Subject: [PATCH 08/25] Fix tools not taking wear when rightclicking Added the API function mcl_autogroup.get_wear which is used to get the tool wear for digging a node of a group. This is used by mcl_tools to compute the wear of shovels and shears when rightclicking to create grass paths and carve pumpkins. --- mods/CORE/_mcl_autogroup/init.lua | 32 ++++++++++++++++++++------ mods/ITEMS/mcl_tools/init.lua | 37 +++---------------------------- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index cf7e53112..b834441a2 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -49,6 +49,9 @@ mcl_autogroup contains the API functions used to register custom digging groups. _mcl_autogroup contains most of the code. The leading underscore in the name "_mcl_autogroup" is used to force Minetest to load that part of the mod as late as possible. Minetest loads mods in reverse alphabetical order. + +This also means that it is very important that no mod adds _mcl_autogroups as a +dependency. --]] -- Returns a table containing the unique "_mcl_hardness" for nodes belonging to @@ -233,21 +236,36 @@ end -- or in the metadata of an enchanted tool. -- -- Parameters: --- tool_name - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") +-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") -- efficiency - The efficiency level the tool is enchanted with (default 0) -- -- NOTE: --- Mods calling this function (like mcl_enchanting) should _not_ have --- _mcl_autogroups as a dependency. It is very important that this mod is --- loaded last. This also means this function can only be called by other mods --- after all mods have been initialized. -function mcl_autogroup.get_groupcaps(tool_name, efficiency) - local tdef = minetest.registered_tools[tool_name] +-- This function can only be called after mod initialization. Otherwise a mod +-- would have to add _mcl_autogroup as a dependency which would break the mod +-- loading order. +function mcl_autogroup.get_groupcaps(toolname, efficiency) + local tdef = minetest.registered_tools[toolname] local groupcaps = table.copy(tdef.tool_capabilities.groupcaps or {}) add_groupcaps(groupcaps, tdef._mcl_autogroup_groupcaps, efficiency) return groupcaps end +-- Get the wear from using a tool on a digging group. +-- +-- Parameters +-- toolname - Name of the tool used +-- diggroup - The name of the diggroup the tool is used on +-- +-- NOTE: +-- This function can only be called after mod initialization. Otherwise a mod +-- would have to add _mcl_autogroup as a dependency which would break the mod +-- loading order. +function mcl_autogroup.get_wear(toolname, diggroup) + local tdef = minetest.registered_tools[toolname] + local uses = tdef._mcl_autogroup_groupcaps[diggroup].uses + return math.ceil(65535 / uses) +end + local overwrite = function() for nname, ndef in pairs(minetest.registered_nodes) do local newgroups = table.copy(ndef.groups) diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 85119d18a..2d3c41014 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -179,26 +179,6 @@ minetest.register_tool("mcl_tools:pick_diamond", { }, }) -local get_shovel_dig_group = function(itemstack) - local itemstring = itemstack:get_name() - local efficiency_level = mcl_enchanting.get_enchantment(itemstack, "efficiency") - local postfix = efficiency_level > 0 and "_efficiency_" .. efficiency_level or "" - if itemstring:find("mcl_tools:shovel_wood") == 1 then - return "shovely_dig_wood" .. postfix - elseif itemstring:find("mcl_tools:shovel_stone") == 1 then - return "shovely_dig_stone" .. postfix - elseif itemstring:find("mcl_tools:shovel_iron") == 1 then - return "shovely_dig_iron" .. postfix - elseif itemstring:find("mcl_tools:shovel_gold") == 1 then - return "shovely_dig_gold" .. postfix - elseif itemstring:find("mcl_tools:shovel_diamond") == 1 then - return "shovely_dig_diamond" .. postfix - else - -- Fallback - return "shovely_dig_wood" - end -end - local make_grass_path = function(itemstack, placer, pointed_thing) -- Use pointed node's on_rightclick function first, if present local node = minetest.get_node(pointed_thing.under) @@ -223,15 +203,9 @@ local make_grass_path = function(itemstack, placer, pointed_thing) end if not minetest.is_creative_enabled(placer:get_player_name()) then - -- Add wear, as if digging a level 0 shovely node + -- Add wear (as if digging a shovely node) local toolname = itemstack:get_name() - local def = minetest.registered_items[toolname] - local group = get_shovel_dig_group(itemstack) - local toolcaps = itemstack:get_tool_capabilities() - local base_uses = toolcaps.groupcaps[group].uses - local maxlevel = toolcaps.groupcaps[group].maxlevel - local uses = base_uses * math.pow(3, maxlevel) - local wear = math.ceil(65535 / uses) + local wear = mcl_autogroup.get_wear(toolname, "shovely") itemstack:add_wear(wear) end minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) @@ -260,12 +234,7 @@ if minetest.get_modpath("mcl_farming") then if not minetest.is_creative_enabled(placer:get_player_name()) then -- Add wear (as if digging a shearsy node) local toolname = itemstack:get_name() - local def = minetest.registered_items[toolname] - local group = get_shovel_dig_group(toolname) - local base_uses = def.tool_capabilities.groupcaps["shearsy_dig"].uses - local maxlevel = def.tool_capabilities.groupcaps["shearsy_dig"].maxlevel - local uses = base_uses * math.pow(3, maxlevel) - local wear = math.ceil(65535 / uses) + local wear = mcl_autogroup.get_wear(toolname, "shearsy") itemstack:add_wear(wear) end minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) From 3241dbbec512c41941d508de6765376d91a9eef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Mon, 15 Mar 2021 17:58:26 +0100 Subject: [PATCH 09/25] Update enchanted tools with outdated digging times Because of the way digging times is implemented in Mineclone2, it is possible for the digging times of efficiency enchanted tools to become outdated. This fixes that by automatically updating the tools tool_capabilities after each time the tool is used. --- mods/ITEMS/mcl_enchanting/engine.lua | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index e6f98fada..6f6633ed8 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -219,6 +219,43 @@ function mcl_enchanting.enchantments_snippet(_, _, itemstack) end end +-- Returns after_use callback function for enchanted items. The after_use +-- callback is used to check the tool_capabilities of enchanted tools to update +-- old enchanted tools with outdated digtimes in their tool_capabilities. +-- +-- This is neccessary for digging times of tools to be in sync when MineClone2 +-- or mods change add new hardness values for nodes or when existing hardness +-- values are changed. +local function get_after_use_callback(itemdef) + if itemdef.after_use then + -- If the tool already has an after_use, make sure to call that + -- one too. + return function(itemstack, user, node, digparams) + itemdef.after_use(itemstack, user, node, digparams) + + local enchantments = mcl_enchanting.get_enchantments(itemstack) + local level = enchantments.efficiency + if level then + mcl_enchanting.enchantments.efficiency.on_enchant(itemstack, level) + end + end + end + + -- If the tool does not have after_use, add wear to the tool as if no + -- after_use was registered. + return function(itemstack, user, node, digparams) + if not minetest.is_creative_enabled(user) then + itemstack:add_wear(digparams.wear) + end + + local enchantments = mcl_enchanting.get_enchantments(itemstack) + local level = enchantments.efficiency + if level then + mcl_enchanting.enchantments.efficiency.on_enchant(itemstack, level) + end + end +end + function mcl_enchanting.initialize() local register_tool_list = {} local register_item_list = {} @@ -236,6 +273,7 @@ function mcl_enchanting.initialize() new_def.groups.enchanted = 1 new_def.texture = itemdef.texture or itemname:gsub("%:", "_") new_def._mcl_enchanting_enchanted_tool = new_name + new_def.after_use = get_after_use_callback(itemdef) local register_list = register_item_list if itemdef.type == "tool" then register_list = register_tool_list From 922bdbc6014c0dad3cc4ec38188c3dd0857517cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Mon, 15 Mar 2021 19:32:43 +0100 Subject: [PATCH 10/25] Use hashing for more efficient groupcaps updating This adds the metadata field "groupcaps_hash" to tools enchanted with efficiency. This value contains a hash of the groupcaps field in tool_capabilities. This value gets compared to the expected hash value to determine if the tools tool_capabilities should be updated according to commit af31f8189e8e5c2b. This commit makes efficiency more efficient. --- mods/CORE/mcl_util/init.lua | 8 +++ mods/ITEMS/mcl_enchanting/enchantments.lua | 4 +- mods/ITEMS/mcl_enchanting/engine.lua | 60 ++++++++++++++++++++-- 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 6c63c21ab..408189d14 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -405,3 +405,11 @@ function mcl_util.get_object_center(obj) pos.y = pos.y + (ymax - ymin) / 2.0 return pos end + +-- Compute a hash value. +function mcl_util.hash(value) + -- minetest.get_password_hash is quite fast, even if it uses a + -- cryptographic hashing function (SHA-1). It is written in C++ and it + -- is probably hard to write a faster hashing function in Lua. + return minetest.get_password_hash("ryvnf", minetest.serialize(value)) +end diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 44eeeef11..265bdb742 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -155,9 +155,7 @@ mcl_enchanting.enchantments.efficiency = { description = S("Increases mining speed."), curse = false, on_enchant = function(itemstack, level) - local tool_capabilities = itemstack:get_tool_capabilities() - tool_capabilities.groupcaps = mcl_autogroup.get_groupcaps(itemstack:get_name(), level) - itemstack:get_meta():set_tool_capabilities(tool_capabilities) + mcl_enchanting.apply_efficiency(itemstack, level) end, requires_tool = false, treasure = false, diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 6f6633ed8..72cdbba5f 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -1,6 +1,53 @@ local S = minetest.get_translator("mcl_enchanting") local F = minetest.formspec_escape +local efficiency_cache_table = {} + +-- Get the efficiency groupcaps and hash for a tool and efficiency level. If +-- this function is called repeatedly with the same values it will return data +-- from a cache. +-- +-- Returns a table with the following two fields: +-- values - the groupcaps table +-- hash - the hash of the groupcaps table +local function get_efficiency_groupcaps(toolname, level) + local toolcache = efficiency_cache_table[toolname] + if not toolcache then + toolcache = {} + efficiency_cache_table[toolname] = toolcache + end + + local levelcache = toolcache[level] + if not levelcache then + levelcache = {} + levelcache.values = mcl_autogroup.get_groupcaps(toolname, level) + levelcache.hash = mcl_util.hash(levelcache.values) + toolcache[level] = levelcache + end + + return levelcache +end + +-- Apply efficiency enchantment to a tool. This will update the tools +-- tool_capabilities to give it new digging times. This function will be called +-- repeatedly to make sure the digging times stored in groupcaps stays in sync +-- when the digging times of nodes can change. +-- +-- To make it more efficient it will first check a hash value to determine if +-- the tool needs to be updated. +function mcl_enchanting.apply_efficiency(itemstack, level) + local name = itemstack:get_name() + local groupcaps = get_efficiency_groupcaps(name, level) + local hash = itemstack:get_meta():get_string("groupcaps_hash") + + if not hash or hash ~= groupcaps.hash then + local tool_capabilities = itemstack:get_tool_capabilities() + tool_capabilities.groupcaps = groupcaps.values + itemstack:get_meta():set_tool_capabilities(tool_capabilities) + itemstack:get_meta():set_string("groupcaps_hash", groupcaps.hash) + end +end + function mcl_enchanting.is_book(itemname) return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or itemname == "mcl_books:book_enchanted" end @@ -219,13 +266,16 @@ function mcl_enchanting.enchantments_snippet(_, _, itemstack) end end --- Returns after_use callback function for enchanted items. The after_use --- callback is used to check the tool_capabilities of enchanted tools to update --- old enchanted tools with outdated digtimes in their tool_capabilities. +-- Returns the after_use callback function to use when registering an enchanted +-- item. The after_use callback is used to update the tool_capabilities of +-- efficiency enchanted tools with outdated digging times. +-- +-- It does this by calling apply_efficiency to reapply the efficiency +-- enchantment. That function is written to use hash values to only update the +-- tool if neccessary. -- -- This is neccessary for digging times of tools to be in sync when MineClone2 --- or mods change add new hardness values for nodes or when existing hardness --- values are changed. +-- or mods add new hardness values. local function get_after_use_callback(itemdef) if itemdef.after_use then -- If the tool already has an after_use, make sure to call that From e77473e800027d01c6eb9e6da7425595233bd9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Mon, 15 Mar 2021 21:55:59 +0100 Subject: [PATCH 11/25] 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. --- mods/CORE/_mcl_autogroup/init.lua | 91 +++++++++++++------------- mods/CORE/mcl_autogroup/init.lua | 6 +- mods/ENTITIES/mcl_item_entity/init.lua | 11 ++-- mods/ITEMS/mcl_core/init.lua | 4 +- mods/ITEMS/mcl_tools/init.lua | 68 ++++++++++--------- 5 files changed, 94 insertions(+), 86 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index b834441a2..5e0e4d928 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -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 - if ndef.groups[g] then - if not string.find(g, "_0_dig$") and string.find(g, "_dig$") then - return true + -- 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 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 diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua index 0bbc44495..d02196c89 100644 --- a/mods/CORE/mcl_autogroup/init.lua +++ b/mods/CORE/mcl_autogroup/init.lua @@ -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 diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index f0aa289f2..28981fa7c 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -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 diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 8ef964825..aae6abe9a 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -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") diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 2d3c41014..3e5ea1452 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -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 } }, }) From 51937306525c2121af9673aa906f4b9dc615a55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 12:09:24 +0100 Subject: [PATCH 12/25] Truncate groupcaps_hash to 8 Base64 digits --- mods/CORE/mcl_util/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 408189d14..bac919a80 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -411,5 +411,5 @@ function mcl_util.hash(value) -- minetest.get_password_hash is quite fast, even if it uses a -- cryptographic hashing function (SHA-1). It is written in C++ and it -- is probably hard to write a faster hashing function in Lua. - return minetest.get_password_hash("ryvnf", minetest.serialize(value)) + return string.sub(minetest.get_password_hash("ryvnf", minetest.serialize(value)), 1, 8) end From 2e9b3c2259e4abe2f1a4fc7bf15f39b0a452d38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 12:21:42 +0100 Subject: [PATCH 13/25] Move efficiency code to its own file --- mods/ITEMS/mcl_enchanting/efficiency.lua | 46 ++++++++++++++++++++++ mods/ITEMS/mcl_enchanting/engine.lua | 49 +----------------------- mods/ITEMS/mcl_enchanting/init.lua | 1 + 3 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 mods/ITEMS/mcl_enchanting/efficiency.lua diff --git a/mods/ITEMS/mcl_enchanting/efficiency.lua b/mods/ITEMS/mcl_enchanting/efficiency.lua new file mode 100644 index 000000000..afb97bfc4 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/efficiency.lua @@ -0,0 +1,46 @@ +local efficiency_cache_table = {} + +-- Get the efficiency groupcaps and hash for a tool and efficiency level. If +-- this function is called repeatedly with the same values it will return data +-- from a cache. +-- +-- Returns a table with the following two fields: +-- values - the groupcaps table +-- hash - the hash of the groupcaps table +local function get_efficiency_groupcaps(toolname, level) + local toolcache = efficiency_cache_table[toolname] + if not toolcache then + toolcache = {} + efficiency_cache_table[toolname] = toolcache + end + + local levelcache = toolcache[level] + if not levelcache then + levelcache = {} + levelcache.values = mcl_autogroup.get_groupcaps(toolname, level) + levelcache.hash = mcl_util.hash(levelcache.values) + toolcache[level] = levelcache + end + + return levelcache +end + +-- Apply efficiency enchantment to a tool. This will update the tools +-- tool_capabilities to give it new digging times. This function will be called +-- repeatedly to make sure the digging times stored in groupcaps stays in sync +-- when the digging times of nodes can change. +-- +-- To make it more efficient it will first check a hash value to determine if +-- the tool needs to be updated. +function mcl_enchanting.apply_efficiency(itemstack, level) + local name = itemstack:get_name() + local groupcaps = get_efficiency_groupcaps(name, level) + local hash = itemstack:get_meta():get_string("groupcaps_hash") + + if not hash or hash ~= groupcaps.hash then + local tool_capabilities = itemstack:get_tool_capabilities() + tool_capabilities.groupcaps = groupcaps.values + itemstack:get_meta():set_tool_capabilities(tool_capabilities) + itemstack:get_meta():set_string("groupcaps_hash", groupcaps.hash) + end +end diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 72cdbba5f..acde352b7 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -1,53 +1,6 @@ local S = minetest.get_translator("mcl_enchanting") local F = minetest.formspec_escape -local efficiency_cache_table = {} - --- Get the efficiency groupcaps and hash for a tool and efficiency level. If --- this function is called repeatedly with the same values it will return data --- from a cache. --- --- Returns a table with the following two fields: --- values - the groupcaps table --- hash - the hash of the groupcaps table -local function get_efficiency_groupcaps(toolname, level) - local toolcache = efficiency_cache_table[toolname] - if not toolcache then - toolcache = {} - efficiency_cache_table[toolname] = toolcache - end - - local levelcache = toolcache[level] - if not levelcache then - levelcache = {} - levelcache.values = mcl_autogroup.get_groupcaps(toolname, level) - levelcache.hash = mcl_util.hash(levelcache.values) - toolcache[level] = levelcache - end - - return levelcache -end - --- Apply efficiency enchantment to a tool. This will update the tools --- tool_capabilities to give it new digging times. This function will be called --- repeatedly to make sure the digging times stored in groupcaps stays in sync --- when the digging times of nodes can change. --- --- To make it more efficient it will first check a hash value to determine if --- the tool needs to be updated. -function mcl_enchanting.apply_efficiency(itemstack, level) - local name = itemstack:get_name() - local groupcaps = get_efficiency_groupcaps(name, level) - local hash = itemstack:get_meta():get_string("groupcaps_hash") - - if not hash or hash ~= groupcaps.hash then - local tool_capabilities = itemstack:get_tool_capabilities() - tool_capabilities.groupcaps = groupcaps.values - itemstack:get_meta():set_tool_capabilities(tool_capabilities) - itemstack:get_meta():set_string("groupcaps_hash", groupcaps.hash) - end -end - function mcl_enchanting.is_book(itemname) return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or itemname == "mcl_books:book_enchanted" end @@ -286,7 +239,7 @@ local function get_after_use_callback(itemdef) local enchantments = mcl_enchanting.get_enchantments(itemstack) local level = enchantments.efficiency if level then - mcl_enchanting.enchantments.efficiency.on_enchant(itemstack, level) + mcl_enchanting.apply_efficiency(itemstack, level) end end end diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index a53350a70..45faa498b 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -59,6 +59,7 @@ mcl_enchanting = { } dofile(modpath .. "/engine.lua") +dofile(modpath .. "/efficiency.lua") dofile(modpath .. "/enchantments.lua") minetest.register_chatcommand("enchant", { From 6458565bf9a4f9040bda5e8ca32e292d128c6b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 16:57:50 +0100 Subject: [PATCH 14/25] Move mcl_util.hash to a local function It is probably unlikely it will be useful at other places in Mineclone2. --- mods/CORE/mcl_util/init.lua | 8 -------- mods/ITEMS/mcl_enchanting/efficiency.lua | 10 +++++++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index bac919a80..6c63c21ab 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -405,11 +405,3 @@ function mcl_util.get_object_center(obj) pos.y = pos.y + (ymax - ymin) / 2.0 return pos end - --- Compute a hash value. -function mcl_util.hash(value) - -- minetest.get_password_hash is quite fast, even if it uses a - -- cryptographic hashing function (SHA-1). It is written in C++ and it - -- is probably hard to write a faster hashing function in Lua. - return string.sub(minetest.get_password_hash("ryvnf", minetest.serialize(value)), 1, 8) -end diff --git a/mods/ITEMS/mcl_enchanting/efficiency.lua b/mods/ITEMS/mcl_enchanting/efficiency.lua index afb97bfc4..d4b06e5fb 100644 --- a/mods/ITEMS/mcl_enchanting/efficiency.lua +++ b/mods/ITEMS/mcl_enchanting/efficiency.lua @@ -1,5 +1,13 @@ local efficiency_cache_table = {} +-- Compute a hash value. +function compute_hash(value) + -- minetest.get_password_hash is quite fast, even if it uses a + -- cryptographic hashing function (SHA-1). It is written in C++ and it + -- is probably hard to write a faster hashing function in Lua. + return string.sub(minetest.get_password_hash("ryvnf", minetest.serialize(value)), 1, 8) +end + -- Get the efficiency groupcaps and hash for a tool and efficiency level. If -- this function is called repeatedly with the same values it will return data -- from a cache. @@ -18,7 +26,7 @@ local function get_efficiency_groupcaps(toolname, level) if not levelcache then levelcache = {} levelcache.values = mcl_autogroup.get_groupcaps(toolname, level) - levelcache.hash = mcl_util.hash(levelcache.values) + levelcache.hash = compute_hash(levelcache.values) toolcache[level] = levelcache end From bec1f786a61ac655ee8312f35146b774a1b0e1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 16:10:57 +0100 Subject: [PATCH 15/25] Improve documentation of mcl_autogroup --- API.md | 4 +++ mods/CORE/_mcl_autogroup/init.lua | 47 ++++++++++++++++++++----------- mods/CORE/mcl_autogroup/init.lua | 10 +++---- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/API.md b/API.md index 344414b72..131effe4d 100644 --- a/API.md +++ b/API.md @@ -17,6 +17,10 @@ Items can have these fields: anvil. See `mcl_banners` for an example. +Tools can have these fields: +* `_mcl_autogroup_groupcaps`: Specifies the digging groups that a tool can dig + and how efficiently. See `_mcl_autogroup` for more information. + All nodes can have these fields: * `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0 diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 5e0e4d928..503cd3b89 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -16,32 +16,46 @@ information. How the mod is used =================== -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: +In MineClone 2, all diggable nodes have the hardness set in the custom field +"_mcl_hardness" (0 by default). These values are used together with digging +groups by this mod to create the correct digging times for nodes. Digging +groups are registered using the following code: + mcl_autogroup.register_diggroup("shovely") mcl_autogroup.register_diggroup("pickaxey", { levels = { "wood", "gold", "stone", "iron", "diamond" } }) - mcl_autogroup.register_diggroup("shovely") - mcl_autogroup.register_diggroup("shovely") -The first line registers "pickaxey" as a digging group. The "levels" field -indicates that the digging group have 5 levels (in this case one for each -material of a pickaxe). The second line registers "shovely" as a digging group -which does not have separate levels (if the "levels" field is not set it -defaults to 0). +The first line registers a simple digging group. The second line registers a +digging group with 5 different levels (in this case one for each material of a +pickaxes). 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=4 because it requires a -pickaxe of level 4 ("stone") to be mined. +pickaxe of level 4 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. -See "mcl_tools/init.lua" for examples of this. +For tools to be able to dig nodes of digging groups they need to use the have +the custom field "_mcl_autogroup_groupcaps" function to get the groupcaps. The +value of this field is a table which defines which groups the tool can dig and +how efficiently. + + _mcl_autogroup_groupcaps = { + handy = { tool_multiplier = 1, level = 1, uses = 0 }, + pickaxey = { tool_multiplier = 1, level = 0, uses = 0 }, + } + +The "uses" field indicate how many uses (0 for infinite) a tool has when used on +the specified digging group. The "tool_multiplier" field is a multiplier to the +dig speed on that digging group. + +The "level" field indicates which levels of the group the tool can harvest. A +level of 0 means that the tool cannot harvest blocks of that node. A level of 1 +or above means that the tool can harvest nodes with that level or below. See +"mcl_tools/init.lua" for examples on how "_mcl_autogroup_groupcaps" is used in +practice. Information about the mod ========================= @@ -123,9 +137,8 @@ end -- group - the group which it is digging -- can_harvest - if the tool can harvest the block -- tool_multiplier - dig speed multiplier for tool (default 1) --- efficiency - efficiency level for the tool (default 0) +-- efficiency - efficiency level for the tool if applicable 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 then @@ -162,6 +175,8 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) } end +-- Add the groupcaps from a field in "_mcl_autogroup_groupcaps" to the groupcaps +-- of a tool. local function add_groupcaps(groupcaps, groupcaps_def, efficiency) for g, capsdef in pairs(groupcaps_def) do local mult = capsdef.tool_multiplier or 1 diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua index d02196c89..09894dd84 100644 --- a/mods/CORE/mcl_autogroup/init.lua +++ b/mods/CORE/mcl_autogroup/init.lua @@ -1,6 +1,7 @@ --[[ -This mod implements the API to register digging groups for mcl_autogroup. The -rest of the mod is implemented and documented in the mod _mcl_autogroup. +This is one part of a mod to replicate the digging times from Minecraft. This +part only exposes a function to register digging groups. The rest of the mod is +implemented and documented in the _mcl_autogroup. The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. mcl_autogroup contains the API functions used to register custom digging groups. @@ -18,9 +19,8 @@ mcl_autogroup.registered_diggroups = {} -- def - Table with information about the diggroup (defaults to {} if unspecified) -- -- Values in def: --- 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. +-- level - If specified 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 From ece4c892f451aea6acd72bb481f28db54bea3ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 20:19:19 +0100 Subject: [PATCH 16/25] Force tools to include levels in their diggroups --- mods/CORE/_mcl_autogroup/init.lua | 12 ++++++----- mods/ITEMS/mcl_tools/init.lua | 36 +++++++++++++++---------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 503cd3b89..db6effdda 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -177,13 +177,15 @@ end -- Add the groupcaps from a field in "_mcl_autogroup_groupcaps" to the groupcaps -- of a tool. -local function add_groupcaps(groupcaps, groupcaps_def, efficiency) +local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency) for g, capsdef in pairs(groupcaps_def) do local mult = capsdef.tool_multiplier or 1 local uses = capsdef.uses local def = mcl_autogroup.registered_diggroups[g] local max_level = def.levels and #def.levels or 1 - local level = math.min(capsdef.level or max_level, max_level) + + assert(capsdef.level, toolname .. ' is missing level for ' .. g) + local level = math.min(capsdef.level, max_level) if def.levels then groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses) @@ -211,7 +213,7 @@ function mcl_autogroup.can_harvest(nodename, toolname) 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 + if ndef.groups[g] <= gdef.level then return true end end @@ -223,7 +225,7 @@ function mcl_autogroup.can_harvest(nodename, toolname) 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 + if ndef.groups[g] <= gdef.level then return true end end @@ -257,7 +259,7 @@ end function mcl_autogroup.get_groupcaps(toolname, efficiency) local tdef = minetest.registered_tools[toolname] local groupcaps = table.copy(tdef.tool_capabilities.groupcaps or {}) - add_groupcaps(groupcaps, tdef._mcl_autogroup_groupcaps, efficiency) + add_groupcaps(toolname, groupcaps, tdef._mcl_autogroup_groupcaps, efficiency) return groupcaps end diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 3e5ea1452..dfe872adb 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -273,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, uses = 60 } + shovely = { tool_multiplier = 2, level = 1, uses = 60 } }, }) minetest.register_tool("mcl_tools:shovel_stone", { @@ -294,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, uses = 132 } + shovely = { tool_multiplier = 4, level = 3, uses = 132 } }, }) minetest.register_tool("mcl_tools:shovel_iron", { @@ -315,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, uses = 251 } + shovely = { tool_multiplier = 6, level = 4, uses = 251 } }, }) minetest.register_tool("mcl_tools:shovel_gold", { @@ -336,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, uses = 33 } + shovely = { tool_multiplier = 12, level = 2, uses = 33 } }, }) minetest.register_tool("mcl_tools:shovel_diamond", { @@ -357,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, uses = 1562 } + shovely = { tool_multiplier = 8, level = 5, uses = 1562 } }, }) @@ -379,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, uses = 60 } + axey = { tool_multiplier = 2, level = 1, uses = 60 } }, }) minetest.register_tool("mcl_tools:axe_stone", { @@ -398,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, uses = 132 } + axey = { tool_multiplier = 4, level = 3, uses = 132 } }, }) minetest.register_tool("mcl_tools:axe_iron", { @@ -418,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, uses = 251 } + axey = { tool_multiplier = 6, level = 4, uses = 251 } }, }) minetest.register_tool("mcl_tools:axe_gold", { @@ -437,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, uses = 33 } + axey = { tool_multiplier = 12, level = 2, uses = 33 } }, }) minetest.register_tool("mcl_tools:axe_diamond", { @@ -456,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, uses = 1562 } + axey = { tool_multiplier = 8, level = 5, uses = 1562 } }, }) @@ -498,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 = 1, uses = 132 }, - swordy_cobweb = { tool_multiplier = 4, level = 1, uses = 132 } + swordy = { tool_multiplier = 4, level = 3, uses = 132 }, + swordy_cobweb = { tool_multiplier = 4, level = 3, uses = 132 } }, }) minetest.register_tool("mcl_tools:sword_iron", { @@ -518,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 = 1, uses = 251 }, - swordy_cobweb = { tool_multiplier = 6, level = 1, uses = 251 } + swordy = { tool_multiplier = 6, level = 4, uses = 251 }, + swordy_cobweb = { tool_multiplier = 6, level = 4, uses = 251 } }, }) minetest.register_tool("mcl_tools:sword_gold", { @@ -538,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 = 1, uses = 33 }, - swordy_cobweb = { tool_multiplier = 12, level = 1, uses = 33 } + swordy = { tool_multiplier = 12, level = 2, uses = 33 }, + swordy_cobweb = { tool_multiplier = 12, level = 2, uses = 33 } }, }) minetest.register_tool("mcl_tools:sword_diamond", { @@ -558,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 = 1, uses = 1562 }, - swordy_cobweb = { tool_multiplier = 8, level = 1, uses = 1562 } + swordy = { tool_multiplier = 8, level = 5, uses = 1562 }, + swordy_cobweb = { tool_multiplier = 8, level = 5, uses = 1562 } }, }) From 7b93f68ed82736e3a58ae6eb5151a09abd7dad6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 20:27:35 +0100 Subject: [PATCH 17/25] Fix typo --- mods/CORE/_mcl_autogroup/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index db6effdda..c01ba2692 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -66,7 +66,7 @@ _mcl_autogroup contains most of the code. The leading underscore in the name "_mcl_autogroup" is used to force Minetest to load that part of the mod as late as possible. Minetest loads mods in reverse alphabetical order. -This also means that it is very important that no mod adds _mcl_autogroups as a +This also means that it is very important that no mod adds _mcl_autogroup as a dependency. --]] From cff0130506322706f837c4495a156c4bf6b87b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Tue, 16 Mar 2021 20:36:38 +0100 Subject: [PATCH 18/25] Rename _mcl_autogroup_groupcaps to _mcl_diggroups --- API.md | 4 +-- mods/CORE/_mcl_autogroup/init.lua | 28 ++++++++-------- mods/ENTITIES/mcl_item_entity/init.lua | 2 +- mods/ITEMS/mcl_tools/init.lua | 44 +++++++++++++------------- 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/API.md b/API.md index 131effe4d..d82a2547a 100644 --- a/API.md +++ b/API.md @@ -18,8 +18,8 @@ Items can have these fields: See `mcl_banners` for an example. Tools can have these fields: -* `_mcl_autogroup_groupcaps`: Specifies the digging groups that a tool can dig - and how efficiently. See `_mcl_autogroup` for more information. +* `_mcl_diggroups`: Specifies the digging groups that a tool can dig and how + efficiently. See `_mcl_autogroup` for more information. All nodes can have these fields: diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index c01ba2692..400f0d11e 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -38,11 +38,11 @@ the group indicates which digging level the node requires. pickaxe of level 4 be mined. For tools to be able to dig nodes of digging groups they need to use the have -the custom field "_mcl_autogroup_groupcaps" function to get the groupcaps. The -value of this field is a table which defines which groups the tool can dig and -how efficiently. +the custom field "_mcl_diggroups" function to get the groupcaps. The value of +this field is a table which defines which groups the tool can dig and how +efficiently. - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { handy = { tool_multiplier = 1, level = 1, uses = 0 }, pickaxey = { tool_multiplier = 1, level = 0, uses = 0 }, } @@ -54,8 +54,7 @@ dig speed on that digging group. The "level" field indicates which levels of the group the tool can harvest. A level of 0 means that the tool cannot harvest blocks of that node. A level of 1 or above means that the tool can harvest nodes with that level or below. See -"mcl_tools/init.lua" for examples on how "_mcl_autogroup_groupcaps" is used in -practice. +"mcl_tools/init.lua" for examples on how "_mcl_diggroups" is used in practice. Information about the mod ========================= @@ -175,8 +174,8 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) } end --- Add the groupcaps from a field in "_mcl_autogroup_groupcaps" to the groupcaps --- of a tool. +-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a +-- tool. local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency) for g, capsdef in pairs(groupcaps_def) do local mult = capsdef.tool_multiplier or 1 @@ -211,7 +210,7 @@ function mcl_autogroup.can_harvest(nodename, toolname) -- 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 + for g, gdef in pairs(tdef._mcl_diggroups) do if ndef.groups[g] then if ndef.groups[g] <= gdef.level then return true @@ -223,7 +222,7 @@ function mcl_autogroup.can_harvest(nodename, toolname) -- 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 + for g, gdef in pairs(tdef._mcl_diggroups) do if ndef.groups[g] then if ndef.groups[g] <= gdef.level then return true @@ -259,7 +258,7 @@ end function mcl_autogroup.get_groupcaps(toolname, efficiency) local tdef = minetest.registered_tools[toolname] local groupcaps = table.copy(tdef.tool_capabilities.groupcaps or {}) - add_groupcaps(toolname, groupcaps, tdef._mcl_autogroup_groupcaps, efficiency) + add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency) return groupcaps end @@ -275,7 +274,7 @@ end -- loading order. function mcl_autogroup.get_wear(toolname, diggroup) local tdef = minetest.registered_tools[toolname] - local uses = tdef._mcl_autogroup_groupcaps[diggroup].uses + local uses = tdef._mcl_diggroups[diggroup].uses return math.ceil(65535 / uses) end @@ -321,9 +320,8 @@ local overwrite = function() for tname, tdef in pairs(minetest.registered_tools) do -- Assign groupcaps for digging the registered digging groups - -- depending on the _mcl_autogroup_groupcaps in the tool - -- definition - if tdef._mcl_autogroup_groupcaps then + -- depending on the _mcl_diggroups in the tool definition + if tdef._mcl_diggroups then local toolcaps = table.copy(tdef.tool_capabilities) or {} toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 28981fa7c..81ef049ec 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -236,7 +236,7 @@ function minetest.handle_node_drops(pos, drops, digger) end end - local diggroups = tooldef and tooldef._mcl_autogroup_groupcaps + local diggroups = tooldef and tooldef._mcl_diggroups 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 diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index dfe872adb..da7c06a31 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -68,7 +68,7 @@ minetest.register_tool(":", { damage_groups = {fleshy=1}, }, groups = hand_groups, - _mcl_autogroup_groupcaps = hand_autogroup_groupcaps, + _mcl_diggroups = hand_autogroup_groupcaps, }) -- Help texts @@ -100,7 +100,7 @@ minetest.register_tool("mcl_tools:pick_wood", { sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { pickaxey = { tool_multiplier = 2, level = 1, uses = 60 } }, }) @@ -120,7 +120,7 @@ minetest.register_tool("mcl_tools:pick_stone", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { pickaxey = { tool_multiplier = 4, level = 3, uses = 132 } }, }) @@ -140,7 +140,7 @@ minetest.register_tool("mcl_tools:pick_iron", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { pickaxey = { tool_multiplier = 6, level = 4, uses = 251 } }, }) @@ -160,7 +160,7 @@ minetest.register_tool("mcl_tools:pick_gold", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { pickaxey = { tool_multiplier = 12, level = 2, uses = 33 } }, }) @@ -180,7 +180,7 @@ minetest.register_tool("mcl_tools:pick_diamond", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { pickaxey = { tool_multiplier = 8, level = 5, uses = 1562 } }, }) @@ -272,7 +272,7 @@ minetest.register_tool("mcl_tools:shovel_wood", { sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { shovely = { tool_multiplier = 2, level = 1, uses = 60 } }, }) @@ -293,7 +293,7 @@ minetest.register_tool("mcl_tools:shovel_stone", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { shovely = { tool_multiplier = 4, level = 3, uses = 132 } }, }) @@ -314,7 +314,7 @@ minetest.register_tool("mcl_tools:shovel_iron", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { shovely = { tool_multiplier = 6, level = 4, uses = 251 } }, }) @@ -335,7 +335,7 @@ minetest.register_tool("mcl_tools:shovel_gold", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { shovely = { tool_multiplier = 12, level = 2, uses = 33 } }, }) @@ -356,7 +356,7 @@ minetest.register_tool("mcl_tools:shovel_diamond", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { shovely = { tool_multiplier = 8, level = 5, uses = 1562 } }, }) @@ -378,7 +378,7 @@ minetest.register_tool("mcl_tools:axe_wood", { sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { axey = { tool_multiplier = 2, level = 1, uses = 60 } }, }) @@ -397,7 +397,7 @@ minetest.register_tool("mcl_tools:axe_stone", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { axey = { tool_multiplier = 4, level = 3, uses = 132 } }, }) @@ -417,7 +417,7 @@ minetest.register_tool("mcl_tools:axe_iron", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { axey = { tool_multiplier = 6, level = 4, uses = 251 } }, }) @@ -436,7 +436,7 @@ minetest.register_tool("mcl_tools:axe_gold", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { axey = { tool_multiplier = 12, level = 2, uses = 33 } }, }) @@ -455,7 +455,7 @@ minetest.register_tool("mcl_tools:axe_diamond", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { axey = { tool_multiplier = 8, level = 5, uses = 1562 } }, }) @@ -477,7 +477,7 @@ minetest.register_tool("mcl_tools:sword_wood", { sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { swordy = { tool_multiplier = 2, level = 1, uses = 60 }, swordy_cobweb = { tool_multiplier = 2, level = 1, uses = 60 } }, @@ -497,7 +497,7 @@ minetest.register_tool("mcl_tools:sword_stone", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { swordy = { tool_multiplier = 4, level = 3, uses = 132 }, swordy_cobweb = { tool_multiplier = 4, level = 3, uses = 132 } }, @@ -517,7 +517,7 @@ minetest.register_tool("mcl_tools:sword_iron", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { swordy = { tool_multiplier = 6, level = 4, uses = 251 }, swordy_cobweb = { tool_multiplier = 6, level = 4, uses = 251 } }, @@ -537,7 +537,7 @@ minetest.register_tool("mcl_tools:sword_gold", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { swordy = { tool_multiplier = 12, level = 2, uses = 33 }, swordy_cobweb = { tool_multiplier = 12, level = 2, uses = 33 } }, @@ -557,7 +557,7 @@ minetest.register_tool("mcl_tools:sword_diamond", { sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { swordy = { tool_multiplier = 8, level = 5, uses = 1562 }, swordy_cobweb = { tool_multiplier = 8, level = 5, uses = 1562 } }, @@ -579,7 +579,7 @@ minetest.register_tool("mcl_tools:shears", { on_place = carve_pumpkin, sound = { breaks = "default_tool_breaks" }, _mcl_toollike_wield = true, - _mcl_autogroup_groupcaps = { + _mcl_diggroups = { shearsy = { tool_multiplier = 1.5, level = 1, uses = 238 }, shearsy_wool = { tool_multiplier = 5, level = 1, uses = 238 }, shearsy_cobweb = { tool_multiplier = 15, level = 1, uses = 238 } From 0112825a9f5b860a3ffa35f82458bbaa90710d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Wed, 17 Mar 2021 11:45:20 +0100 Subject: [PATCH 19/25] Localize variables in _mcl_autogroup --- mods/CORE/_mcl_autogroup/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 400f0d11e..c107b7b72 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -102,7 +102,7 @@ end -- Returns a table containing a table indexed by "_mcl_hardness_value" to get -- its index in the list of unique hardnesses for each diggroup. local function get_hardness_lookup_for_groups(hardness_values) - map = {} + local map = {} for g, values in pairs(hardness_values) do map[g] = {} for k, v in pairs(values) do @@ -139,7 +139,7 @@ end -- efficiency - efficiency level for the tool if applicable local function get_digtimes(group, can_harvest, tool_multiplier, efficiency) tool_multiplier = tool_multiplier or 1 - speed_multiplier = tool_multiplier + local speed_multiplier = tool_multiplier if efficiency then speed_multiplier = speed_multiplier + efficiency * efficiency + 1 end From fe770c19a5de9b92d7062c251582717ec9fd918d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Wed, 17 Mar 2021 16:59:26 +0100 Subject: [PATCH 20/25] Fix crash when tool_capabilities is nil --- mods/CORE/_mcl_autogroup/init.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index c107b7b72..7b2c275df 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -243,6 +243,15 @@ local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) } end +-- Returns the tool_capabilities from a tool definition or a default set of +-- tool_capabilities +local function get_tool_capabilities(tdef) + if tdef.tool_capabilities then + return tdef.tool_capabilities + end + return {} +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. @@ -257,7 +266,7 @@ end -- loading order. function mcl_autogroup.get_groupcaps(toolname, efficiency) local tdef = minetest.registered_tools[toolname] - local groupcaps = table.copy(tdef.tool_capabilities.groupcaps or {}) + local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {}) add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency) return groupcaps end @@ -322,7 +331,7 @@ local overwrite = function() -- Assign groupcaps for digging the registered digging groups -- depending on the _mcl_diggroups in the tool definition if tdef._mcl_diggroups then - local toolcaps = table.copy(tdef.tool_capabilities) or {} + local toolcaps = table.copy(get_tool_capabilities(tdef)) toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname) minetest.override_item(tname, { From 4c46eb2b4bc5907323c9e859f728bfe2c2d43a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Wed, 17 Mar 2021 17:09:19 +0100 Subject: [PATCH 21/25] Make tools without toolcaps do damage as hand If the tool_capabilities defaults to {} if unspecified the tool, then users will not be able to attack with the tool at all. This solves that by including the damage_group and full_punch_interval from the hand into the tool_capabilities when it is nil. --- mods/CORE/_mcl_autogroup/init.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 7b2c275df..86bef08bf 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -249,7 +249,14 @@ local function get_tool_capabilities(tdef) if tdef.tool_capabilities then return tdef.tool_capabilities end - return {} + + -- If the damage group and punch interval from hand is not included, + -- then the user will not be able to attack with the tool. + local hand_toolcaps = minetest.registered_tools[""].tool_capabilities + return { + full_punch_interval = hand_toolcaps.full_punch_interval, + damage_groups = hand_toolcaps.damage_groups + } end -- Get the groupcaps for a tool. This function returns "groupcaps" table of From 8f9650abe489630d3acc04ae11ebff6d6d41e771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Wed, 17 Mar 2021 17:39:15 +0100 Subject: [PATCH 22/25] Update the groupcaps of all enchanted tools Not just those enchanted with efficiency. --- mods/ITEMS/mcl_enchanting/enchantments.lua | 2 +- mods/ITEMS/mcl_enchanting/engine.lua | 12 ++------- .../{efficiency.lua => groupcaps.lua} | 27 +++++++++++-------- mods/ITEMS/mcl_enchanting/init.lua | 2 +- 4 files changed, 20 insertions(+), 23 deletions(-) rename mods/ITEMS/mcl_enchanting/{efficiency.lua => groupcaps.lua} (69%) diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 265bdb742..ca936c319 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -155,7 +155,7 @@ mcl_enchanting.enchantments.efficiency = { description = S("Increases mining speed."), curse = false, on_enchant = function(itemstack, level) - mcl_enchanting.apply_efficiency(itemstack, level) + mcl_enchanting.update_groupcaps(itemstack) end, requires_tool = false, treasure = false, diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index acde352b7..1325e5777 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -235,12 +235,7 @@ local function get_after_use_callback(itemdef) -- one too. return function(itemstack, user, node, digparams) itemdef.after_use(itemstack, user, node, digparams) - - local enchantments = mcl_enchanting.get_enchantments(itemstack) - local level = enchantments.efficiency - if level then - mcl_enchanting.apply_efficiency(itemstack, level) - end + mcl_enchanting.update_groupcaps(itemstack) end end @@ -252,10 +247,7 @@ local function get_after_use_callback(itemdef) end local enchantments = mcl_enchanting.get_enchantments(itemstack) - local level = enchantments.efficiency - if level then - mcl_enchanting.enchantments.efficiency.on_enchant(itemstack, level) - end + mcl_enchanting.update_groupcaps(itemstack) end end diff --git a/mods/ITEMS/mcl_enchanting/efficiency.lua b/mods/ITEMS/mcl_enchanting/groupcaps.lua similarity index 69% rename from mods/ITEMS/mcl_enchanting/efficiency.lua rename to mods/ITEMS/mcl_enchanting/groupcaps.lua index d4b06e5fb..3060000db 100644 --- a/mods/ITEMS/mcl_enchanting/efficiency.lua +++ b/mods/ITEMS/mcl_enchanting/groupcaps.lua @@ -1,4 +1,4 @@ -local efficiency_cache_table = {} +local groupcaps_cache = {} -- Compute a hash value. function compute_hash(value) @@ -8,18 +8,23 @@ function compute_hash(value) return string.sub(minetest.get_password_hash("ryvnf", minetest.serialize(value)), 1, 8) end --- Get the efficiency groupcaps and hash for a tool and efficiency level. If --- this function is called repeatedly with the same values it will return data --- from a cache. +-- Get the groupcaps and hash for an enchanted tool. If this function is called +-- repeatedly with the same values it will return data from a cache. +-- +-- Parameters: +-- toolname - Name of the tool +-- level - The efficiency level of the tool -- -- Returns a table with the following two fields: --- values - the groupcaps table --- hash - the hash of the groupcaps table +-- values - The groupcaps table +-- hash - The hash of the groupcaps table local function get_efficiency_groupcaps(toolname, level) - local toolcache = efficiency_cache_table[toolname] + local toolcache = groupcaps_cache[toolname] + local level = level + if not toolcache then toolcache = {} - efficiency_cache_table[toolname] = toolcache + groupcaps_cache[toolname] = toolcache end local levelcache = toolcache[level] @@ -33,15 +38,15 @@ local function get_efficiency_groupcaps(toolname, level) return levelcache end --- Apply efficiency enchantment to a tool. This will update the tools --- tool_capabilities to give it new digging times. This function will be called +-- Update groupcaps of an enchanted tool. This function will be called -- repeatedly to make sure the digging times stored in groupcaps stays in sync -- when the digging times of nodes can change. -- -- To make it more efficient it will first check a hash value to determine if -- the tool needs to be updated. -function mcl_enchanting.apply_efficiency(itemstack, level) +function mcl_enchanting.update_groupcaps(itemstack) local name = itemstack:get_name() + local level = mcl_enchanting.get_enchantment(itemstack, "efficiency") local groupcaps = get_efficiency_groupcaps(name, level) local hash = itemstack:get_meta():get_string("groupcaps_hash") diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index 45faa498b..5858b85eb 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -59,7 +59,7 @@ mcl_enchanting = { } dofile(modpath .. "/engine.lua") -dofile(modpath .. "/efficiency.lua") +dofile(modpath .. "/groupcaps.lua") dofile(modpath .. "/enchantments.lua") minetest.register_chatcommand("enchant", { From c8b543991ffe136350b48ae116aef3b8d60d627a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Wed, 17 Mar 2021 17:50:52 +0100 Subject: [PATCH 23/25] Automatically assign nodes to creative_breakable If they belong to any digging group. --- mods/CORE/_mcl_autogroup/init.lua | 8 +++++++ mods/ITEMS/mcl_tools/init.lua | 37 +++++++++++-------------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 86bef08bf..345bfd302 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -311,9 +311,12 @@ local overwrite = function() newgroups.opaque = 1 end + local creative_breakable = false + -- Assign groups used for digging this node depending on -- the registered digging groups for g, gdef in pairs(mcl_autogroup.registered_diggroups) do + creative_breakable = true local index = hardness_lookup[g][ndef._mcl_hardness or 0] if ndef.groups[g] then if gdef.levels then @@ -328,6 +331,11 @@ local overwrite = function() end end + -- Automatically assign the node to the + -- creative_breakable group if it belongs to any digging + -- group. + newgroups["creative_breakable"] = 1 + minetest.override_item(nname, { groups = newgroups }) diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index da7c06a31..3004a8305 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -19,35 +19,14 @@ dig_speed_class group: -- The hand local groupcaps, hand_range, hand_groups + if minetest.is_creative_enabled("") then -- Instant breaking in creative mode - groupcaps = {} + groupcaps = { creative_breakable = { times = {0}, uses = 0 } } hand_range = 10 hand_groups = { dig_speed_class = 7 } - hand_autogroup_groupcaps = { - 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 = 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 } end @@ -68,7 +47,17 @@ minetest.register_tool(":", { damage_groups = {fleshy=1}, }, groups = hand_groups, - _mcl_diggroups = hand_autogroup_groupcaps, + _mcl_diggroups = { + 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 }, + } }) -- Help texts From 521f96b4ab3258173d79a1dd3dc1333bcf2aec87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 18 Mar 2021 13:34:31 +0100 Subject: [PATCH 24/25] Use mod.conf for mcl_autogroup and _mcl_autogroup --- mods/CORE/_mcl_autogroup/depends.txt | 1 - mods/CORE/_mcl_autogroup/description.txt | 1 - mods/CORE/_mcl_autogroup/mod.conf | 3 +++ mods/CORE/mcl_autogroup/mod.conf | 3 +++ 4 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 mods/CORE/_mcl_autogroup/depends.txt delete mode 100644 mods/CORE/_mcl_autogroup/description.txt create mode 100644 mods/CORE/mcl_autogroup/mod.conf diff --git a/mods/CORE/_mcl_autogroup/depends.txt b/mods/CORE/_mcl_autogroup/depends.txt deleted file mode 100644 index 2c9bbaec7..000000000 --- a/mods/CORE/_mcl_autogroup/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_autogroup diff --git a/mods/CORE/_mcl_autogroup/description.txt b/mods/CORE/_mcl_autogroup/description.txt deleted file mode 100644 index dbc4f3186..000000000 --- a/mods/CORE/_mcl_autogroup/description.txt +++ /dev/null @@ -1 +0,0 @@ -MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/_mcl_autogroup/mod.conf b/mods/CORE/_mcl_autogroup/mod.conf index fb171b765..80cffa9ed 100644 --- a/mods/CORE/_mcl_autogroup/mod.conf +++ b/mods/CORE/_mcl_autogroup/mod.conf @@ -1 +1,4 @@ name = _mcl_autogroup +author = ryvnf +description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. +depends = mcl_autogroup diff --git a/mods/CORE/mcl_autogroup/mod.conf b/mods/CORE/mcl_autogroup/mod.conf new file mode 100644 index 000000000..45818cd58 --- /dev/null +++ b/mods/CORE/mcl_autogroup/mod.conf @@ -0,0 +1,3 @@ +name = mcl_autogroup +author = ryvnf +description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. From 13268965eed18cccad88007365cd790e8682d2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20=C3=85str=C3=B6m?= Date: Thu, 18 Mar 2021 13:40:56 +0100 Subject: [PATCH 25/25] Update README.txt in _mcl_autogroup --- mods/CORE/_mcl_autogroup/README.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mods/CORE/_mcl_autogroup/README.txt b/mods/CORE/_mcl_autogroup/README.txt index b7068a0b3..11383f311 100644 --- a/mods/CORE/_mcl_autogroup/README.txt +++ b/mods/CORE/_mcl_autogroup/README.txt @@ -4,6 +4,11 @@ Specifically, this mod has 2 purposes: 1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft. 2) Generating digging time group for all nodes based on node metadata (it's complicated) +This mod also requires another mod called “mcl_autogroup” to function properly. +“mcl_autogroup” exposes the API used to register digging groups, while this mod +uses those digging groups to set the digging time groups for all the nodes and +tools. + See init.lua for more infos. The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible.