diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua index ec9c56c29..33473091d 100644 --- a/builtin/game/falling.lua +++ b/builtin/game/falling.lua @@ -79,6 +79,9 @@ core.register_entity(":__builtin:falling_node", { -- Cache whether we're supposed to float on water self.floats = core.get_item_group(node.name, "float") ~= 0 + -- Save liquidtype for falling water + self.liquidtype = def.liquidtype + -- Set entity visuals if def.drawtype == "torchlike" or def.drawtype == "signlike" then local textures @@ -294,9 +297,17 @@ core.register_entity(":__builtin:falling_node", { end -- Decide if we're replacing the node or placing on top + -- This condition is very similar to the check in core.check_single_for_falling(p) local np = vector.copy(bcp) - if bcd and bcd.buildable_to and - (not self.floats or bcd.liquidtype == "none") then + if bcd and bcd.buildable_to + and -- Take "float" group into consideration: + ( + -- Fall through non-liquids + not self.floats or bcd.liquidtype == "none" or + -- Only let sources fall through flowing liquids + (self.floats and self.liquidtype ~= "none" and bcd.liquidtype ~= "source") + ) then + core.remove_node(bcp) else np.y = np.y + 1 @@ -307,7 +318,7 @@ core.register_entity(":__builtin:falling_node", { local nd = core.registered_nodes[n2.name] -- If it's not air or liquid, remove node and replace it with -- it's drops - if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then + if n2.name ~= "air" and (not nd or nd.liquidtype ~= "source") then if nd and nd.buildable_to == false then nd.on_dig(np, n2, nil) -- If it's still there, it might be protected @@ -555,11 +566,19 @@ function core.check_single_for_falling(p) local success, _ = convert_to_falling_node(p, n) return success end + local d_falling = core.registered_nodes[n.name] + local do_float = core.get_item_group(n.name, "float") > 0 -- Otherwise only if the bottom node is considered "fall through" if not same and - (not d_bottom.walkable or d_bottom.buildable_to) and - (core.get_item_group(n.name, "float") == 0 or - d_bottom.liquidtype == "none") then + (not d_bottom.walkable or d_bottom.buildable_to) + and -- Take "float" group into consideration: + ( + -- Fall through non-liquids + not do_float or d_bottom.liquidtype == "none" or + -- Only let sources fall through flowing liquids + (do_float and d_falling.liquidtype == "source" and d_bottom.liquidtype ~= "source") + ) then + local success, _ = convert_to_falling_node(p, n) return success end diff --git a/doc/lua_api.md b/doc/lua_api.md index 6f5bb8683..5a4bc059c 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -2167,6 +2167,8 @@ to games. Negative damage values are discarded as no damage. * `falling_node`: if there is no walkable block under the node it will fall * `float`: the node will not fall through liquids (`liquidtype ~= "none"`) + * A liquid source with `groups = {falling_node = 1, float = 1}` + will fall through flowing liquids. * `level`: Can be used to give an additional sense of progression in the game. * A larger level will cause e.g. a weapon of a lower level make much less damage, and get worn out much faster, or not be able to get drops diff --git a/games/devtest/mods/testnodes/liquids.lua b/games/devtest/mods/testnodes/liquids.lua index 13b8dd9d7..334b16dff 100644 --- a/games/devtest/mods/testnodes/liquids.lua +++ b/games/devtest/mods/testnodes/liquids.lua @@ -9,7 +9,7 @@ for d=0, 8 do end minetest.register_node("testnodes:rliquid_"..d, { description = "Test Liquid Source, Range "..d.. - tt_normal, + tt_normal .. "\n" .. "(falling & floating node)", drawtype = "liquid", tiles = {"testnodes_liquidsource_r"..d..".png"}, special_tiles = { @@ -25,6 +25,8 @@ for d=0, 8 do liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d, liquid_alternative_source = "testnodes:rliquid_"..d, liquid_range = d, + -- Also use these nodes to test falling, floating liquid source nodes + groups = {float = 1, falling_node = 1}, }) minetest.register_node("testnodes:rliquid_flowing_"..d, {