diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md index 20e85036b..773537bed 100644 --- a/mods/CORE/flowlib/API.md +++ b/mods/CORE/flowlib/API.md @@ -42,4 +42,18 @@ WARNING: This function is never used in mcl2, use at your own risk. The informat * pos: position * realpos: position, position of the entity * node: node -* radius: number \ No newline at end of file +* radius: number + +## flowlib.get_liquid_height(pos, pos_offset) +Return the exact height that a flowing liquid is rendered at , or nil if there is no flowing liquid in that node. +This has sub-node precision. +If is specified, then must be rounded to the nearest node, and is the offset from the centre of the node. +* pos: position (vector) +* pos_offset: offset (vector) - all dimensions must have absolute value of at most 0.5 + +## flowlib.liquid_at_exact(pos, pos_offset) +Return the liquid that is rendered at , or nil if no liquid is rendered at that position. +This has sub-node precision. +If is specified, then must be rounded to the nearest node, and is the offset from the centre of the node. +* pos: position (vector) +* pos_offset: offset (vector) - all dimensions must have absolute value of at most 0.5 diff --git a/mods/CORE/flowlib/init.lua b/mods/CORE/flowlib/init.lua index dc801e9ee..006981b89 100644 --- a/mods/CORE/flowlib/init.lua +++ b/mods/CORE/flowlib/init.lua @@ -65,7 +65,7 @@ end flowlib.is_liquid = is_liquid local function node_is_liquid(node) - return minetest.get_item_group(node.name, "liquid") ~= 0 + return get_item_group(node.name, "liquid") ~= 0 end flowlib.node_is_liquid = node_is_liquid @@ -187,21 +187,14 @@ end -- Based on https://github.com/minetest/minetest/blob/master/src/client/content_mapblock.cpp#L536-L813 +-- If minetest ever changes liquid flowing rendering this must be changed accordingly local function get_liquid_corner_heights(pos) - - local stime = minetest.get_us_time() -- debug - local cur_liquid = {} local node = get_node(pos) - local ndef = registered_nodes[node.name] if not (get_item_group(node.name, "liquid") > 0) then return end - + local ndef = registered_nodes[node.name] local node_above = get_node({x=pos.x, y=pos.y+1, z=pos.z}) - - minetest.debug("glch1", minetest.get_us_time() - stime) - stime = minetest.get_us_time() - -- BEGIN prepareLiquidNodeDrawing cur_liquid.content = node.name local c_flowing = ndef.liquid_alternative_flowing @@ -210,8 +203,6 @@ local function get_liquid_corner_heights(pos) -- quick return if the liquid above is the same if cur_liquid.top_is_same_liquid then return {0.5, 0.5, 0.5, 0.5} end -- END prepareLiquidNodeDrawing - minetest.debug("glch2", minetest.get_us_time() - stime) - stime = minetest.get_us_time() local c_flowing_ndef = registered_nodes[c_flowing] @@ -248,10 +239,6 @@ local function get_liquid_corner_heights(pos) end --END getLiquidNeighborhood - - minetest.debug("glch3", minetest.get_us_time() - stime) - stime = minetest.get_us_time() - --BEGIN drawLiquidTop calculateCornerLevels local vertices = { get_corner_level(1, 2, c_flowing, c_source, neighbors), @@ -259,57 +246,59 @@ local function get_liquid_corner_heights(pos) get_corner_level(2, 1, c_flowing, c_source, neighbors), get_corner_level(1, 1, c_flowing, c_source, neighbors), } - --first 3 vertices are connected, so are last 2 and first - - minetest.debug("glch4", minetest.get_us_time() - stime) - stime = minetest.get_us_time() --END drawLiquidTop calculateCornerLevels return vertices end -local function get_liquid_height(pos_origin, pos_offset) - local stime = minetest.get_us_time() -- debug +local function get_liquid_height(pos, pos_offset) + local pos_origin + if pos_offset == nil then + pos_origin = vector.round(pos) + pos_offset = pos - pos_origin + else + pos_origin = pos + end + minetest.debug("pos_origin:", pos_origin) local corner_heights = get_liquid_corner_heights(pos_origin) - minetest.debug("glh1", minetest.get_us_time() - stime) - stime = minetest.get_us_time() if corner_heights == nil then return end -- order: -+ ++ +- -- + --first 3 vertices are connected, so are last 2 and first + local height_centre, height_x, height_z if pos_offset.x + pos_offset.z > 0 then -- first triangle - pos_offset = {x=0.5, y=0, z=0.5} - pos_offset - local height_centre = corner_heights[2] - local height_x = corner_heights[1] - local height_z = corner_heights[3] - local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z - return height + pos_origin.y + minetest.debug(dump(pos_offset)) + pos_offset = vector.subtract({x=0.5, y=0, z=0.5}, pos_offset) + height_centre = corner_heights[2] + height_x = corner_heights[1] + height_z = corner_heights[3] else -- second triangle - pos_offset = {x=0.5, y=0, z=0.5} + pos_offset - local height_centre = corner_heights[4] - local height_x = corner_heights[3] - local height_z = corner_heights[1] - local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z - return height + pos_origin.y + pos_offset = vector.add({x=0.5, y=0, z=0.5}, pos_offset) + height_centre = corner_heights[4] + height_x = corner_heights[3] + height_z = corner_heights[1] end + -- interpolate based on position in triangle + local height = height_centre + (height_x - height_centre) * pos_offset.x + (height_z - height_centre) * pos_offset.z + return height + pos_origin.y end local function liquid_at_exact(pos, pos_offset) - local pos_origin = vector.round(pos) + local pos_origin if pos_offset == nil then + pos_origin = vector.round(pos) pos_offset = pos - pos_origin + else + pos_origin = pos end local liq_height = get_liquid_height(pos_origin, pos_offset) if liq_height == nil then return nil end if liq_height > (pos_offset.y + pos_origin.y) then - return minetest.get_node(pos_origin).name + return get_node(pos_origin).name else return nil end end - - -flowlib.get_liquid_corner_heights = get_liquid_corner_heights flowlib.get_liquid_height = get_liquid_height flowlib.liquid_at_exact = liquid_at_exact - diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index a08f78b33..0ab895873 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -552,8 +552,6 @@ end local function do_breath_tick(player, dtime) -- don't use default breath - - minetest.set_node({x=0, y=100, z=0}, {name="mcl_core:lava_flowing", param2=math.random(0,7)}) player:set_breath(player:get_properties().breath_max) local breath_max = hb.settings.breath_max diff --git a/mods/PLAYER/mcl_playerinfo/init.lua b/mods/PLAYER/mcl_playerinfo/init.lua index 57726ee15..f4b53db3d 100644 --- a/mods/PLAYER/mcl_playerinfo/init.lua +++ b/mods/PLAYER/mcl_playerinfo/init.lua @@ -45,7 +45,31 @@ end local time = 0 local function get_head_submerged_node(head_pos) - return flowlib.liquid_at_exact(head_pos) + local true_liquid = flowlib.liquid_at_exact(head_pos) + -- If player is on the edge of a liquid node, they should not be in it + -- This is to allow water columns to be climbed without drowning + -- Would be better if this were implemented in minetest i.e. players climbing outside of liquids + local pos_origin = vector.round(head_pos)--{x=math.floor(head_pos.x + 0.5), y=head_pos.y, z=math.floor(head_pos.z + 0.5)} + -- Amount in nodes to allow player to be inside liquid without being inside liquid + local inside_liquid_leeway = 0.06 + local adjacent_liquid + if head_pos.x - pos_origin.x > 0.5 - inside_liquid_leeway then + adjacent_liquid = flowlib.liquid_at_exact({x=pos_origin.x+1, y=pos_origin.y, z=pos_origin.z}, {x=-0.5, y=head_pos.y - pos_origin.y, z=0}) + elseif pos_origin.x - head_pos.x > 0.5 - inside_liquid_leeway then + adjacent_liquid = flowlib.liquid_at_exact({x=pos_origin.x-1, y=pos_origin.y, z=pos_origin.z}, {x= 0.5, y=head_pos.y - pos_origin.y, z=0}) + elseif head_pos.z - pos_origin.z > 0.5 - inside_liquid_leeway then + adjacent_liquid = flowlib.liquid_at_exact({x=pos_origin.x, y=pos_origin.y, z=pos_origin.z+1}, {x=0, y=head_pos.y - pos_origin.y, z=-0.5}) + elseif pos_origin.z - head_pos.z > 0.5 - inside_liquid_leeway then + adjacent_liquid = flowlib.liquid_at_exact({x=pos_origin.x, y=pos_origin.y, z=pos_origin.z-1}, {x=0, y=head_pos.y - pos_origin.y, z=0.5}) + else + return true_liquid + end + -- Only use the adjacent node if it is air + if adjacent_liquid == nil then + return adjacent_liquid + else + return true_liquid + end end local function get_player_nodes(player) @@ -69,32 +93,6 @@ local function get_player_nodes(player) infotable.head_submerged_in = get_head_submerged_node(part_pos) minetest.debug("player " .. player:get_player_name() .. " has head submerged in:", infotable.head_submerged_in) - - - local lch = flowlib.get_liquid_corner_heights(part_pos) - local lh = flowlib.get_liquid_height(vector.round(part_pos), part_pos - vector.round(part_pos)) - if lch then - --minetest.debug("current liquid corner heights: ", "-+", lch[1].y , "++", lch[2].y , "+-", lch[3].y , "--", lch[4].y) - end - for i,v in ipairs(minetest.get_objects_inside_radius(player_pos, 5)) do - if (v:get_luaentity() or {}).name == "mcl_playerinfo:debug_marker" then - v:remove() - end - end - if lch then - minetest.add_entity(vector.add(vector.round(part_pos), {x=-0.5, y=lch[1], z= 0.5}), "mcl_playerinfo:debug_marker") - minetest.add_entity(vector.add(vector.round(part_pos), {x= 0.5, y=lch[2], z= 0.5}), "mcl_playerinfo:debug_marker") - minetest.add_entity(vector.add(vector.round(part_pos), {x= 0.5, y=lch[3], z=-0.5}), "mcl_playerinfo:debug_marker") - minetest.add_entity(vector.add(vector.round(part_pos), {x=-0.5, y=lch[4], z=-0.5}), "mcl_playerinfo:debug_marker") - end - for i=1,4 do - - if lh then - minetest.add_entity({x=part_pos.x, y=lh, z=part_pos.z}, "mcl_playerinfo:debug_marker") - end - minetest.add_entity(part_pos, "mcl_playerinfo:debug_marker") - end - part_pos = get_playerpart_pos("head_top", player_pos, collisionbox, eye_height) infotable.node_head_top = node_ok(part_pos).name @@ -147,11 +145,6 @@ minetest.register_on_joinplayer(function(player) node_stand = "", node_stand_below = "", node_head_top = "", - ndef_head = "", - ndef_feet = "", - ndef_stand = "", - ndef_stand_below = "", - ndef_head_top = "", } end)