diff options
author | Auke Kok <sofar@foo-projects.org> | 2016-03-03 23:18:04 -0800 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2016-03-12 12:08:17 -0500 |
commit | 37b4f0d34c73de58e0f5d153b7e699dc7430e23d (patch) | |
tree | 5c1f23df722ef9bc2c1110d78016439b26b35772 /src/nodedef.cpp | |
parent | e737b1c271c9d957651ef2201bb820e4465358bf (diff) | |
download | minetest-37b4f0d34c73de58e0f5d153b7e699dc7430e23d.tar.gz minetest-37b4f0d34c73de58e0f5d153b7e699dc7430e23d.tar.bz2 minetest-37b4f0d34c73de58e0f5d153b7e699dc7430e23d.zip |
Allow nodes to specify which sides to connect to.
NDT_CONNECTED attempts to connect to any side of nodes that it can
connect to, which is troublesome for FACEDIR type nodes that generally
may only have one usable face, and can be rotated.
We introduce a node parameter `connect_sides` that is valid for
any node type. If specified, it lists faces of the node (in "top",
"bottom", "front", "left", "back", "right", form, as array) that
connecting nodeboxes can connect to. "front" corresponds to the south
facing side of a node with facedir = 0.
If the node is rotatable using *simple* FACEDIR, then the attached
face is properly rotated before checking. This allows e.g. a chest
to be attached to only from the rear side.
Diffstat (limited to 'src/nodedef.cpp')
-rw-r--r-- | src/nodedef.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
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; } |