Compare commits
16 Commits
07781855ad
...
9c28941a6a
Author | SHA1 | Date |
---|---|---|
trans_soup | 9c28941a6a | |
trans_soup | a4f121ac24 | |
trans_soup | 6bb71aa341 | |
trans_soup | c0ef9c3677 | |
trans_soup | b22827952c | |
trans_soup | c4a70e45ce | |
trans_soup | a3319cf9ea | |
trans_soup | 72a8666a86 | |
trans_soup | 5014254c91 | |
trans_soup | 4b408d9943 | |
trans_soup | 8d94fb9c70 | |
trans_soup | 87fba22f3b | |
trans_soup | 96ebbe8e0e | |
trans_soup | a09dc62101 | |
trans_soup | becfb37402 | |
trans_soup | e1103a07e4 |
|
@ -0,0 +1,103 @@
|
|||
local entity = minetest.registered_entities["__builtin:falling_node"]
|
||||
|
||||
|
||||
|
||||
local old_try_place = entity.try_place
|
||||
local after_land_callbacks = {}
|
||||
|
||||
entity.try_place = function (self, bcp, bcn)
|
||||
local result = old_try_place(self, bcp, bcn)
|
||||
-- `result` will be true if the falling node landed successfully (afaict from reading `/builtin/game/falling.lua` in the minetest source).
|
||||
if result then
|
||||
-- `bcp` is actually the node 0.7 nodes (rounded) below the falling_node entity.
|
||||
-- the vector addition here makes it be the position where the entity itself landed.
|
||||
-- if it landed on something layered, this new position might be air when the callbacks are called.
|
||||
local pos = bcp + vector.new(0, 1, 0)
|
||||
for _, callback in pairs(after_land_callbacks) do
|
||||
callback(pos, bcn, self)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function blockgame.register_after_falling_node_lands (callback)
|
||||
table.insert(after_land_callbacks, callback)
|
||||
end
|
||||
|
||||
blockgame.register_after_falling_node_lands(function (pos, node)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
|
||||
if type(def.after_land) == "function" then
|
||||
def.after_land(pos, node)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
local old_on_step = entity.on_step
|
||||
local on_step_callbacks = {}
|
||||
|
||||
entity.on_step = function (self, dtime, moveresult)
|
||||
local result = old_on_step(self, dtime, moveresult)
|
||||
for _, callback in pairs(on_step_callbacks) do
|
||||
callback(self, dtime, moveresult)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function blockgame.register_on_falling_node_step (callback)
|
||||
table.insert(on_step_callbacks, callback)
|
||||
end
|
||||
|
||||
-- keep track of velocity a falling_node had before landing
|
||||
-- so that code hooked into the landing can check "how fast was this moving?"
|
||||
blockgame.register_on_falling_node_step(function (entity, delta_time, move_result)
|
||||
local velocity = entity.object:get_velocity()
|
||||
|
||||
-- let `previous_velocity` be (0, 0, 0) at the very first step
|
||||
if not entity.fall_velocity then
|
||||
entity.fall_velocity = vector.new(0, 0, 0)
|
||||
end
|
||||
|
||||
-- keep track of moving velocity, not still velocity
|
||||
if velocity and (vector.length(velocity) ~= 0) then
|
||||
entity.fall_velocity = vector.copy(velocity)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- make falling nodes collide with `walkable = false` nodes if they are also `supports_falling = true`.
|
||||
blockgame.register_on_falling_node_step(function (entity, delta_time, move_result)
|
||||
local pos = entity.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
local below = pos:offset(0, -0.7, 0) -- same offset as in `/builtin/game/falling.lua`
|
||||
|
||||
local node = minetest.get_node(below)
|
||||
if node == "air" then return end
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if not def then return end
|
||||
|
||||
if def.walkable or not def.supports_falling then return end
|
||||
|
||||
local success = entity:try_place(below, node)
|
||||
|
||||
if not success then
|
||||
local drops = minetest.get_node_drops(entity.node, "")
|
||||
for _, item in pairs(drops) do
|
||||
minetest.add_item(pos, item)
|
||||
end
|
||||
end
|
||||
entity.object:remove()
|
||||
end)
|
||||
|
||||
local old_check = minetest.check_single_for_falling
|
||||
function minetest.check_single_for_falling (pos, ...)
|
||||
local node = minetest.get_node(pos:offset(0, -1, 0))
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if def and def.supports_falling then return false end
|
||||
return old_check(pos, ...)
|
||||
end
|
|
@ -22,5 +22,6 @@ load_file("wrappers")
|
|||
load_file("random_tick")
|
||||
load_file("increasing_abm")
|
||||
load_file("loose_node")
|
||||
load_file("fall_fix")
|
||||
|
||||
load_file("cleanup")
|
||||
|
|
|
@ -30,3 +30,37 @@ blockgame.crafting.register_pummel_recipe({
|
|||
minetest.set_node(pos, {name = modname .. ":bricks"})
|
||||
end,
|
||||
})
|
||||
|
||||
local crush_recipes = {
|
||||
{
|
||||
input = {"bg_terrain:cobblestone", "bg_terrain:cobblestone_loose"},
|
||||
output = modname .. ":tile",
|
||||
},
|
||||
{
|
||||
input = {modname .. ":tile"},
|
||||
output = modname .. ":bricks",
|
||||
},
|
||||
}
|
||||
|
||||
blockgame.register_after_falling_node_lands(function (pos, node, entity)
|
||||
if not blockgame.item_matches(node.name, {"group:stoney"}) then return end
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local mass = def.mass or 1
|
||||
local force = math.abs(entity.fall_velocity.y) * mass
|
||||
|
||||
if force < 5 then return end
|
||||
|
||||
local below = pos + blockgame.vector.dirs.down
|
||||
local target = minetest.get_node(below).name
|
||||
if not blockgame.item_matches(target, {"group:stoney"}) then return end
|
||||
|
||||
for _, recipe in pairs(crush_recipes) do
|
||||
local input = recipe.input
|
||||
local output = recipe.output
|
||||
if blockgame.item_matches(target, input) then
|
||||
minetest.set_node(below, {name = output})
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -24,7 +24,7 @@ end
|
|||
blockgame.register_abm({
|
||||
nodenames = {"bg_terrain:grass"},
|
||||
neighbors = {"bg_terrain:dirt"},
|
||||
interval = 15,
|
||||
interval = 30,
|
||||
chance = 8,
|
||||
action = function (pos, node)
|
||||
local sides = listify_table(blockgame.vector.sides)
|
||||
|
|
|
@ -27,22 +27,18 @@ blockgame.register_increasing_abm({
|
|||
end,
|
||||
})
|
||||
|
||||
local decompose_node_scores = {
|
||||
[leaves_decomposing] = 30,
|
||||
}
|
||||
local decompose_group_scores = {
|
||||
local decompose_scores = {
|
||||
dirty = 50,
|
||||
leaves_decomposing = 30,
|
||||
}
|
||||
|
||||
local decompose_cost = 2000
|
||||
|
||||
local average_leaves_per_dirt = 4
|
||||
|
||||
blockgame.register_increasing_abm({
|
||||
id = modname .. ":decompose",
|
||||
label = "decompose leaves",
|
||||
nodenames = {leaves_decomposing},
|
||||
neighbors = {"group:dirty", leaves_decomposing},
|
||||
nodenames = {"group:leaves_decomposing"},
|
||||
-- neighbors = {"group:dirty", "group:leaves_decomposing"},
|
||||
interval = 30,
|
||||
chance = 10,
|
||||
rate = function (pos, node, data)
|
||||
|
@ -55,9 +51,10 @@ blockgame.register_increasing_abm({
|
|||
local name = minetest.get_node(pos).name
|
||||
|
||||
local gain = 0
|
||||
for group, value in pairs(decompose_group_scores) do
|
||||
if minetest.get_item_group(name, group) > 0 then
|
||||
gain = math.max(gain, value)
|
||||
for group, value in pairs(decompose_scores) do
|
||||
local group = minetest.get_item_group(name, group)
|
||||
if group > 0 then
|
||||
gain = math.max(gain, value * group)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -68,10 +65,7 @@ blockgame.register_increasing_abm({
|
|||
return true
|
||||
end
|
||||
|
||||
if decompose_node_scores[name] then
|
||||
score = score + math.floor(decompose_node_scores[name] / distance)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end, 4)
|
||||
|
||||
return data.value + score
|
||||
|
@ -80,7 +74,12 @@ blockgame.register_increasing_abm({
|
|||
return data.value >= decompose_cost
|
||||
end,
|
||||
action = function (pos, node, data)
|
||||
if blockgame.chance(average_leaves_per_dirt) then
|
||||
-- currently, larger leaf piles have a greater chance of turning into dirt instead of disappearing.
|
||||
-- might wanna make it so that instead, dirt is layered as well?
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local dirt_chance = def.level_max - def.level + 1
|
||||
|
||||
if blockgame.chance(dirt_chance) then
|
||||
minetest.set_node(pos, {name = "bg_terrain:dirt"})
|
||||
else
|
||||
minetest.remove_node(pos)
|
||||
|
|
|
@ -25,6 +25,7 @@ blockgame.register_abm({
|
|||
end, 3)
|
||||
|
||||
if not is_supported then
|
||||
-- TODO: become randomly-sized leaves pile when layered leaves is added.
|
||||
minetest.set_node(pos, {name = modname .. ":leaves"})
|
||||
minetest.check_for_falling(pos)
|
||||
-- TODO: send out event here that makes nearby leaves check if they're unsupported as well?
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
|
||||
local function reg_leaves (name, def)
|
||||
def.description = def.description or name
|
||||
def.texture = def.texture or name
|
||||
def.tiles = {modname .. "_" .. def.texture .. ".png"}
|
||||
local texture = def.texture or name
|
||||
|
||||
def.drawtype = "glasslike"
|
||||
def.paramtype = "light"
|
||||
def.sunlight_propagates = true
|
||||
def = blockgame.underride(def, {
|
||||
description = name,
|
||||
|
||||
texture = texture,
|
||||
tiles = {modname .. "_" .. texture .. ".png"},
|
||||
|
||||
drawtype = "allfaces_optional",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
def.groups = blockgame.underride(def.groups, {
|
||||
planty = 1,
|
||||
|
@ -39,6 +44,8 @@ local nutty_drops = {
|
|||
|
||||
reg_leaves("leaves", {
|
||||
description = "Leaves",
|
||||
walkable = false,
|
||||
supports_falling = true,
|
||||
})
|
||||
reg_leaves("leaves_growing", {
|
||||
description = "Growing Leaves",
|
||||
|
@ -55,9 +62,68 @@ reg_leaves("leaves_alive", {
|
|||
falling_node = 0,
|
||||
},
|
||||
})
|
||||
reg_leaves("leaves_decomposing", {
|
||||
description = "Decomposing Leaves",
|
||||
groups = {
|
||||
supports_leaves = 0,
|
||||
},
|
||||
})
|
||||
|
||||
-- TODO: generalize stacking node registration and put into API.
|
||||
local decomposing_leaves_layers = 4
|
||||
|
||||
local after_place_stack = function (pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if not blockgame.starts_with(node.name, modname .. ":leaves_decomposing") then return end
|
||||
|
||||
local below = pos + blockgame.vector.dirs.down
|
||||
local below_node = minetest.get_node(below)
|
||||
if not blockgame.starts_with(below_node.name, modname .. ":leaves_decomposing") then return end
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local below_def = minetest.registered_nodes[below_node.name]
|
||||
|
||||
if below_def.level == decomposing_leaves_layers then return end
|
||||
local max_diff = decomposing_leaves_layers - below_def.level
|
||||
local diff = math.min(max_diff, def.level)
|
||||
|
||||
minetest.swap_node(below, {name = modname .. ":leaves_decomposing_" .. (below_def.level + diff)})
|
||||
if diff == def.level then
|
||||
minetest.remove_node(pos)
|
||||
else
|
||||
minetest.swap_node(pos, {name = modname .. ":leaves_decomposing_" .. (def.level - diff)})
|
||||
end
|
||||
end
|
||||
|
||||
local function reg_decomposing (level)
|
||||
local height = level / decomposing_leaves_layers
|
||||
|
||||
local description = "Decomposing Leaves (" .. level .. "/" .. decomposing_leaves_layers .. ")"
|
||||
if level == decomposing_leaves_layers then description = "Decomposing Leaves" end
|
||||
|
||||
local drawtype = "nodebox"
|
||||
local node_box = {
|
||||
["type"] = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, -0.5 + height, 0.5 },
|
||||
}
|
||||
if level == decomposing_leaves_layers then
|
||||
drawtype = "allfaces_optional"
|
||||
node_box = nil
|
||||
end
|
||||
|
||||
reg_leaves("leaves_decomposing_" .. level, {
|
||||
description = description,
|
||||
level = level,
|
||||
level_max = decomposing_leaves_layers,
|
||||
texture = "leaves_decomposing",
|
||||
drawtype = drawtype,
|
||||
node_box = node_box,
|
||||
after_place_node = after_place_stack,
|
||||
after_land = after_place_stack,
|
||||
drop = modname .. ":leaves_decomposing_1 " .. level,
|
||||
groups = {
|
||||
leaves_decomposing = level,
|
||||
},
|
||||
walkable = false,
|
||||
supports_falling = true,
|
||||
})
|
||||
end
|
||||
for level=1, decomposing_leaves_layers do
|
||||
reg_decomposing(level)
|
||||
end
|
||||
|
||||
minetest.register_alias(modname .. ":leaves_decomposing", modname .. ":leaves_decomposing_" .. decomposing_leaves_layers)
|
||||
|
|
Loading…
Reference in New Issue