aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/game/falling.lua41
-rw-r--r--builtin/game/item.lua5
-rw-r--r--doc/lua_api.txt13
-rw-r--r--games/devtest/mods/testnodes/properties.lua56
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attached4_bottom.pngbin0 -> 123 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attached4_side.pngbin0 -> 111 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attached4_top.pngbin0 -> 100 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attachedf_bottom.pngbin0 -> 274 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attachedf_side.pngbin0 -> 188 bytes
-rw-r--r--games/devtest/mods/testnodes/textures/testnodes_attachedf_top.pngbin0 -> 170 bytes
-rw-r--r--src/client/game.cpp32
-rw-r--r--src/util/directiontables.cpp49
-rw-r--r--src/util/directiontables.h6
13 files changed, 176 insertions, 26 deletions
diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua
index 01a7d60b8..f9d71c90a 100644
--- a/builtin/game/falling.lua
+++ b/builtin/game/falling.lua
@@ -466,15 +466,39 @@ local function drop_attached_node(p)
end
end
-function builtin_shared.check_attached_node(p, n)
+function builtin_shared.check_attached_node(p, n, group_rating)
local def = core.registered_nodes[n.name]
local d = vector.zero()
- if def.paramtype2 == "wallmounted" or
+ if group_rating == 3 then
+ -- always attach to floor
+ d.y = -1
+ elseif group_rating == 4 then
+ -- always attach to ceiling
+ d.y = 1
+ elseif group_rating == 2 then
+ -- attach to facedir or 4dir direction
+ if (def.paramtype2 == "facedir" or
+ def.paramtype2 == "colorfacedir") then
+ -- Attach to whatever facedir is "mounted to".
+ -- For facedir, this is where tile no. 5 point at.
+
+ -- The fallback vector here is in case 'facedir to dir' is nil due
+ -- to voxelmanip placing a wallmounted node without resetting a
+ -- pre-existing param2 value that is out-of-range for facedir.
+ -- The fallback vector corresponds to param2 = 0.
+ d = core.facedir_to_dir(n.param2) or vector.new(0, 0, 1)
+ elseif (def.paramtype2 == "4dir" or
+ def.paramtype2 == "color4dir") then
+ -- Similar to facedir handling
+ d = core.fourdir_to_dir(n.param2) or vector.new(0, 0, 1)
+ end
+ elseif def.paramtype2 == "wallmounted" or
def.paramtype2 == "colorwallmounted" then
- -- The fallback vector here is in case 'wallmounted to dir' is nil due
- -- to voxelmanip placing a wallmounted node without resetting a
- -- pre-existing param2 value that is out-of-range for wallmounted.
- -- The fallback vector corresponds to param2 = 0.
+ -- Attach to whatever this node is "mounted to".
+ -- This where tile no. 2 points at.
+
+ -- The fallback vector here is used for the same reason as
+ -- for facedir nodes.
d = core.wallmounted_to_dir(n.param2) or vector.new(0, 1, 0)
else
d.y = -1
@@ -519,8 +543,9 @@ function core.check_single_for_falling(p)
end
end
- if core.get_item_group(n.name, "attached_node") ~= 0 then
- if not builtin_shared.check_attached_node(p, n) then
+ local an = core.get_item_group(n.name, "attached_node")
+ if an ~= 0 then
+ if not builtin_shared.check_attached_node(p, n, an) then
drop_attached_node(p)
return true
end
diff --git a/builtin/game/item.lua b/builtin/game/item.lua
index 1d1d52860..71126b0a7 100644
--- a/builtin/game/item.lua
+++ b/builtin/game/item.lua
@@ -240,8 +240,9 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
end
-- Check if the node is attached and if it can be placed there
- if core.get_item_group(def.name, "attached_node") ~= 0 and
- not builtin_shared.check_attached_node(place_to, newnode) then
+ local an = core.get_item_group(def.name, "attached_node")
+ if an ~= 0 and
+ not builtin_shared.check_attached_node(place_to, newnode, an) then
log("action", "attached node " .. def.name ..
" cannot be placed at " .. core.pos_to_string(place_to))
return itemstack, nil
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index b576863d6..1630b06dc 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1890,9 +1890,16 @@ to games.
### Node-only groups
-* `attached_node`: if the node under it is not a walkable block the node will be
- dropped as an item. If the node is wallmounted the wallmounted direction is
- checked.
+* `attached_node`: the node is 'attached' to a neighboring node. It checks
+ whether the node it is attached to is walkable. If it
+ isn't, the node will drop as an item.
+ * `1`: if the node is wallmounted, the node is attached in the wallmounted
+ direction. Otherwise, the node is attached to the node below.
+ * `2`: if the node is facedir or 4dir, the facedir or 4dir direction is checked.
+ No effect for other nodes.
+ Note: The "attaching face" of this node is tile no. 5 (back face).
+ * `3`: the node is always attached to the node below.
+ * `4`: the node is always attached to the node above.
* `bouncy`: value is bounce speed in percent.
If positive, jump/sneak on floor impact will increase/decrease bounce height.
Negative value is the same bounciness, but non-controllable.
diff --git a/games/devtest/mods/testnodes/properties.lua b/games/devtest/mods/testnodes/properties.lua
index 4dabe21fc..c51db810c 100644
--- a/games/devtest/mods/testnodes/properties.lua
+++ b/games/devtest/mods/testnodes/properties.lua
@@ -57,7 +57,6 @@ minetest.register_node("testnodes:attached", {
},
groups = { attached_node = 1, dig_immediate = 3 },
})
-
-- This node attaches to the side of a node and drops as item
-- when the node it attaches to is gone.
minetest.register_node("testnodes:attached_wallmounted", {
@@ -73,6 +72,61 @@ minetest.register_node("testnodes:attached_wallmounted", {
groups = { attached_node = 1, dig_immediate = 3 },
})
+-- Wallmounted node that always attaches to the floor
+minetest.register_node("testnodes:attached_wallmounted_floor", {
+ description = S("Floor-Attached Wallmounted Node"),
+ paramtype2 = "wallmounted",
+ tiles = {
+ "testnodes_attached_top.png",
+ "testnodes_attached_bottom.png",
+ "testnodes_attached_side.png",
+ },
+ groups = { attached_node = 3, dig_immediate = 3 },
+ color = "#FF8080",
+})
+
+-- This node attaches to the ceiling and drops as item
+-- when the ceiling is gone.
+minetest.register_node("testnodes:attached_top", {
+ description = S("Ceiling-Attached Node"),
+ tiles = {
+ "testnodes_attached_bottom.png",
+ "testnodes_attached_top.png",
+ "testnodes_attached_side.png^[transformR180",
+ },
+ groups = { attached_node = 4, dig_immediate = 3 },
+})
+
+-- Same as wallmounted attached, but for facedir
+minetest.register_node("testnodes:attached_facedir", {
+ description = S("Facedir Attached Node"),
+ paramtype2 = "facedir",
+ tiles = {
+ "testnodes_attachedf_side.png^[transformR180",
+ "testnodes_attachedf_side.png",
+ "testnodes_attachedf_side.png^[transformR90",
+ "testnodes_attachedf_side.png^[transformR270",
+ "testnodes_attachedf_bottom.png",
+ "testnodes_attachedf_top.png",
+ },
+ groups = { attached_node = 2, dig_immediate = 3 },
+})
+
+-- Same as facedir attached, but for 4dir
+minetest.register_node("testnodes:attached_4dir", {
+ description = S("4dir Attached Node"),
+ paramtype2 = "4dir",
+ tiles = {
+ "testnodes_attached4_side.png^[transformR180",
+ "testnodes_attached4_side.png",
+ "testnodes_attached4_side.png^[transformR90",
+ "testnodes_attached4_side.png^[transformR270",
+ "testnodes_attached4_bottom.png",
+ "testnodes_attached4_top.png",
+ },
+ groups = { attached_node = 2, dig_immediate = 3 },
+})
+
-- Jump disabled
minetest.register_node("testnodes:nojump", {
description = S("Non-jumping Node").."\n"..
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached4_bottom.png b/games/devtest/mods/testnodes/textures/testnodes_attached4_bottom.png
new file mode 100644
index 000000000..b7a7a2fdb
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attached4_bottom.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached4_side.png b/games/devtest/mods/testnodes/textures/testnodes_attached4_side.png
new file mode 100644
index 000000000..869e0736a
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attached4_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached4_top.png b/games/devtest/mods/testnodes/textures/testnodes_attached4_top.png
new file mode 100644
index 000000000..94219bcf5
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attached4_top.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedf_bottom.png b/games/devtest/mods/testnodes/textures/testnodes_attachedf_bottom.png
new file mode 100644
index 000000000..6c53d59de
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attachedf_bottom.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedf_side.png b/games/devtest/mods/testnodes/textures/testnodes_attachedf_side.png
new file mode 100644
index 000000000..f79001b57
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attachedf_side.png
Binary files differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedf_top.png b/games/devtest/mods/testnodes/textures/testnodes_attachedf_top.png
new file mode 100644
index 000000000..7a7ed1c18
--- /dev/null
+++ b/games/devtest/mods/testnodes/textures/testnodes_attachedf_top.png
Binary files differ
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 360ce4f8c..179557cf5 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -3585,22 +3585,30 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
}
// Check attachment if node is in group attached_node
- if (itemgroup_get(predicted_f.groups, "attached_node") != 0) {
- const static v3s16 wallmounted_dirs[8] = {
- v3s16(0, 1, 0),
- v3s16(0, -1, 0),
- v3s16(1, 0, 0),
- v3s16(-1, 0, 0),
- v3s16(0, 0, 1),
- v3s16(0, 0, -1),
- };
+ int an = itemgroup_get(predicted_f.groups, "attached_node");
+ if (an != 0) {
v3s16 pp;
- if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
- predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)
+ if (an == 3) {
+ pp = p + v3s16(0, -1, 0);
+ } else if (an == 4) {
+ pp = p + v3s16(0, 1, 0);
+ } else if (an == 2) {
+ if (predicted_f.param_type_2 == CPT2_FACEDIR ||
+ predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) {
+ pp = p + facedir_dirs[param2];
+ } else if (predicted_f.param_type_2 == CPT2_4DIR ||
+ predicted_f.param_type_2 == CPT2_COLORED_4DIR ) {
+ pp = p + fourdir_dirs[param2];
+ } else {
+ pp = p;
+ }
+ } else if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
+ predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
pp = p + wallmounted_dirs[param2];
- else
+ } else {
pp = p + v3s16(0, -1, 0);
+ }
if (!nodedef->get(map.getNode(pp)).walkable) {
soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed;
diff --git a/src/util/directiontables.cpp b/src/util/directiontables.cpp
index 296585f90..297058c9c 100644
--- a/src/util/directiontables.cpp
+++ b/src/util/directiontables.cpp
@@ -118,3 +118,52 @@ const u8 wallmounted_to_facedir[6] = {
8,
4 + 2
};
+
+const v3s16 wallmounted_dirs[8] = {
+ v3s16(0, 1, 0),
+ v3s16(0, -1, 0),
+ v3s16(1, 0, 0),
+ v3s16(-1, 0, 0),
+ v3s16(0, 0, 1),
+ v3s16(0, 0, -1),
+};
+
+const v3s16 facedir_dirs[32] = {
+ //0
+ v3s16(0, 0, 1),
+ v3s16(1, 0, 0),
+ v3s16(0, 0, -1),
+ v3s16(-1, 0, 0),
+ //4
+ v3s16(0, -1, 0),
+ v3s16(1, 0, 0),
+ v3s16(0, 1, 0),
+ v3s16(-1, 0, 0),
+ //8
+ v3s16(0, 1, 0),
+ v3s16(1, 0, 0),
+ v3s16(0, -1, 0),
+ v3s16(-1, 0, 0),
+ //12
+ v3s16(0, 0, 1),
+ v3s16(0, -1, 0),
+ v3s16(0, 0, -1),
+ v3s16(0, 1, 0),
+ //16
+ v3s16(0, 0, 1),
+ v3s16(0, 1, 0),
+ v3s16(0, 0, -1),
+ v3s16(0, -1, 0),
+ //20
+ v3s16(0, 0, 1),
+ v3s16(-1, 0, 0),
+ v3s16(0, 0, -1),
+ v3s16(1, 0, 0),
+};
+
+const v3s16 fourdir_dirs[4] = {
+ v3s16(0, 0, 1),
+ v3s16(1, 0, 0),
+ v3s16(0, 0, -1),
+ v3s16(-1, 0, 0),
+};
diff --git a/src/util/directiontables.h b/src/util/directiontables.h
index ef00e3bfe..3883a6e37 100644
--- a/src/util/directiontables.h
+++ b/src/util/directiontables.h
@@ -33,6 +33,12 @@ extern const v3s16 g_27dirs[27];
extern const u8 wallmounted_to_facedir[6];
+extern const v3s16 wallmounted_dirs[8];
+
+extern const v3s16 facedir_dirs[32];
+
+extern const v3s16 fourdir_dirs[4];
+
/// Direction in the 6D format. g_27dirs contains corresponding vectors.
/// Here P means Positive, N stands for Negative.
enum Direction6D {