From 1d04903c1973591e795d3275b900d76d7cb7877a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 16 Sep 2022 13:18:55 +0200 Subject: [PATCH] Add paramtype2s for 4 horizontal rotations and 64 colors (#11431) 4dir is like facedir, but only for 4 horizontal directions: NESW. It is identical in behavior to facedir otherwise. The reason why game makers would want to use this over facedir is 1) simplicity and 2) you get 6 free bits. It can be used for things like chests and furnaces and you don't need or want them to "flip them on the side" (like you could with facedir). color4dir is like colorfacedir, but you get 64 colors instead of only 8. --- builtin/game/falling.lua | 11 ++- builtin/game/item.lua | 6 +- builtin/game/item_s.lua | 25 +++++- doc/lua_api.txt | 47 ++++++++++- games/devtest/mods/testnodes/meshes.lua | 25 ++++++ games/devtest/mods/testnodes/nodeboxes.lua | 66 ++++++++++++++-- games/devtest/mods/testnodes/param2.lua | 74 ++++++++++++++++++ .../textures/testnodes_palette_4dir.png | Bin 0 -> 197 bytes src/client/content_mapblock.cpp | 4 +- src/client/game.cpp | 8 +- src/mapnode.cpp | 21 +++-- src/nodedef.cpp | 29 ++++++- src/nodedef.h | 6 +- src/script/common/c_content.cpp | 3 +- src/script/cpp_api/s_node.cpp | 2 + 15 files changed, 299 insertions(+), 28 deletions(-) create mode 100644 games/devtest/mods/testnodes/textures/testnodes_palette_4dir.png diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua index d5727f2a7..01a7d60b8 100644 --- a/builtin/game/falling.lua +++ b/builtin/game/falling.lua @@ -161,7 +161,16 @@ core.register_entity(":__builtin:falling_node", { local fdir = node.param2 % 32 % 24 -- Get rotation from a precalculated lookup table local euler = facedir_to_euler[fdir + 1] - self.object:set_rotation(euler) + if euler then + self.object:set_rotation(euler) + end + elseif (def.paramtype2 == "4dir" or def.paramtype2 == "color4dir") then + local fdir = node.param2 % 4 + -- Get rotation from a precalculated lookup table + local euler = facedir_to_euler[fdir + 1] + if euler then + self.object:set_rotation(euler) + end elseif (def.drawtype ~= "plantlike" and def.drawtype ~= "plantlike_rooted" and (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted" or def.drawtype == "signlike")) then local rot = node.param2 % 8 diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 00601c68c..af3fcb645 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -205,7 +205,9 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2, newnode.param2 = core.dir_to_wallmounted(dir) -- Calculate the direction for furnaces and chests and stuff elseif (def.paramtype2 == "facedir" or - def.paramtype2 == "colorfacedir") and not param2 then + def.paramtype2 == "colorfacedir" or + def.paramtype2 == "4dir" or + def.paramtype2 == "color4dir") and not param2 then local placer_pos = placer and placer:get_pos() if placer_pos then local dir = vector.subtract(above, placer_pos) @@ -225,6 +227,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2, color_divisor = 8 elseif def.paramtype2 == "colorfacedir" then color_divisor = 32 + elseif def.paramtype2 == "color4dir" then + color_divisor = 4 elseif def.paramtype2 == "colordegrotate" then color_divisor = 32 end diff --git a/builtin/game/item_s.lua b/builtin/game/item_s.lua index a51cd0a1c..ac1090d63 100644 --- a/builtin/game/item_s.lua +++ b/builtin/game/item_s.lua @@ -92,6 +92,26 @@ function core.facedir_to_dir(facedir) return facedir_to_dir[facedir_to_dir_map[facedir % 32]] end +function core.dir_to_fourdir(dir) + if math.abs(dir.x) > math.abs(dir.z) then + if dir.x < 0 then + return 3 + else + return 1 + end + else + if dir.z < 0 then + return 2 + else + return 0 + end + end +end + +function core.fourdir_to_dir(fourdir) + return facedir_to_dir[facedir_to_dir_map[fourdir % 4]] +end + function core.dir_to_wallmounted(dir) if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then if dir.y < 0 then @@ -137,7 +157,8 @@ end function core.is_colored_paramtype(ptype) return (ptype == "color") or (ptype == "colorfacedir") or - (ptype == "colorwallmounted") or (ptype == "colordegrotate") + (ptype == "color4dir") or (ptype == "colorwallmounted") or + (ptype == "colordegrotate") end function core.strip_param2_color(param2, paramtype2) @@ -146,6 +167,8 @@ function core.strip_param2_color(param2, paramtype2) end if paramtype2 == "colorfacedir" then param2 = math.floor(param2 / 32) * 32 + elseif paramtype2 == "color4dir" then + param2 = math.floor(param2 / 4) * 4 elseif paramtype2 == "colorwallmounted" then param2 = math.floor(param2 / 8) * 8 elseif paramtype2 == "colordegrotate" then diff --git a/doc/lua_api.txt b/doc/lua_api.txt index abdad7f2c..5bac6d165 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -758,6 +758,17 @@ appropriate `paramtype2`: first (= 0 + 1) pixel will be picked from the palette. * `param2 = 35` is 1 * 32 + 3, so the rotation is 3 and the second (= 1 + 1) pixel will be picked from the palette. +* `paramtype2 = "color4dir"` for nodes which use the first + six bits of `param2` for palette indexing. The remaining + two bits are describing rotation, as in `4dir` paramtype2. + Division by 4 yields the palette index (without stretching the + palette). These nodes can have 64 different colors, and the + palette should contain 64 pixels. + Examples: + * `param2 = 17` is 4 * 4 + 1, so the rotation is 1 and the + fifth (= 4 + 1) pixel will be picked from the palette. + * `param2 = 35` is 8 * 4 + 3, so the rotation is 3 and the + ninth (= 8 + 1) pixel will be picked from the palette. To colorize a node on the map, set its `param2` value (according to the node's paramtype2). @@ -1058,18 +1069,36 @@ The function of `param2` is determined by `paramtype2` in node definition. * Supported drawtypes: "torchlike", "signlike", "plantlike", "plantlike_rooted", "normal", "nodebox", "mesh" * 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 * The value denotes at which direction the node is "mounted": 0 = y+, 1 = y-, 2 = x+, 3 = x-, 4 = z+, 5 = z- + * By default, on placement the param2 is automatically set to the + appropriate rotation, depending on which side was pointed at * `paramtype2 = "facedir"` * Supported drawtypes: "normal", "nodebox", "mesh" - * The rotation of the node is stored in `param2`. Furnaces and chests are - rotated this way. Can be made by using `minetest.dir_to_facedir()`. + * The rotation of the node is stored in `param2`. + * Node is rotated around face and axis; 24 rotations in total. + * Can be made by using `minetest.dir_to_facedir()`. + * Chests and furnaces can be rotated that way, and also 'flipped' * Values range 0 - 23 * facedir / 4 = axis direction: 0 = y+, 1 = z+, 2 = z-, 3 = x+, 4 = x-, 5 = y- * facedir modulo 4 = rotation around that axis + * By default, on placement the param2 is automatically set to the + horizondal direction the player was looking at (values 0-3) + * Special case: If the node is a connected nodebox, the nodebox + will NOT rotate, only the textures will. +* `paramtype2 = "4dir"` + * Supported drawtypes: "normal", "nodebox", "mesh" + * The rotation of the node is stored in `param2`. + * Allows node to be rotated horizontally, 4 rotations in total + * Can be made by using `minetest.dir_to_fourdir()`. + * Chests and furnaces can be rotated that way, but not flipped + * Values range 0 - 3 + * 4dir modulo 4 = rotation + * Otherwise, behavior is identical to facedir * `paramtype2 = "leveled"` * Only valid for "nodebox" with 'type = "leveled"', and "plantlike_rooted". * Leveled nodebox: @@ -1112,6 +1141,10 @@ The function of `param2` is determined by `paramtype2` in node definition. * Same as `facedir`, but with colors. * The first three bits of `param2` tells which color is picked from the palette. The palette should have 8 pixels. +* `paramtype2 = "color4dir"` + * Same as `facedir`, but with colors. + * The first six bits of `param2` tells which color is picked from the + palette. The palette should have 64 pixels. * `paramtype2 = "colorwallmounted"` * Same as `wallmounted`, but with colors. * The first five bits of `param2` tells which color is picked from the @@ -5776,6 +5809,12 @@ Item handling * `minetest.facedir_to_dir(facedir)` * Convert a facedir back into a vector aimed directly out the "back" of a node. +* `minetest.dir_to_fourdir(dir)` + * Convert a vector to a 4dir value, used in `param2` for + `paramtype2="4dir"`. +* `minetest.fourdir_to_dir(fourdir)` + * Convert a 4dir back into a vector aimed directly out the "back" of a + node. * `minetest.dir_to_wallmounted(dir)` * Convert a vector to a wallmounted value, used for `paramtype2="wallmounted"`. @@ -5788,7 +5827,7 @@ Item handling * Convert yaw (angle) to a vector * `minetest.is_colored_paramtype(ptype)` * Returns a boolean. Returns `true` if the given `paramtype2` contains - color information (`color`, `colorwallmounted` or `colorfacedir`). + color information (`color`, `colorwallmounted`, `colorfacedir`, etc.). * `minetest.strip_param2_color(param2, paramtype2)` * Removes everything but the color information from the given `param2` value. @@ -7893,7 +7932,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and -- You can set the currently used color as the "palette_index" field of -- the item stack metadata. -- The palette is always stretched to fit indices between 0 and 255, to - -- ensure compatibility with "colorfacedir" and "colorwallmounted" nodes. + -- ensure compatibility with "colorfacedir" (and similar) nodes. color = "#ffffffff", -- Color the item is colorized with. The palette overrides this. diff --git a/games/devtest/mods/testnodes/meshes.lua b/games/devtest/mods/testnodes/meshes.lua index 900abc180..76c2c0027 100644 --- a/games/devtest/mods/testnodes/meshes.lua +++ b/games/devtest/mods/testnodes/meshes.lua @@ -60,6 +60,31 @@ minetest.register_node("testnodes:mesh_colorfacedir", { groups = {dig_immediate=3}, }) +minetest.register_node("testnodes:mesh_4dir", { + description = S("4dir Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes.png"}, + paramtype = "light", + paramtype2 = "4dir", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:mesh_color4dir", { + description = S("Color 4dir Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes3.png"}, + paramtype = "light", + paramtype2 = "color4dir", + palette = "testnodes_palette_4dir.png", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + -- Wallmounted mesh: pyramid minetest.register_node("testnodes:mesh_wallmounted", { description = S("Wallmounted Mesh Test Node"), diff --git a/games/devtest/mods/testnodes/nodeboxes.lua b/games/devtest/mods/testnodes/nodeboxes.lua index 7e966fdce..e3c03b073 100644 --- a/games/devtest/mods/testnodes/nodeboxes.lua +++ b/games/devtest/mods/testnodes/nodeboxes.lua @@ -60,6 +60,25 @@ minetest.register_node("testnodes:nodebox_leveled", { groups = {dig_immediate=3}, }) + +local nodebox_wall = { + type = "connected", + fixed = {-0.125, -0.500, -0.125, 0.125, 0.500, 0.125}, + connect_front = {-0.125, -0.500, -0.500, 0.125, 0.400, -0.125}, + connect_back = {-0.125, -0.500, 0.125, 0.125, 0.400, 0.500}, + connect_left = {-0.500, -0.500, -0.125, -0.125, 0.400, 0.125}, + connect_right = {0.125, -0.500, -0.125, 0.500, 0.400, 0.125}, +} + +local nodebox_wall_thick = { + type = "connected", + fixed = {-0.25, -0.500, -0.25, 0.25, 0.500, 0.25}, + connect_front = {-0.25, -0.500, -0.500, 0.25, 0.400, -0.25}, + connect_back = {-0.25, -0.500, 0.25, 0.25, 0.400, 0.500}, + connect_left = {-0.500, -0.500, -0.25, -0.25, 0.400, 0.25}, + connect_right = {0.25, -0.500, -0.25, 0.500, 0.400, 0.25}, +} + -- Wall-like nodebox that connects to neighbors minetest.register_node("testnodes:nodebox_connected", { description = S("Connected Nodebox Test Node"), @@ -69,13 +88,44 @@ minetest.register_node("testnodes:nodebox_connected", { paramtype = "light", connects_to = {"group:connected_nodebox"}, connect_sides = {"front", "back", "left", "right"}, - node_box = { - type = "connected", - fixed = {-0.125, -0.500, -0.125, 0.125, 0.500, 0.125}, - connect_front = {-0.125, -0.500, -0.500, 0.125, 0.400, -0.125}, - connect_back = {-0.125, -0.500, 0.125, 0.125, 0.400, 0.500}, - connect_left = {-0.500, -0.500, -0.125, -0.125, 0.400, 0.125}, - connect_right = {0.125, -0.500, -0.125, 0.500, 0.400, 0.125}, - }, + node_box = nodebox_wall, +}) + +minetest.register_node("testnodes:nodebox_connected_facedir", { + description = S("Facedir Connected Nodebox Test Node"), + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right"}, + node_box = nodebox_wall_thick, +}) + +minetest.register_node("testnodes:nodebox_connected_4dir", { + description = S("4Dir Connected Nodebox Test Node"), + tiles = { + "testnodes_1.png^[colorize:#FFFF00:127", + "testnodes_2.png^[colorize:#FFFF00:127", + "testnodes_3.png^[colorize:#FFFF00:127", + "testnodes_4.png^[colorize:#FFFF00:127", + "testnodes_5.png^[colorize:#FFFF00:127", + "testnodes_6.png^[colorize:#FFFF00:127", + }, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "4dir", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right"}, + node_box = nodebox_wall_thick, }) diff --git a/games/devtest/mods/testnodes/param2.lua b/games/devtest/mods/testnodes/param2.lua index 5d64376fa..908b54bfc 100644 --- a/games/devtest/mods/testnodes/param2.lua +++ b/games/devtest/mods/testnodes/param2.lua @@ -17,6 +17,21 @@ minetest.register_node("testnodes:facedir", { groups = { dig_immediate = 3 }, }) +minetest.register_node("testnodes:4dir", { + description = S("4dir Test Node"), + paramtype2 = "4dir", + tiles = { + "testnodes_1.png^[colorize:#FFFF00:127", + "testnodes_2.png^[colorize:#FFFF00:127", + "testnodes_3.png^[colorize:#FFFF00:127", + "testnodes_4.png^[colorize:#FFFF00:127", + "testnodes_5.png^[colorize:#FFFF00:127", + "testnodes_6.png^[colorize:#FFFF00:127", + }, + + groups = { dig_immediate = 3 }, +}) + minetest.register_node("testnodes:facedir_nodebox", { description = S("Facedir Nodebox Test Node"), tiles = { @@ -38,6 +53,27 @@ minetest.register_node("testnodes:facedir_nodebox", { groups = {dig_immediate=3}, }) +minetest.register_node("testnodes:4dir_nodebox", { + description = S("4dir Nodebox Test Node"), + tiles = { + "testnodes_1.png^[colorize:#ffff00:127", + "testnodes_2.png^[colorize:#ffff00:127", + "testnodes_3.png^[colorize:#ffff00:127", + "testnodes_4.png^[colorize:#ffff00:127", + "testnodes_5.png^[colorize:#ffff00:127", + "testnodes_6.png^[colorize:#ffff00:127", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "4dir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + minetest.register_node("testnodes:wallmounted", { description = S("Wallmounted Test Node"), paramtype2 = "wallmounted", @@ -125,6 +161,44 @@ minetest.register_node("testnodes:colorfacedir_nodebox", { groups = {dig_immediate=3}, }) +minetest.register_node("testnodes:color4dir", { + description = S("Color 4dir Test Node"), + paramtype2 = "color4dir", + palette = "testnodes_palette_4dir.png", + tiles = { + "testnodes_1g.png", + "testnodes_2g.png", + "testnodes_3g.png", + "testnodes_4g.png", + "testnodes_5g.png", + "testnodes_6g.png", + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:color4dir_nodebox", { + description = S("Color 4dir Nodebox Test Node"), + tiles = { + "testnodes_1g.png", + "testnodes_2g.png", + "testnodes_3g.png", + "testnodes_4g.png", + "testnodes_5g.png", + "testnodes_6g.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "color4dir", + palette = "testnodes_palette_4dir.png", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + minetest.register_node("testnodes:colorwallmounted", { description = S("Color Wallmounted Test Node"), paramtype2 = "colorwallmounted", diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_4dir.png b/games/devtest/mods/testnodes/textures/testnodes_palette_4dir.png new file mode 100644 index 0000000000000000000000000000000000000000..bf5ebf2d581feaad4a5a91b6732213425909e835 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^4nWMv!2~29^4o(rY)RhkE m9fgV?xBTCkVRvo*Q}#param_type_2 == CPT2_FACEDIR || - f->param_type_2 == CPT2_COLORED_FACEDIR) { + f->param_type_2 == CPT2_COLORED_FACEDIR || + f->param_type_2 == CPT2_4DIR || + f->param_type_2 == CPT2_COLORED_4DIR) { facedir = n.getFaceDir(nodedef); } else if (f->param_type_2 == CPT2_WALLMOUNTED || f->param_type_2 == CPT2_COLORED_WALLMOUNTED) { diff --git a/src/client/game.cpp b/src/client/game.cpp index 6a4bff61a..b4926d9bf 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3462,7 +3462,9 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, param2 = dir.Z < 0 ? 5 : 4; } } else if (predicted_f.param_type_2 == CPT2_FACEDIR || - predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) { + predicted_f.param_type_2 == CPT2_COLORED_FACEDIR || + predicted_f.param_type_2 == CPT2_4DIR || + predicted_f.param_type_2 == CPT2_COLORED_4DIR) { v3s16 dir = nodepos - floatToInt(client->getEnv().getLocalPlayer()->getPosition(), BS); if (abs(dir.X) > abs(dir.Z)) { @@ -3501,6 +3503,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, // Apply color if (!place_param2 && (predicted_f.param_type_2 == CPT2_COLOR || predicted_f.param_type_2 == CPT2_COLORED_FACEDIR + || predicted_f.param_type_2 == CPT2_COLORED_4DIR || predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) { const auto &indexstr = selected_item.metadata. getString("palette_index", 0); @@ -3514,6 +3517,9 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, } else if (predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) { // param2 = pure palette index + other param2 = (index & 0xe0) | (param2 & 0x1f); + } else if (predicted_f.param_type_2 == CPT2_COLORED_4DIR) { + // param2 = pure palette index + other + param2 = (index & 0xfc) | (param2 & 0x03); } } } diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 42f020e71..1685dc11c 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -149,6 +149,9 @@ u8 MapNode::getFaceDir(const NodeDefManager *nodemgr, if (f.param_type_2 == CPT2_FACEDIR || f.param_type_2 == CPT2_COLORED_FACEDIR) return (getParam2() & 0x1F) % 24; + if (f.param_type_2 == CPT2_4DIR || + f.param_type_2 == CPT2_COLORED_4DIR) + return getParam2() & 0x03; if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED || f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) return wallmounted_to_facedir[getParam2() & 0x07]; @@ -196,7 +199,8 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot) { ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2; - if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR) { + if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR || + cpt2 == CPT2_4DIR || cpt2 == CPT2_COLORED_4DIR) { static const u8 rotate_facedir[24 * 4] = { // Table value = rotated facedir // Columns: 0, 90, 180, 270 degrees rotation around vertical axis @@ -232,10 +236,17 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot) 22, 21, 20, 23, 23, 22, 21, 20 }; - u8 facedir = (param2 & 31) % 24; - u8 index = facedir * 4 + rot; - param2 &= ~31; - param2 |= rotate_facedir[index]; + if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR) { + u8 facedir = (param2 & 31) % 24; + u8 index = facedir * 4 + rot; + param2 &= ~31; + param2 |= rotate_facedir[index]; + } else if (cpt2 == CPT2_4DIR || cpt2 == CPT2_COLORED_4DIR) { + u8 fourdir = param2 & 3; + u8 index = fourdir + rot; + param2 &= ~3; + param2 |= rotate_facedir[index]; + } } else if (cpt2 == CPT2_WALLMOUNTED || cpt2 == CPT2_COLORED_WALLMOUNTED) { u8 wmountface = (param2 & 7); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index e2a222ed3..f42231736 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -992,6 +992,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc if (param_type_2 == CPT2_COLOR || param_type_2 == CPT2_COLORED_FACEDIR || + param_type_2 == CPT2_COLORED_4DIR || param_type_2 == CPT2_COLORED_WALLMOUNTED || param_type_2 == CPT2_COLORED_DEGROTATE) palette = tsrc->getPalette(palette_name); @@ -1018,6 +1019,15 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc recalculateBoundingBox(mesh_ptr[j]); meshmanip->recalculateNormals(mesh_ptr[j], true, false); } + } else if (tsettings.enable_mesh_cache && mesh_ptr[0] && + (param_type_2 == CPT2_4DIR + || param_type_2 == CPT2_COLORED_4DIR)) { + for (u16 j = 1; j < 4; j++) { + mesh_ptr[j] = cloneMesh(mesh_ptr[0]); + rotateMeshBy6dFacedir(mesh_ptr[j], j); + recalculateBoundingBox(mesh_ptr[j]); + meshmanip->recalculateNormals(mesh_ptr[j], true, false); + } } else if (tsettings.enable_mesh_cache && mesh_ptr[0] && (param_type_2 == CPT2_WALLMOUNTED || param_type_2 == CPT2_COLORED_WALLMOUNTED)) { @@ -1241,7 +1251,9 @@ void getNodeBoxUnion(const NodeBox &nodebox, const ContentFeatures &features, half_processed.MaxEdge.Y = +BS / 2; } if (features.param_type_2 == CPT2_FACEDIR || - features.param_type_2 == CPT2_COLORED_FACEDIR) { + features.param_type_2 == CPT2_COLORED_FACEDIR || + features.param_type_2 == CPT2_4DIR || + features.param_type_2 == CPT2_COLORED_4DIR) { // Get maximal coordinate f32 coords[] = { fabsf(half_processed.MinEdge.X), @@ -1705,7 +1717,9 @@ bool NodeDefManager::nodeboxConnects(MapNode from, MapNode to, // does to node declare usable faces? if (f2.connect_sides > 0) { if ((f2.param_type_2 == CPT2_FACEDIR || - f2.param_type_2 == CPT2_COLORED_FACEDIR) + f2.param_type_2 == CPT2_COLORED_FACEDIR || + f2.param_type_2 == CPT2_4DIR || + f2.param_type_2 == CPT2_COLORED_4DIR) && (connect_face >= 4)) { static const u8 rot[33 * 4] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1719,8 +1733,15 @@ bool NodeDefManager::nodeboxConnects(MapNode from, MapNode to, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 16, 8, 4 // 32 - left }; - return (f2.connect_sides - & rot[(connect_face * 4) + (to.param2 & 0x1F)]); + if (f2.param_type_2 == CPT2_FACEDIR || + f2.param_type_2 == CPT2_COLORED_FACEDIR) { + return (f2.connect_sides + & rot[(connect_face * 4) + (to.param2 & 0x1F)]); + } else if (f2.param_type_2 == CPT2_4DIR || + f2.param_type_2 == CPT2_COLORED_4DIR) { + return (f2.connect_sides + & rot[(connect_face * 4) + (to.param2 & 0x03)]); + } } return (f2.connect_sides & connect_face); } diff --git a/src/nodedef.h b/src/nodedef.h index f4367cba9..b63748e44 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -58,7 +58,7 @@ enum ContentParamType2 CPT2_FULL, // Flowing liquid properties CPT2_FLOWINGLIQUID, - // Direction for chests and furnaces and such + // Direction for chests and furnaces and such (with axis rotation) CPT2_FACEDIR, // Direction for signs, torches and such CPT2_WALLMOUNTED, @@ -78,6 +78,10 @@ enum ContentParamType2 CPT2_GLASSLIKE_LIQUID_LEVEL, // 3 bits of palette index, then degrotate CPT2_COLORED_DEGROTATE, + // Simplified direction for chests and furnaces and such (4 directions) + CPT2_4DIR, + // 6 bits of palette index, then 4dir + CPT2_COLORED_4DIR, }; enum LiquidType diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index f15d41f96..da54edb96 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -673,7 +673,8 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index) !(f.param_type_2 == CPT2_COLOR || f.param_type_2 == CPT2_COLORED_FACEDIR || f.param_type_2 == CPT2_COLORED_WALLMOUNTED || - f.param_type_2 == CPT2_COLORED_DEGROTATE)) + f.param_type_2 == CPT2_COLORED_DEGROTATE || + f.param_type_2 == CPT2_COLORED_4DIR)) warningstream << "Node " << f.name.c_str() << " has a palette, but not a suitable paramtype2." << std::endl; diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 029cb6308..a9638e239 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -66,6 +66,8 @@ struct EnumString ScriptApiNode::es_ContentParamType2[] = {CPT2_COLORED_WALLMOUNTED, "colorwallmounted"}, {CPT2_GLASSLIKE_LIQUID_LEVEL, "glasslikeliquidlevel"}, {CPT2_COLORED_DEGROTATE, "colordegrotate"}, + {CPT2_4DIR, "4dir"}, + {CPT2_COLORED_4DIR, "color4dir"}, {0, NULL}, };