8e47b687d0
Try to standardize the way we handle tools, materials, digtimes. - Levels start at 1 and work upwards. - Level 1 is for "hand" or "primitive" tools. - Levels 2+ are wood, stone, metal, etc. - Link dig times, tool levels, and durability together. - Material groups now define standard "base dig times" which are the main thing that makes e.g. stone harder to dig than dirt. The speed of digging almost everything will probably have changed, in some cases not for the better; much testing will be needed.
111 lines
3.2 KiB
Lua
111 lines
3.2 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local math, minetest, nodecore, pairs, type
|
|
= math, minetest, nodecore, pairs, type
|
|
local math_random
|
|
= math.random
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
--[[
|
|
Nodes with the "falling_repose" group will not only fall if unsupported
|
|
from below, but if there is a sufficient drop off the sides, so simulate
|
|
an "angle of repose."
|
|
--]]
|
|
|
|
function nodecore.falling_repose_drop(posfrom, posto, node)
|
|
minetest.spawn_falling_node(posto, node, minetest.get_meta(posfrom))
|
|
minetest.remove_node(posfrom)
|
|
posfrom.y = posfrom.y + 1
|
|
return minetest.check_for_falling(posfrom)
|
|
end
|
|
|
|
nodecore.register_on_register_item(function(name, def)
|
|
if def.type ~= "node" then return end
|
|
|
|
def.groups = def.groups or {}
|
|
|
|
if def.groups.falling_repose then def.groups.falling_node = 1 end
|
|
|
|
def.repose_drop = def.repose_drop or nodecore.falling_repose_drop
|
|
end)
|
|
|
|
function minetest.spawn_falling_node(pos, node, meta)
|
|
node = node or minetest.get_node(pos)
|
|
if node.name == "air" or node.name == "ignore" then
|
|
return false
|
|
end
|
|
local obj = minetest.add_entity(pos, "__builtin:falling_node")
|
|
if obj then
|
|
obj:get_luaentity():set_node(node, meta or minetest.get_meta(pos):to_table())
|
|
minetest.remove_node(pos)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function check_empty(pos, dx, dy, dz)
|
|
for ndy = dy, 1 do
|
|
local p = {x = pos.x + dx, y = pos.y + ndy, z = pos.z + dz}
|
|
local node = minetest.get_node(p)
|
|
if not minetest.registered_nodes[node.name].buildable_to then return end
|
|
end
|
|
return {x = pos.x + dx, y = pos.y, z = pos.z + dz}
|
|
end
|
|
function nodecore.falling_repose_check(pos)
|
|
if minetest.check_single_for_falling(pos) then return end
|
|
local node = minetest.get_node(pos)
|
|
local def = minetest.registered_nodes[node.name]
|
|
local repose = def.groups.falling_repose
|
|
if not repose then return end
|
|
|
|
-- Reposing nodes can always sit comfortably atop
|
|
-- a non-moving node; it's only when stacked on other
|
|
-- falling nodes that they can slip off.
|
|
if not (minetest.registered_nodes[minetest.get_node(
|
|
{x = pos.x, y = pos.y - 1, z = pos.z}).name].groups
|
|
or {}).falling_node
|
|
then return end
|
|
|
|
local open = {}
|
|
local ok = check_empty(pos, 1, -repose, 0)
|
|
if ok then open[1] = ok end
|
|
ok = check_empty(pos, -1, -repose, 0)
|
|
if ok then open[#open + 1] = ok end
|
|
ok = check_empty(pos, 0, -repose, 1)
|
|
if ok then open[#open + 1] = ok end
|
|
ok = check_empty(pos, 0, -repose, -1)
|
|
if ok then open[#open + 1] = ok end
|
|
if #open < 1 then return end
|
|
return def.repose_drop(pos, open[math_random(1, #open)], node)
|
|
end
|
|
|
|
local reposeq
|
|
local qqty
|
|
local qmax = 100
|
|
local function reposeall()
|
|
for _, v in pairs(reposeq) do v() end
|
|
reposeq = nil
|
|
qqty = nil
|
|
end
|
|
nodecore.register_limited_abm({
|
|
label = "Falling Repose",
|
|
nodenames = {"group:falling_repose"},
|
|
neighbors = {"air"},
|
|
interval = 2,
|
|
chance = 5,
|
|
action = function(pos, node)
|
|
if not reposeq then
|
|
reposeq = {}
|
|
qqty = 0
|
|
minetest.after(0, reposeall)
|
|
end
|
|
local f = function() nodecore.falling_repose_check(pos) end
|
|
if #reposeq > qmax then
|
|
local i = math_random(1, qqty)
|
|
if i < qmax then reposeq[i] = f end
|
|
else
|
|
reposeq[#reposeq + 1] = f
|
|
end
|
|
qqty = qqty + 1
|
|
end
|
|
})
|