diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index 3d47336f..4b054cc2 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -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 --