forked from minetest/minetest_game
Doors: Allow falling nodes to fall onto doors.
We were cleverly attempting to use an airlike node as the top half of the doors, but as airlike nodes are not walkable, falling nodes would not stop falling and thus remain an entity stuck on top of a door. After inspecting the builtin/game/falling.lua code, I considered the remaining options: (a) revert doors such that the top part is actually the door, (b) play with nodedef fields and see if other flags may work, or (c) modify the hidden door part to another drawtype that properly prevents this issue. (a) seemed way over the top for now, although it would solve the issue, it would cause a rewrite of most of the code including the old-door-conversion. (b) turned up nothing. (c) turned out to be relatively simple. So, here's the implementation where I turn the hidden door top into a tiny, non-targetable but walkable nodebox that is entirely inside the door hinge. It's entirely transparent, so you still can't see it, can't hit it, nor can you place anything in it or make liquids flow through it. The top part is placed in the right position on placement and not touched further. Falling nodes will properly stop on top of these doors. I've adjusted the door conversion code to properly account for the issue as well, so the only thing remaining is people who have been running a git branch - those can upgrade by re-placing the door.
This commit is contained in:
parent
a2ecc51fbc
commit
9de43cdf7d
@ -74,17 +74,32 @@ end
|
|||||||
-- nodes from being placed in the top half of the door.
|
-- nodes from being placed in the top half of the door.
|
||||||
minetest.register_node("doors:hidden", {
|
minetest.register_node("doors:hidden", {
|
||||||
description = "Hidden Door Segment",
|
description = "Hidden Door Segment",
|
||||||
drawtype = "airlike",
|
-- can't use airlike otherwise falling nodes will turn to entities
|
||||||
|
-- and will be forever stuck until door is removed.
|
||||||
|
drawtype = "nodebox",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
|
paramtype2 = "facedir",
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
walkable = false,
|
-- has to be walkable for falling nodes to stop falling.
|
||||||
|
walkable = true,
|
||||||
pointable = false,
|
pointable = false,
|
||||||
diggable = false,
|
diggable = false,
|
||||||
buildable_to = false,
|
buildable_to = false,
|
||||||
floodable = false,
|
floodable = false,
|
||||||
drop = "",
|
drop = "",
|
||||||
groups = { not_in_creative_inventory = 1 },
|
groups = {not_in_creative_inventory = 1},
|
||||||
on_blast = function() end
|
on_blast = function() end,
|
||||||
|
tiles = {"doors_blank.png"},
|
||||||
|
-- 1px transparent block inside door hinge near node top.
|
||||||
|
nodebox = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32},
|
||||||
|
},
|
||||||
|
-- collision_box needed otherise selection box would be full node size
|
||||||
|
collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
-- table used to aid door opening/closing
|
-- table used to aid door opening/closing
|
||||||
@ -196,8 +211,21 @@ function doors.register(name, def)
|
|||||||
-- retain infotext and doors_owner fields
|
-- retain infotext and doors_owner fields
|
||||||
minetest.swap_node(pos, {name = name .. "_" .. new.type, param2 = p2})
|
minetest.swap_node(pos, {name = name .. "_" .. new.type, param2 = p2})
|
||||||
meta:set_int("state", new.state)
|
meta:set_int("state", new.state)
|
||||||
|
-- properly place doors:hidden at the right spot
|
||||||
|
local p3 = p2
|
||||||
|
if new.state >= 2 then
|
||||||
|
p3 = (p3 + 3) % 4
|
||||||
|
end
|
||||||
|
if new.state % 2 == 1 then
|
||||||
|
if new.state >= 2 then
|
||||||
|
p3 = (p3 + 1) % 4
|
||||||
|
else
|
||||||
|
p3 = (p3 + 3) % 4
|
||||||
|
end
|
||||||
|
end
|
||||||
-- wipe meta on top node as it's unused
|
-- wipe meta on top node as it's unused
|
||||||
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, { name = "doors:hidden" })
|
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z},
|
||||||
|
{name = "doors:hidden", param2 = p3})
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -259,10 +287,11 @@ function doors.register(name, def)
|
|||||||
if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then
|
if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then
|
||||||
state = state + 2
|
state = state + 2
|
||||||
minetest.set_node(pos, {name = name .. "_b", param2 = dir})
|
minetest.set_node(pos, {name = name .. "_b", param2 = dir})
|
||||||
|
minetest.set_node(above, {name = "doors:hidden", param2 = (dir + 3) % 4})
|
||||||
else
|
else
|
||||||
minetest.set_node(pos, {name = name .. "_a", param2 = dir})
|
minetest.set_node(pos, {name = name .. "_a", param2 = dir})
|
||||||
|
minetest.set_node(above, {name = "doors:hidden", param2 = dir})
|
||||||
end
|
end
|
||||||
minetest.set_node(above, { name = "doors:hidden" })
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_int("state", state)
|
meta:set_int("state", state)
|
||||||
@ -322,7 +351,8 @@ function doors.register(name, def)
|
|||||||
_doors.door_toggle(pos, clicker)
|
_doors.door_toggle(pos, clicker)
|
||||||
end
|
end
|
||||||
def.after_dig_node = function(pos, node, meta, digger)
|
def.after_dig_node = function(pos, node, meta, digger)
|
||||||
minetest.remove_node({ x = pos.x, y = pos.y + 1, z = pos.z})
|
minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z})
|
||||||
|
nodeupdate({x = pos.x, y = pos.y + 1, z = pos.z})
|
||||||
end
|
end
|
||||||
def.can_dig = function(pos, player)
|
def.can_dig = function(pos, player)
|
||||||
return can_dig(pos, player)
|
return can_dig(pos, player)
|
||||||
|
BIN
mods/doors/textures/doors_blank.png
Normal file
BIN
mods/doors/textures/doors_blank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 B |
Loading…
Reference in New Issue
Block a user