From e113db1478326f4adf622cebf82307551a98b462 Mon Sep 17 00:00:00 2001 From: Treer Date: Sun, 1 Mar 2020 18:02:35 +1100 Subject: [PATCH 1/2] Add facedir support to Portals API Portal shematics include facedir information for when new portals are spawned using frame nodes that are facedir or colorfacedir --- portal_api.lua | 116 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 40 deletions(-) diff --git a/portal_api.lua b/portal_api.lua index 13ab3ca..8f1b31a 100644 --- a/portal_api.lua +++ b/portal_api.lua @@ -113,9 +113,23 @@ metadata). ]] -local __ = {name = "air", prob = 0} -local AA = {name = "air", prob = 255, force_place = true} -local OO = {name = "default:obsidian", prob = 255, force_place = true} +local facedir_up, facedir_north, facedir_south, facedir_east, facedir_west, facedir_down = 0, 4, 8, 12, 16, 20 + +local __ = {name = "air", prob = 0} +local AA = {name = "air", prob = 255, force_place = true} +local ON = {name = "default:obsidian", facedir = facedir_north + 0, prob = 255, force_place = true} +local ON2 = {name = "default:obsidian", facedir = facedir_north + 1, prob = 255, force_place = true} +local ON3 = {name = "default:obsidian", facedir = facedir_north + 2, prob = 255, force_place = true} +local ON4 = {name = "default:obsidian", facedir = facedir_north + 3, prob = 255, force_place = true} +local OS = {name = "default:obsidian", facedir = facedir_south, prob = 255, force_place = true} +local OE = {name = "default:obsidian", facedir = facedir_east, prob = 255, force_place = true} +local OW = {name = "default:obsidian", facedir = facedir_west, prob = 255, force_place = true} +local OU = {name = "default:obsidian", facedir = facedir_up + 0, prob = 255, force_place = true} +local OU2 = {name = "default:obsidian", facedir = facedir_up + 1, prob = 255, force_place = true} +local OU3 = {name = "default:obsidian", facedir = facedir_up + 2, prob = 255, force_place = true} +local OU4 = {name = "default:obsidian", facedir = facedir_up + 3, prob = 255, force_place = true} +local OD = {name = "default:obsidian", facedir = facedir_down, prob = 255, force_place = true} +local facedirNodeList = {ON, ON2, ON3, ON4, OS, OE, OW, OU, OU2, OU3, OU4, OD} -- a list of node references which should have their facedir value copied into param2 before placing a schematic -- This object defines a portal's shape, segregating the shape logic code from portal behaviour code. -- You can create a new "PortalShape" definition object which implements the same @@ -285,25 +299,26 @@ nether.PortalShape_Traditional = { AA,AA,AA,AA, AA,AA,AA,AA, AA,AA,AA,AA, - - OO,OO,OO,OO, - OO,AA,AA,OO, - OO,AA,AA,OO, - OO,AA,AA,OO, - OO,OO,OO,OO, - + + ON,OW,OE,ON2, + OU,AA,AA,OU, + OU,AA,AA,OU, + OU,AA,AA,OU, + ON4,OE,OW,ON3, + __,__,__,__, AA,AA,AA,AA, AA,AA,AA,AA, AA,AA,AA,AA, AA,AA,AA,AA, - + __,__,__,__, AA,AA,AA,AA, AA,AA,AA,AA, AA,AA,AA,AA, AA,AA,AA,AA, - } + }, + facedirNodes = facedirNodeList } } -- End of PortalShape_Traditional class @@ -449,7 +464,7 @@ nether.PortalShape_Circular = { __,__,AA,AA,AA,__,__, __,__,__,__,__,__,__, __,__,__,__,__,__,__, - + __,__,__,__,__,__,__, __,AA,AA,AA,AA,AA,__, __,AA,AA,AA,AA,AA,__, @@ -457,7 +472,7 @@ nether.PortalShape_Circular = { __,AA,AA,AA,AA,AA,__, __,AA,AA,AA,AA,AA,__, __,__,__,__,__,__,__, - + __,__,__,__,__,__,__, __,AA,AA,AA,AA,AA,__, AA,AA,AA,AA,AA,AA,AA, @@ -465,15 +480,15 @@ nether.PortalShape_Circular = { AA,AA,AA,AA,AA,AA,AA, __,AA,AA,AA,AA,AA,__, __,__,AA,AA,AA,__,__, - - __,__,OO,OO,OO,__,__, - __,OO,AA,AA,AA,OO,__, - OO,AA,AA,AA,AA,AA,OO, - OO,AA,AA,AA,AA,AA,OO, - OO,AA,AA,AA,AA,AA,OO, - __,OO,AA,AA,AA,OO,__, - __,__,OO,OO,OO,__,__, - + + __,__,OW,OW,OW,__,__, + __,ON,AA,AA,AA,ON2,__, + OU,AA,AA,AA,AA,AA,OD, + OU,AA,AA,AA,AA,AA,OD, + OU,AA,AA,AA,AA,AA,OD, + __,ON4,AA,AA,AA,ON3,__, + __,__,OE,OE,OE,__,__, + __,__,__,__,__,__,__, __,AA,AA,AA,AA,AA,__, AA,AA,AA,AA,AA,AA,AA, @@ -481,7 +496,7 @@ nether.PortalShape_Circular = { AA,AA,AA,AA,AA,AA,AA, __,AA,AA,AA,AA,AA,__, __,__,AA,AA,AA,__,__, - + __,__,__,__,__,__,__, __,AA,AA,AA,AA,AA,__, __,AA,AA,AA,AA,AA,__, @@ -497,7 +512,8 @@ nether.PortalShape_Circular = { __,__,AA,AA,AA,__,__, __,__,__,__,__,__,__, __,__,__,__,__,__,__, - } + }, + facedirNodes = facedirNodeList } } -- End of PortalShape_Circular class @@ -597,35 +613,36 @@ nether.PortalShape_Platform = { size = {x = 5, y = 5, z = 5}, data = { -- note that data is upside down __,__,__,__,__, - OO,OO,OO,OO,OO, + OU4,OW,OW,OW,OU3, __,AA,AA,AA,__, __,AA,AA,AA,__, __,__,__,__,__, - - __,OO,OO,OO,__, - OO,AA,AA,AA,OO, + + __,OU4,OW,OU3,__, + ON,AA,AA,AA,OS, AA,AA,AA,AA,AA, AA,AA,AA,AA,AA, __,AA,AA,AA,__, - - __,OO,OO,OO,__, - OO,AA,AA,AA,OO, + + __,ON,OD,OS,__, + ON,AA,AA,AA,OS, AA,AA,AA,AA,AA, AA,AA,AA,AA,AA, __,AA,AA,AA,__, - - __,OO,OO,OO,__, - OO,AA,AA,AA,OO, + + __,OU,OE,OU2,__, + ON,AA,AA,AA,OS, AA,AA,AA,AA,AA, AA,AA,AA,AA,AA, __,AA,AA,AA,__, - + __,__,__,__,__, - OO,OO,OO,OO,OO, + OU,OE,OE,OE,OU2, __,AA,AA,AA,__, __,AA,AA,AA,__, __,__,__,__,__, - } + }, + facedirNodes = facedirNodeList } } -- End of PortalShape_Platform class @@ -1137,8 +1154,27 @@ local function is_within_portal_frame(portal_definition, pos) end +-- sets param2 values in the schematic to match facedir values, or 0 if the portalframe-nodedef doesn't use facedir +local function set_schematic_param2(schematic_table, frame_node_name) + + local paramtype2 = minetest.registered_nodes[frame_node_name].paramtype2 + local isFacedir = paramtype2 == "facedir" or paramtype2 == "colorfacedir" + + if schematic_table.facedirNodes ~= nil then + for _, node in ipairs(schematic_table.facedirNodes) do + if isFacedir and node.facedir ~= nil then + node.param2 = node.facedir + else + node.param2 = 0 + end + end + end +end + local function build_portal(portal_definition, anchorPos, orientation, destination_wormholePos) + set_schematic_param2(portal_definition.shape.schematic, portal_definition.frame_node_name) + minetest.place_schematic( portal_definition.shape.get_schematicPos_from_anchorPos(anchorPos, orientation), portal_definition.shape.schematic, @@ -1178,8 +1214,8 @@ local function remote_portal_checkup(elapsed, portal_definition, anchorPos, orie local wormholePos = portal_definition.shape.get_wormholePos_from_anchorPos(anchorPos, orientation) local wormhole_node = minetest.get_node_or_nil(wormholePos) - local portalFound, portalLit = false, false - if wormhole_node ~= nil and wormhole_node.name == portal_definition.wormhole_node_name then + local portalFound, portalLit = false, false + if wormhole_node ~= nil and wormhole_node.name == portal_definition.wormhole_node_name then -- a wormhole node was there, but check the whole frame is intact portalFound, portalLit = is_portal_at_anchorPos(portal_definition, anchorPos, orientation, false) end From e5fbc2486b0315a06714f4d9da9b7f6e9b506dd6 Mon Sep 17 00:00:00 2001 From: Treer Date: Sun, 31 May 2020 19:05:40 +1000 Subject: [PATCH 2/2] Allow a colorfacedir color to be specified for a portal's frame node A color could also be specified via param2 in a portal schematic. --- portal_api.lua | 19 +++++++++++++++---- portal_api.txt | 6 ++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/portal_api.lua b/portal_api.lua index 8f1b31a..00b43da 100644 --- a/portal_api.lua +++ b/portal_api.lua @@ -129,7 +129,12 @@ local OU2 = {name = "default:obsidian", facedir = facedir_up + 1, prob = 255, local OU3 = {name = "default:obsidian", facedir = facedir_up + 2, prob = 255, force_place = true} local OU4 = {name = "default:obsidian", facedir = facedir_up + 3, prob = 255, force_place = true} local OD = {name = "default:obsidian", facedir = facedir_down, prob = 255, force_place = true} -local facedirNodeList = {ON, ON2, ON3, ON4, OS, OE, OW, OU, OU2, OU3, OU4, OD} -- a list of node references which should have their facedir value copied into param2 before placing a schematic + +-- facedirNodeList is a list of node references which should have their facedir value copied into +-- param2 before placing a schematic. The facedir values will only be copied when the portal's frame +-- node has a paramtype2 of "facedir" or "colorfacedir". +-- Having schematics provide this list avoids needing to check every node in the schematic volume. +local facedirNodeList = {ON, ON2, ON3, ON4, OS, OE, OW, OU, OU2, OU3, OU4, OD} -- This object defines a portal's shape, segregating the shape logic code from portal behaviour code. -- You can create a new "PortalShape" definition object which implements the same @@ -1155,7 +1160,7 @@ end -- sets param2 values in the schematic to match facedir values, or 0 if the portalframe-nodedef doesn't use facedir -local function set_schematic_param2(schematic_table, frame_node_name) +local function set_schematic_param2(schematic_table, frame_node_name, frame_node_color) local paramtype2 = minetest.registered_nodes[frame_node_name].paramtype2 local isFacedir = paramtype2 == "facedir" or paramtype2 == "colorfacedir" @@ -1163,7 +1168,9 @@ local function set_schematic_param2(schematic_table, frame_node_name) if schematic_table.facedirNodes ~= nil then for _, node in ipairs(schematic_table.facedirNodes) do if isFacedir and node.facedir ~= nil then - node.param2 = node.facedir + -- frame_node_color can be nil + local colorBits = (frame_node_color or math.floor((node.param2 or 0) / 32)) * 32 + node.param2 = node.facedir + colorBits else node.param2 = 0 end @@ -1173,7 +1180,7 @@ end local function build_portal(portal_definition, anchorPos, orientation, destination_wormholePos) - set_schematic_param2(portal_definition.shape.schematic, portal_definition.frame_node_name) + set_schematic_param2(portal_definition.shape.schematic, portal_definition.frame_node_name, portal_definition.frame_node_color) minetest.place_schematic( portal_definition.shape.get_schematicPos_from_anchorPos(anchorPos, orientation), @@ -1900,6 +1907,10 @@ function test_portaldef_is_valid(portal_definition) assert(portal_definition.wormhole_node_color >= 0 and portal_definition.wormhole_node_color < 8, "portaldef.wormhole_node_color must be between 0 and 7 (inclusive)") assert(portal_definition.is_within_realm ~= nil, "portaldef.is_within_realm() must be implemented") assert(portal_definition.find_realm_anchorPos ~= nil, "portaldef.find_realm_anchorPos() must be implemented") + + if portal_definition.frame_node_color ~= nil then + assert(portal_definition.frame_node_color >= 0 and portal_definition.frame_node_color < 8, "portal_definition.frame_node_color must be between 0 and 7 (inclusive)") + end -- todo return result diff --git a/portal_api.txt b/portal_api.txt index e6cf533..42c4bd4 100644 --- a/portal_api.txt +++ b/portal_api.txt @@ -115,6 +115,12 @@ Used by `nether.register_portal`. -- Required. For best results, have your portal constructed of a -- material nobody else is using. + frame_node_color = 0, + -- Optional. + -- A value from 0 to 7. Only used if the frame node's paramtype2 is + -- "colorfacedir", in which case this color will be used when a remote + -- portal is created. + shape = nether.PortalShape_Traditional, -- Optional. -- Shapes available are: