From 97e969832f9b27cdc1795d37f3eecf03c2a4d7c6 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Sat, 4 Sep 2021 01:05:19 +0200 Subject: [PATCH] Speed up water flow to make lavacasting possible Minecraft-style lavacasting involves making a lavafall and pouring water over it to solidify the flowing lava. The Minetest engine make this hard to do, since water that flows beside lava flows at similar speed as lava disappaers. Therefore, making a lava curtain and pouring water over that can not create a solid wall of cobblestone as it does in Minecraft if no code is added to speed up downwards water flow. This patch adds an ABM that speeds up downwards water flows, turning any lava nodes next to the newly spawned water into cobblestone or obsidian. --- mods/ITEMS/mcl_core/functions.lua | 104 ++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) 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 --