forked from VoxeLibre/VoxeLibre
Compare commits
6 Commits
master
...
on_mods_lo
Author | SHA1 | Date |
---|---|---|
Daniel Cassidy | 4a0974b62a | |
Daniel Cassidy | e852d0a1c4 | |
epCode | 9b881df465 | |
Daniel Cassidy | 3831a03515 | |
Daniel Cassidy | 45d31eac5d | |
Daniel Cassidy | 2c23ab6174 |
|
@ -1,15 +0,0 @@
|
||||||
This mod automatically adds groups to items based on item metadata.
|
|
||||||
|
|
||||||
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.
|
|
||||||
As of 0.4.16, Minetest loads mods in reverse alphabetical order.
|
|
|
@ -1,367 +0,0 @@
|
||||||
--[[
|
|
||||||
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:
|
|
||||||
|
|
||||||
1) The block's hardness
|
|
||||||
2) The tool being used (the tool speed 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 <http://minecraft.gamepedia.com/Minecraft_Wiki> for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
How the mod is used
|
|
||||||
===================
|
|
||||||
|
|
||||||
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" }
|
|
||||||
})
|
|
||||||
|
|
||||||
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 be mined.
|
|
||||||
|
|
||||||
For tools to be able to dig nodes of digging groups they need to use the have
|
|
||||||
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_diggroups = {
|
|
||||||
handy = { speed = 1, level = 1, uses = 0 },
|
|
||||||
pickaxey = { speed = 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 "speed" 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_diggroups" is used in practice.
|
|
||||||
|
|
||||||
Information about the mod
|
|
||||||
=========================
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
This also means that it is very important that no mod adds _mcl_autogroup as a
|
|
||||||
dependency.
|
|
||||||
--]]
|
|
||||||
|
|
||||||
assert(minetest.get_modpath("mcl_autogroup"), "This mod requires the mod mcl_autogroup to function")
|
|
||||||
|
|
||||||
-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to
|
|
||||||
-- each diggroup.
|
|
||||||
local function get_hardness_values_for_groups()
|
|
||||||
local maps = {}
|
|
||||||
local values = {}
|
|
||||||
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(mcl_autogroup.registered_diggroups) do
|
|
||||||
if ndef.groups[g] then
|
|
||||||
maps[g][ndef._mcl_hardness or 0] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for g, map in pairs(maps) do
|
|
||||||
for k, _ in pairs(map) do
|
|
||||||
table.insert(values[g], k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
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 diggroup.
|
|
||||||
local function get_hardness_lookup_for_groups(hardness_values)
|
|
||||||
local 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
|
|
||||||
-- diggroup.
|
|
||||||
--
|
|
||||||
-- Parameters:
|
|
||||||
-- group - the group which it is digging
|
|
||||||
-- can_harvest - if the tool can harvest the block
|
|
||||||
-- speed - dig speed multiplier for tool (default 1)
|
|
||||||
-- efficiency - efficiency level for the tool if applicable
|
|
||||||
local function get_digtimes(group, can_harvest, speed, efficiency)
|
|
||||||
local speed = speed or 1
|
|
||||||
if efficiency then
|
|
||||||
speed = speed + efficiency * efficiency + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local digtimes = {}
|
|
||||||
|
|
||||||
for index, hardness in pairs(hardness_values[group]) do
|
|
||||||
local digtime = (hardness or 0) / speed
|
|
||||||
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
|
|
||||||
|
|
||||||
-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a
|
|
||||||
-- tool.
|
|
||||||
local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
|
|
||||||
if not groupcaps_def then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for g, capsdef in pairs(groupcaps_def) do
|
|
||||||
local mult = capsdef.speed or 1
|
|
||||||
local uses = capsdef.uses
|
|
||||||
local def = mcl_autogroup.registered_diggroups[g]
|
|
||||||
local max_level = def.levels and #def.levels or 1
|
|
||||||
|
|
||||||
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)
|
|
||||||
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, level > 0, mult, efficiency, uses)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 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]
|
|
||||||
|
|
||||||
if not ndef then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if it can be dug by tool
|
|
||||||
local tdef = minetest.registered_tools[toolname]
|
|
||||||
if tdef and tdef._mcl_diggroups then
|
|
||||||
for g, gdef in pairs(tdef._mcl_diggroups) do
|
|
||||||
if ndef.groups[g] then
|
|
||||||
if 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_diggroups) do
|
|
||||||
if ndef.groups[g] then
|
|
||||||
if ndef.groups[g] <= gdef.level then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
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]]
|
|
||||||
|
|
||||||
-- 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
|
|
||||||
|
|
||||||
-- 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
|
|
||||||
-- digging which should be put in the "tool_capabilities" of the tool definition
|
|
||||||
-- or in the metadata of an enchanted tool.
|
|
||||||
--
|
|
||||||
-- Parameters:
|
|
||||||
-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
|
|
||||||
-- efficiency - The efficiency level the tool is enchanted with (default 0)
|
|
||||||
--
|
|
||||||
-- 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_groupcaps(toolname, efficiency)
|
|
||||||
local tdef = minetest.registered_tools[toolname]
|
|
||||||
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
|
|
||||||
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, 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_diggroups[diggroup].uses
|
|
||||||
return math.ceil(65535 / uses)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function overwrite()
|
|
||||||
for nname, ndef in pairs(minetest.registered_nodes) do
|
|
||||||
local newgroups = table.copy(ndef.groups)
|
|
||||||
if (nname ~= "ignore" and ndef.diggable) then
|
|
||||||
-- 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
|
|
||||||
end
|
|
||||||
-- 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
|
|
||||||
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
|
|
||||||
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
|
|
||||||
end
|
|
||||||
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
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for tname, tdef in pairs(minetest.registered_tools) do
|
|
||||||
-- 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(get_tool_capabilities(tdef))
|
|
||||||
toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname)
|
|
||||||
|
|
||||||
minetest.override_item(tname, {
|
|
||||||
tool_capabilities = toolcaps
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
overwrite()
|
|
|
@ -1,3 +0,0 @@
|
||||||
name = _mcl_autogroup
|
|
||||||
author = ryvnf
|
|
||||||
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
This mod automatically adds groups to items based on item metadata.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
See init.lua for more infos.
|
|
@ -1,19 +1,65 @@
|
||||||
--[[
|
--[[
|
||||||
This is one part of a mod to replicate the digging times from Minecraft. This
|
This mod implements a HACK to make 100% sure the digging times of all tools
|
||||||
part only exposes a function to register digging groups. The rest of the mod is
|
match Minecraft's perfectly. The digging times system of Minetest is very
|
||||||
implemented and documented in the _mcl_autogroup.
|
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:
|
||||||
|
|
||||||
The mod is split up into two parts, mcl_autogroup and _mcl_autogroup.
|
1) The block's hardness
|
||||||
mcl_autogroup contains the API functions used to register custom digging groups.
|
2) The tool being used (the tool speed and its efficiency level)
|
||||||
_mcl_autogroup contains most of the code. The leading underscore in the name
|
3) Whether the tool is considered as "eligible" for the block
|
||||||
"_mcl_autogroup" is used to force Minetest to load that part of the mod as late
|
(e.g. only diamond pick eligible for obsidian)
|
||||||
as possible. Minetest loads mods in reverse alphabetical order.
|
|
||||||
|
See Minecraft Wiki <http://minecraft.gamepedia.com/Minecraft_Wiki> for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
How the mod is used
|
||||||
|
===================
|
||||||
|
|
||||||
|
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" }
|
||||||
|
})
|
||||||
|
|
||||||
|
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 be mined.
|
||||||
|
|
||||||
|
For tools to be able to dig nodes of digging groups they need to use the have
|
||||||
|
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_diggroups = {
|
||||||
|
handy = { speed = 1, level = 1, uses = 0 },
|
||||||
|
pickaxey = { speed = 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 "speed" 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_diggroups" is used in practice.
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
mcl_autogroup = {}
|
mcl_autogroup = {}
|
||||||
mcl_autogroup.registered_diggroups = {}
|
mcl_autogroup.registered_diggroups = {}
|
||||||
|
|
||||||
assert(minetest.get_modpath("_mcl_autogroup"), "This mod requires the mod _mcl_autogroup to function")
|
|
||||||
|
|
||||||
-- Register a group as a digging group.
|
-- Register a group as a digging group.
|
||||||
--
|
--
|
||||||
-- Parameters:
|
-- Parameters:
|
||||||
|
@ -26,3 +72,321 @@ assert(minetest.get_modpath("_mcl_autogroup"), "This mod requires the mod _mcl_a
|
||||||
function mcl_autogroup.register_diggroup(group, def)
|
function mcl_autogroup.register_diggroup(group, def)
|
||||||
mcl_autogroup.registered_diggroups[group] = def or {}
|
mcl_autogroup.registered_diggroups[group] = def or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to
|
||||||
|
-- each diggroup.
|
||||||
|
local function get_hardness_values_for_groups()
|
||||||
|
local maps = {}
|
||||||
|
local values = {}
|
||||||
|
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(mcl_autogroup.registered_diggroups) do
|
||||||
|
if ndef.groups[g] then
|
||||||
|
maps[g][ndef._mcl_hardness or 0] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for g, map in pairs(maps) do
|
||||||
|
for k, _ in pairs(map) do
|
||||||
|
table.insert(values[g], k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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 diggroup.
|
||||||
|
local function get_hardness_lookup_for_groups(hardness_values)
|
||||||
|
local 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
|
||||||
|
|
||||||
|
-- Map indexed by hardness values which return the index of that value in
|
||||||
|
-- hardness_value. Used for quick lookup.
|
||||||
|
local hardness_lookup
|
||||||
|
|
||||||
|
minetest.register_on_mods_loaded(function()
|
||||||
|
hardness_values = get_hardness_values_for_groups()
|
||||||
|
hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--[[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
|
||||||
|
-- diggroup.
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- group - the group which it is digging
|
||||||
|
-- can_harvest - if the tool can harvest the block
|
||||||
|
-- speed - dig speed multiplier for tool (default 1)
|
||||||
|
-- efficiency - efficiency level for the tool if applicable
|
||||||
|
local function get_digtimes(group, can_harvest, speed, efficiency)
|
||||||
|
local speed = speed or 1
|
||||||
|
if efficiency then
|
||||||
|
speed = speed + efficiency * efficiency + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local digtimes = {}
|
||||||
|
|
||||||
|
for index, hardness in pairs(hardness_values[group]) do
|
||||||
|
local digtime = (hardness or 0) / speed
|
||||||
|
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
|
||||||
|
|
||||||
|
-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a
|
||||||
|
-- tool.
|
||||||
|
local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
|
||||||
|
if not groupcaps_def then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for g, capsdef in pairs(groupcaps_def) do
|
||||||
|
local mult = capsdef.speed or 1
|
||||||
|
local uses = capsdef.uses
|
||||||
|
local def = mcl_autogroup.registered_diggroups[g]
|
||||||
|
local max_level = def.levels and #def.levels or 1
|
||||||
|
|
||||||
|
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)
|
||||||
|
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, level > 0, mult, efficiency, uses)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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]
|
||||||
|
|
||||||
|
if not ndef then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if it can be dug by tool
|
||||||
|
local tdef = minetest.registered_tools[toolname]
|
||||||
|
if tdef and tdef._mcl_diggroups then
|
||||||
|
for g, gdef in pairs(tdef._mcl_diggroups) do
|
||||||
|
if ndef.groups[g] then
|
||||||
|
if 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_diggroups) do
|
||||||
|
if ndef.groups[g] then
|
||||||
|
if ndef.groups[g] <= gdef.level then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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]]
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
-- digging which should be put in the "tool_capabilities" of the tool definition
|
||||||
|
-- or in the metadata of an enchanted tool.
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
|
||||||
|
-- efficiency - The efficiency level the tool is enchanted with (default 0)
|
||||||
|
--
|
||||||
|
-- NOTE:
|
||||||
|
-- This function can only be called after mod initialization.
|
||||||
|
function mcl_autogroup.get_groupcaps(toolname, efficiency)
|
||||||
|
local tdef = minetest.registered_tools[toolname]
|
||||||
|
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
|
||||||
|
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, 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.
|
||||||
|
function mcl_autogroup.get_wear(toolname, diggroup)
|
||||||
|
local tdef = minetest.registered_tools[toolname]
|
||||||
|
local uses = tdef._mcl_diggroups[diggroup].uses
|
||||||
|
return math.ceil(65535 / uses)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function overwrite()
|
||||||
|
for nname, ndef in pairs(minetest.registered_nodes) do
|
||||||
|
local newgroups = table.copy(ndef.groups)
|
||||||
|
if (nname ~= "ignore" and ndef.diggable) then
|
||||||
|
-- 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
|
||||||
|
end
|
||||||
|
-- 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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
end
|
||||||
|
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
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for tname, tdef in pairs(minetest.registered_tools) do
|
||||||
|
-- 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(get_tool_capabilities(tdef))
|
||||||
|
toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname)
|
||||||
|
|
||||||
|
minetest.override_item(tname, {
|
||||||
|
tool_capabilities = toolcaps
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_mods_loaded(overwrite)
|
||||||
|
|
||||||
|
-- Test code to demonstrate that on_mods_loaded branch works as expected.
|
||||||
|
-- Do not merge this code to master!
|
||||||
|
|
||||||
|
minetest.register_chatcommand("dump_autogroup", {
|
||||||
|
params = "",
|
||||||
|
description = "Dump data generated by mcl_autogroup to console",
|
||||||
|
privs = { privs = false },
|
||||||
|
func = function()
|
||||||
|
minetest.log("Registered nodes:")
|
||||||
|
for node_name, node_def in pairs(minetest.registered_nodes) do
|
||||||
|
minetest.log(node_name..": "..dump(node_def))
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("Registered tools:")
|
||||||
|
for tool_name, tool_def in pairs(minetest.registered_tools) do
|
||||||
|
minetest.log(tool_name..": "..dump(tool_def))
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("End dump")
|
||||||
|
end
|
||||||
|
})
|
|
@ -173,12 +173,6 @@ minetest.register_globalstep(function(dtime)
|
||||||
and (fly_node == "air" or fly_node == "ignore")
|
and (fly_node == "air" or fly_node == "ignore")
|
||||||
|
|
||||||
if elytra.active then
|
if elytra.active then
|
||||||
if player_velocity.x < (player_velocity_old.x - 10) or player_velocity.x > (player_velocity_old.x + 10) and fly_node ~= "ignore" then
|
|
||||||
mcl_util.deal_damage(player, math.abs(player_velocity_old.x) * 0.2, {type = "fly_into_wall"})
|
|
||||||
end
|
|
||||||
if player_velocity.z < (player_velocity_old.z - 10) or player_velocity.z > (player_velocity_old.z + 10) and fly_node ~= "ignore" then
|
|
||||||
mcl_util.deal_damage(player, math.abs(player_velocity_old.z) * 0.2, {type = "fly_into_wall"})
|
|
||||||
end
|
|
||||||
mcl_player.player_set_animation(player, "fly")
|
mcl_player.player_set_animation(player, "fly")
|
||||||
if player_velocity.y < -1.5 then
|
if player_velocity.y < -1.5 then
|
||||||
player:add_velocity({x=0, y=0.17, z=0})
|
player:add_velocity({x=0, y=0.17, z=0})
|
||||||
|
|
Loading…
Reference in New Issue