summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt2
-rw-r--r--src/collision.cpp2
-rw-r--r--src/content_mapblock.cpp2
-rw-r--r--src/nodedef.cpp25
-rw-r--r--src/nodedef.h4
-rw-r--r--src/script/common/c_content.cpp28
6 files changed, 58 insertions, 5 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index f51c950c3..733ac8412 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -3477,6 +3477,8 @@ Definition tables
* Used for nodebox nodes with the type == "connected"
* Specifies to what neighboring nodes connections will be drawn
* e.g. `{"group:fence", "default:wood"}` or `"default:stone"` ]]
+ connect_sides = { "top", "bottom", "front", "left", "back", "right" }, --[[
+ ^ Tells connected nodebox nodes to connect only to these sides of this node. ]]
mesh = "model",
selection_box = {type="regular"}, -- See "Node boxes" --[[
^ If drawtype "nodebox" is used and selection_box is nil, then node_box is used. ]]
diff --git a/src/collision.cpp b/src/collision.cpp
index a3979f1dc..16db3310c 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -189,7 +189,7 @@ static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef,
Map *map, MapNode n, int v, int *neighbors)
{
MapNode n2 = map->getNodeNoEx(p);
- if (nodedef->nodeboxConnects(n, n2))
+ if (nodedef->nodeboxConnects(n, n2, v))
*neighbors |= v;
}
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index c2934f26a..6a83bd8f3 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -167,7 +167,7 @@ static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef,
MeshMakeData *data, MapNode n, int v, int *neighbors)
{
MapNode n2 = data->m_vmanip.getNodeNoEx(p);
- if (nodedef->nodeboxConnects(n, n2))
+ if (nodedef->nodeboxConnects(n, n2, v))
*neighbors |= v;
}
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index 85cd848ae..edd02d9f3 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -331,6 +331,7 @@ void ContentFeatures::reset()
sound_dug = SimpleSoundSpec();
connects_to.clear();
connects_to_ids.clear();
+ connect_sides = 0;
}
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
@@ -402,6 +403,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
for (std::set<content_t>::const_iterator i = connects_to_ids.begin();
i != connects_to_ids.end(); ++i)
writeU16(os, *i);
+ writeU8(os, connect_sides);
}
void ContentFeatures::deSerialize(std::istream &is)
@@ -479,6 +481,7 @@ void ContentFeatures::deSerialize(std::istream &is)
u16 connects_to_size = readU16(is);
for (u16 i = 0; i < connects_to_size; i++)
connects_to_ids.insert(readU16(is));
+ connect_sides = readU8(is);
}catch(SerializationError &e) {};
}
@@ -517,7 +520,7 @@ public:
virtual void runNodeResolveCallbacks();
virtual void resetNodeResolveState();
virtual void mapNodeboxConnections();
- virtual bool nodeboxConnects(MapNode from, MapNode to);
+ virtual bool nodeboxConnects(MapNode from, MapNode to, u8 connect_face);
private:
void addNameIdMapping(content_t i, std::string name);
@@ -1530,7 +1533,7 @@ void CNodeDefManager::mapNodeboxConnections()
}
}
-bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to)
+bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to, u8 connect_face)
{
const ContentFeatures &f1 = get(from);
@@ -1547,6 +1550,24 @@ bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to)
// ignores actually looking if back connection exists
return (f2.connects_to_ids.find(from.param0) != f2.connects_to_ids.end());
+ // does to node declare usable faces?
+ if (f2.connect_sides > 0) {
+ if ((f2.param_type_2 == CPT2_FACEDIR) && (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, 0, // 4 - back
+ 8, 4, 32, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 - right
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 8, 4, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - front
+ 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, 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]);
+ }
+ return (f2.connect_sides & connect_face);
+ }
// the target is just a regular node, so connect no matter back connection
return true;
}
diff --git a/src/nodedef.h b/src/nodedef.h
index f92a3a941..58d0faffa 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -271,6 +271,8 @@ struct ContentFeatures
bool legacy_facedir_simple;
// Set to true if wall_mounted used to be set to true
bool legacy_wallmounted;
+ // for NDT_CONNECTED pairing
+ u8 connect_sides;
// Sound properties
SimpleSoundSpec sound_footstep;
@@ -325,7 +327,7 @@ public:
virtual void pendNodeResolve(NodeResolver *nr)=0;
virtual bool cancelNodeResolveCallback(NodeResolver *nr)=0;
- virtual bool nodeboxConnects(const MapNode from, const MapNode to)=0;
+ virtual bool nodeboxConnects(const MapNode from, const MapNode to, u8 connect_face)=0;
};
class IWritableNodeDefManager : public INodeDefManager {
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index ababf0718..06e20c2a0 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -547,6 +547,34 @@ ContentFeatures read_content_features(lua_State *L, int index)
}
lua_pop(L, 1);
+ lua_getfield(L, index, "connect_sides");
+ if (lua_istable(L, -1)) {
+ int table = lua_gettop(L);
+ lua_pushnil(L);
+ while (lua_next(L, table) != 0) {
+ // Value at -1
+ std::string side(lua_tostring(L, -1));
+ // Note faces are flipped to make checking easier
+ if (side == "top")
+ f.connect_sides |= 2;
+ else if (side == "bottom")
+ f.connect_sides |= 1;
+ else if (side == "front")
+ f.connect_sides |= 16;
+ else if (side == "left")
+ f.connect_sides |= 32;
+ else if (side == "back")
+ f.connect_sides |= 4;
+ else if (side == "right")
+ f.connect_sides |= 8;
+ else
+ warningstream << "Unknown value for \"connect_sides\": "
+ << side << std::endl;
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+
lua_getfield(L, index, "selection_box");
if(lua_istable(L, -1))
f.selection_box = read_nodebox(L, -1);