Skip to content

Commit

Permalink
Add rotation support for wallmounted nodes in 'ceiling' or 'floor' mo…
Browse files Browse the repository at this point in the history
…de (#11073)
  • Loading branch information
Wuzzy2 committed Jan 17, 2024
1 parent e7dd973 commit 08ee6d8
Show file tree
Hide file tree
Showing 25 changed files with 375 additions and 33 deletions.
2 changes: 2 additions & 0 deletions builtin/common/item_s.lua
Expand Up @@ -144,6 +144,8 @@ local wallmounted_to_dir = {
vector.new(-1, 0, 0),
vector.new( 0, 0, 1),
vector.new( 0, 0, -1),
vector.new( 0, 1, 0),
vector.new( 0, -1, 0),
}
function core.wallmounted_to_dir(wallmounted)
return wallmounted_to_dir[wallmounted % 8]
Expand Down
27 changes: 25 additions & 2 deletions builtin/game/falling.lua
Expand Up @@ -150,7 +150,12 @@ core.register_entity(":__builtin:falling_node", {

-- Rotate entity
if def.drawtype == "torchlike" then
self.object:set_yaw(math.pi*0.25)
if (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted")
and node.param2 % 8 == 7 then
self.object:set_yaw(-math.pi*0.25)
else
self.object:set_yaw(math.pi*0.25)
end
elseif ((node.param2 ~= 0 or def.drawtype == "nodebox" or def.drawtype == "mesh")
and (def.wield_image == "" or def.wield_image == nil))
or def.drawtype == "signlike"
Expand Down Expand Up @@ -190,6 +195,10 @@ core.register_entity(":__builtin:falling_node", {
pitch, yaw = 0, -math.pi/2
elseif rot == 4 then
pitch, yaw = 0, math.pi
elseif rot == 6 then
pitch, yaw = math.pi/2, 0
elseif rot == 7 then
pitch, yaw = -math.pi/2, math.pi
end
else
if rot == 1 then
Expand All @@ -202,6 +211,10 @@ core.register_entity(":__builtin:falling_node", {
pitch, yaw = math.pi/2, math.pi
elseif rot == 5 then
pitch, yaw = math.pi/2, 0
elseif rot == 6 then
pitch, yaw = math.pi, -math.pi/2
elseif rot == 7 then
pitch, yaw = 0, -math.pi/2
end
end
if def.drawtype == "signlike" then
Expand All @@ -210,10 +223,20 @@ core.register_entity(":__builtin:falling_node", {
yaw = yaw + math.pi/2
elseif rot == 1 then
yaw = yaw - math.pi/2
elseif rot == 6 then
yaw = yaw - math.pi/2
pitch = pitch + math.pi
elseif rot == 7 then
yaw = yaw + math.pi/2
pitch = pitch + math.pi
end
elseif def.drawtype == "mesh" or def.drawtype == "normal" or def.drawtype == "nodebox" then
if rot >= 0 and rot <= 1 then
if rot == 0 or rot == 1 then
roll = roll + math.pi
elseif rot == 6 or rot == 7 then
if def.drawtype ~= "normal" then
roll = roll - math.pi/2
end
else
yaw = yaw + math.pi
end
Expand Down
1 change: 1 addition & 0 deletions builtin/game/features.lua
Expand Up @@ -32,6 +32,7 @@ core.features = {
hud_def_type_field = true,
random_state_restore = true,
after_order_expiry_registration = true,
wallmounted_rotate = true,
}

function core.has_feature(arg)
Expand Down
33 changes: 33 additions & 0 deletions builtin/game/item.lua
Expand Up @@ -202,7 +202,40 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
elseif (def.paramtype2 == "wallmounted" or
def.paramtype2 == "colorwallmounted") and not param2 then
local dir = vector.subtract(under, above)
-- If you change this code, also change src/client/game.cpp
newnode.param2 = core.dir_to_wallmounted(dir)
if def.wallmounted_rotate_vertical and
(newnode.param2 == 0 or newnode.param2 == 1) then
local placer_pos = placer and placer:get_pos()
if placer_pos then
local pdir = {
x = above.x - placer_pos.x,
y = dir.y,
z = above.z - placer_pos.z
}
local rotate = false
if def.drawtype == "torchlike" then
if not ((pdir.x < 0 and pdir.z > 0) or
(pdir.x > 0 and pdir.z < 0)) then
rotate = true
end
if pdir.y > 0 then
rotate = not rotate
end
elseif def.drawtype == "signlike" then
if math.abs(pdir.x) < math.abs(pdir.z) then
rotate = true
end
else
if math.abs(pdir.x) > math.abs(pdir.z) then
rotate = true
end
end
if rotate then
newnode.param2 = newnode.param2 + 6
end
end
end
-- Calculate the direction for furnaces and chests and stuff
elseif (def.paramtype2 == "facedir" or
def.paramtype2 == "colorfacedir" or
Expand Down
18 changes: 16 additions & 2 deletions doc/lua_api.md
Expand Up @@ -1270,11 +1270,15 @@ The function of `param2` is determined by `paramtype2` in node definition.
* The rotation of the node is stored in `param2`
* Node is 'mounted'/facing towards one of 6 directions
* You can make this value by using `minetest.dir_to_wallmounted()`
* Values range 0 - 5
* Values range 0 - 7
* The value denotes at which direction the node is "mounted":
0 = y+, 1 = y-, 2 = x+, 3 = x-, 4 = z+, 5 = z-
6 = y+, but rotated by 90°
7 = y-, but rotated by -90°
* By default, on placement the param2 is automatically set to the
appropriate rotation, depending on which side was pointed at
appropriate rotation (0 to 5), depending on which side was
pointed at. With the node field `wallmounted_rotate_vertical = true`,
the param2 values 6 and 7 might additionally be set
* `paramtype2 = "facedir"`
* Supported drawtypes: "normal", "nodebox", "mesh"
* The rotation of the node is stored in `param2`.
Expand Down Expand Up @@ -5291,6 +5295,9 @@ Utilities
-- minetest.after guarantees that coexisting jobs are executed primarily
-- in order of expiry and secondarily in order of registration (5.9.0)
after_order_expiry_registration = true,
-- wallmounted nodes mounted at floor or ceiling may additionally
-- be rotated by 90° with special param2 values (5.9.0)
wallmounted_rotate = true,
}
```

Expand Down Expand Up @@ -8926,6 +8933,13 @@ Used by `minetest.register_node`.
place_param2 = 0,
-- Value for param2 that is set when player places node

wallmounted_rotate_vertical = false,
-- If true, place_param2 is nil, and this is a wallmounted node,
-- this node might use the special 90° rotation when placed
-- on the floor or ceiling, depending on the direction.
-- See the explanation about wallmounted for details.
-- Otherwise, the rotation is always the same on vertical placement.

is_ground_content = true,
-- If false, the cave generator and dungeon generator will not carve
-- through this node.
Expand Down
46 changes: 39 additions & 7 deletions games/devtest/mods/testnodes/drawtypes.lua
Expand Up @@ -163,7 +163,7 @@ minetest.register_node("testnodes:torchlike", {

minetest.register_node("testnodes:torchlike_wallmounted", {
description = S("Wallmounted \"torchlike\" Drawtype Test Node").."\n"..
S("param2 = wallmounted rotation (0..5)"),
S("param2 = wallmounted rotation (0..7)"),
drawtype = "torchlike",
paramtype = "light",
paramtype2 = "wallmounted",
Expand All @@ -179,23 +179,39 @@ minetest.register_node("testnodes:torchlike_wallmounted", {
groups = { dig_immediate = 3 },
})

minetest.register_node("testnodes:torchlike_wallmounted_rot", {
description = S("Wallmounted Rotatable Torchlike Drawtype Test Node"),
drawtype = "torchlike",
paramtype = "light",
paramtype2 = "wallmounted",
wallmounted_rotate_vertical = true,
tiles = {
"testnodes_torchlike_floor.png^[colorize:#FFFF00:40",
"testnodes_torchlike_ceiling.png^[colorize:#FFFF00:40",
"testnodes_torchlike_wall.png^[colorize:#FFFF00:40",
},


walkable = false,
sunlight_propagates = true,
groups = { dig_immediate = 3 },
})

minetest.register_node("testnodes:signlike", {
description = S("Floor \"signlike\" Drawtype Test Node").."\n"..
S("Always on floor"),
drawtype = "signlike",
paramtype = "light",
tiles = { "testnodes_signlike.png^[colorize:#FF0000:64" },


walkable = false,
groups = { dig_immediate = 3 },
sunlight_propagates = true,
groups = { dig_immediate = 3 },
})


minetest.register_node("testnodes:signlike_wallmounted", {
description = S("Wallmounted \"signlike\" Drawtype Test Node").."\n"..
S("param2 = wallmounted rotation (0..5)"),
S("param2 = wallmounted rotation (0..7)"),
drawtype = "signlike",
paramtype = "light",
paramtype2 = "wallmounted",
Expand All @@ -207,6 +223,22 @@ minetest.register_node("testnodes:signlike_wallmounted", {
sunlight_propagates = true,
})

minetest.register_node("testnodes:signlike_rot", {
description = S("Wallmounted Rotatable Signlike Drawtype Test Node"),
drawtype = "signlike",
paramtype = "light",
paramtype2 = "wallmounted",
wallmounted_rotate_vertical = true,
tiles = { "testnodes_signlike.png^[colorize:#FFFF00:40" },


walkable = false,
groups = { dig_immediate = 3 },
sunlight_propagates = true,
})



minetest.register_node("testnodes:plantlike", {
description = S("\"plantlike\" Drawtype Test Node"),
drawtype = "plantlike",
Expand Down Expand Up @@ -235,7 +267,7 @@ minetest.register_node("testnodes:plantlike_waving", {

minetest.register_node("testnodes:plantlike_wallmounted", {
description = S("Wallmounted \"plantlike\" Drawtype Test Node").."\n"..
S("param2 = wallmounted rotation (0..5)"),
S("param2 = wallmounted rotation (0..7)"),
drawtype = "plantlike",
paramtype = "light",
paramtype2 = "wallmounted",
Expand Down Expand Up @@ -366,7 +398,7 @@ minetest.register_node("testnodes:plantlike_rooted", {

minetest.register_node("testnodes:plantlike_rooted_wallmounted", {
description = S("Wallmounted \"rooted_plantlike\" Drawtype Test Node").."\n"..
S("param2 = wallmounted rotation (0..5)"),
S("param2 = wallmounted rotation (0..7)"),
drawtype = "plantlike_rooted",
paramtype = "light",
paramtype2 = "wallmounted",
Expand Down
4 changes: 2 additions & 2 deletions games/devtest/mods/testnodes/meshes.lua
Expand Up @@ -92,7 +92,7 @@ minetest.register_node("testnodes:mesh_color4dir", {
-- Wallmounted mesh: pyramid
minetest.register_node("testnodes:mesh_wallmounted", {
description = S("Wallmounted Mesh Test Node").."\n"..
S("param2 = wallmounted rotation (0..5)"),
S("param2 = wallmounted rotation (0..7)"),
drawtype = "mesh",
mesh = "testnodes_pyramid.obj",
tiles = {"testnodes_mesh_stripes9.png"},
Expand All @@ -105,7 +105,7 @@ minetest.register_node("testnodes:mesh_wallmounted", {

minetest.register_node("testnodes:mesh_colorwallmounted", {
description = S("Color Wallmounted Mesh Test Node").."\n"..
S("param2 = color + wallmounted rotation (0..5, 8..13, ...)"),
S("param2 = color + wallmounted rotation (0..7, 8..15, ...)"),
drawtype = "mesh",
mesh = "testnodes_pyramid.obj",
tiles = {"testnodes_mesh_stripes10.png"},
Expand Down
60 changes: 60 additions & 0 deletions games/devtest/mods/testnodes/nodeboxes.lua
Expand Up @@ -180,3 +180,63 @@ minetest.register_node("testnodes:facedir_to_connect_to", {
paramtype2 = "facedir",
connect_sides = {"left", "top"},
})

-- 3D sign and button:
-- These are example nodes for more realistic example uses
-- of wallmounted_rotate_vertical
minetest.register_node("testnodes:sign3d", {
description = S("Nodebox Sign, Nodebox Type \"fixed\""),
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "wallmounted",
wallmounted_rotate_vertical = true,
sunlight_propagates = true,
walkable = false,
tiles = {
"testnodes_sign3d.png",
},
groups = { dig_immediate = 3 },
node_box = {
type = "fixed",
fixed = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
},
})

minetest.register_node("testnodes:sign3d_wallmounted", {
description = S("Nodebox Sign, Nodebox Type \"wallmounted\""),
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "wallmounted",
wallmounted_rotate_vertical = true,
sunlight_propagates = true,
walkable = false,
tiles = {
"testnodes_sign3d.png^[colorize:#ff0000:127",
},
groups = { dig_immediate = 3 },
node_box = {
type = "wallmounted",
wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125},
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375},
},
})

minetest.register_node("testnodes:button", {
description = S("Button Nodebox Test Node"),
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "wallmounted",
wallmounted_rotate_vertical = true,
sunlight_propagates = true,
walkable = false,
tiles = {
"testnodes_nodebox.png",
},
groups = { dig_immediate = 3 },
node_box = {
type = "fixed",
fixed = { -4/16, -8/16, -2/16, 4/16, -6/16, 2/16 },
},
})

0 comments on commit 08ee6d8

Please sign in to comment.