@ -48,6 +48,110 @@ minetest.register_abm({
end ,
} )
local function count_air_nodes_below ( pos , limit )
local below_pos
local below_node
for i = 1 , limit do
below_pos = { x = pos.x , y = pos.y - i , z = pos.z }
below_node = minetest.get_node ( below_pos )
if below_node.name ~= " air " then
return i - 1
end
end
return limit
end
local function flow_water_downwards ( below_pos )
minetest.set_node (
below_pos ,
{ name = " mcl_core:water_flowing " , param2 = 15 }
)
-- One could assume that the lava cooling ABM would now do its
-- job if water nodes end up next to lava nodes. This is never
-- entirely the case: The only way to get any reliable cooling
-- of lava nodes is to do it ourselves here … the lava is just
-- removed otherwise.
--
-- This might be due to an engine bug.
local beside_pos_list = {
{ x = below_pos.x + 1 , y = below_pos.y , z = below_pos.z } ,
{ x = below_pos.x - 1 , y = below_pos.y , z = below_pos.z } ,
{ x = below_pos.x , y = below_pos.y , z = below_pos.z + 1 } ,
{ x = below_pos.x , y = below_pos.y , z = below_pos.z - 1 } ,
}
local beside_node
local lavatype
for _ , beside_pos in ipairs ( beside_pos_list ) do
beside_node = minetest.get_node ( beside_pos )
if 0 ~= minetest.get_item_group ( beside_node.name , " lava " ) then
lavatype = minetest.registered_nodes [ beside_node.name ] . liquidtype
-- Lava flow → Cobblestone
if lavatype == " flowing " then
minetest.set_node (
beside_pos ,
{ name = " mcl_core:cobble " }
)
-- Lava source → Obsidian
elseif lavatype == " source " then
minetest.set_node (
beside_pos ,
{ name = " mcl_core:obsidian " }
)
end
-- Stone is generated if lava
-- ends up above water nodes,
-- this is handled elsewhere.
minetest.sound_play (
" fire_extinguish_flame " ,
{ pos = beside_pos , gain = 0.25 , max_hear_distance = 16 } ,
true
)
end
end
end
minetest.register_abm ( {
label = " Speed up downwards water flow and cool lava " ,
nodenames = { " mcl_core:water_flowing " } ,
neighbors = { " air " } ,
interval = 0.5 ,
chance = 1 ,
action = function ( pos , node )
-- I want to start with an important message to every
-- future programmer who wants to rewrite the code in
-- a recursive fashion: STACK OVERFLOWS MEAN CRASHES!
--
-- Your recursive approach will most likely crash the
-- game – if not on your computer, then probably some
-- time later on some other computer. If you want the
-- questionable honor of being at fault when a bucket
-- of water can crash the server, go ahead: Refucktor
-- the code and be upset when it ruins someone's day.
--
-- After all, it really was not your fault, right? On
-- your computer everything worked and whoever has an
-- issue with your elegant solution just should buy a
-- new gaming rig or do something else beyond holding
-- you responsible for your utterly perfect solution.
--
-- In case this message offends you, I hereby ask you
-- to kindly fuck off, by which I mean: Stop reading.
-- We have to determine the depth of the air column
-- below the flowing water before changing anything
-- because otherwise we get artifacts in a lavacast
-- due to the lava escaping while we replace nodes.
local air_node_count = count_air_nodes_below ( pos , 80 )
if 0 == air_node_count then
return
end
for i = 1 , air_node_count do
local below_pos = { x = pos.x , y = pos.y - i , z = pos.z }
flow_water_downwards ( below_pos )
end
end ,
} )
--
-- Papyrus and cactus growing
--