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.
This commit is contained in:
Nils Dagsson Moskopp 2021-09-04 01:05:19 +02:00
parent b26fb44aeb
commit 97e969832f
No known key found for this signature in database
GPG Key ID: A3BC671C35191080
1 changed files with 104 additions and 0 deletions

View File

@ -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
--