forked from MineClone5/MineClone5
159 lines
5.6 KiB
Lua
159 lines
5.6 KiB
Lua
--[[ 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)
|
|
|
|
]]
|
|
|
|
--[[ Mining times. Yeah, mining times … Alright, this is going to be FUN!
|
|
|
|
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.so this weird group trickery has to be used.so this weird group trickery has to be used.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
|
|
(e.g. only diamond pick eligible for obsidian)
|
|
See Minecraft Wiki <http://minecraft.gamepedia.com/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.
|
|
|
|
Example:
|
|
mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2
|
|
|
|
→ This menas 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.
|
|
|
|
|
|
|
|
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).
|
|
|
|
]]
|
|
|
|
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,
|
|
}
|
|
|
|
mcl_autogroup = {}
|
|
mcl_autogroup.digtimes = {}
|
|
mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode
|
|
|
|
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]] = {}
|
|
end
|
|
end
|
|
for g=1, #minigroups do
|
|
mcl_autogroup.digtimes[minigroups[g].."_dig"] = {}
|
|
mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {}
|
|
end
|
|
|
|
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
|
|
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
|
|
if not (ndef.paramtype == "light" or ndef.sunlight_propagates) then
|
|
newgroups.opaque = 1
|
|
groups_changed = true
|
|
end
|
|
|
|
local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating)
|
|
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
|
|
time = (hardness * validity_factor) / divisors[material]
|
|
if time <= 0.05 then
|
|
time = 0
|
|
else
|
|
time = math.ceil(time * 20) / 20
|
|
end
|
|
table.insert(mcl_autogroup.digtimes[diggroup], time)
|
|
table.insert(mcl_autogroup.creativetimes[diggroup], 0)
|
|
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])
|
|
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)
|
|
groups_changed = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if groups_changed then
|
|
minetest.override_item(nname, {
|
|
groups = newgroups
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
overwrite()
|