Skip to content

Commit 37b4f0d

Browse files
sofarShadowNinja
authored andcommittedMar 12, 2016
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.
1 parent e737b1c commit 37b4f0d

File tree

6 files changed

+58
-5
lines changed

6 files changed

+58
-5
lines changed
 

‎doc/lua_api.txt

+2
Original file line numberDiff line numberDiff line change
@@ -3477,6 +3477,8 @@ Definition tables
34773477
* Used for nodebox nodes with the type == "connected"
34783478
* Specifies to what neighboring nodes connections will be drawn
34793479
* e.g. `{"group:fence", "default:wood"}` or `"default:stone"` ]]
3480+
connect_sides = { "top", "bottom", "front", "left", "back", "right" }, --[[
3481+
^ Tells connected nodebox nodes to connect only to these sides of this node. ]]
34803482
mesh = "model",
34813483
selection_box = {type="regular"}, -- See "Node boxes" --[[
34823484
^ If drawtype "nodebox" is used and selection_box is nil, then node_box is used. ]]

‎src/collision.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef,
189189
Map *map, MapNode n, int v, int *neighbors)
190190
{
191191
MapNode n2 = map->getNodeNoEx(p);
192-
if (nodedef->nodeboxConnects(n, n2))
192+
if (nodedef->nodeboxConnects(n, n2, v))
193193
*neighbors |= v;
194194
}
195195

‎src/content_mapblock.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef,
167167
MeshMakeData *data, MapNode n, int v, int *neighbors)
168168
{
169169
MapNode n2 = data->m_vmanip.getNodeNoEx(p);
170-
if (nodedef->nodeboxConnects(n, n2))
170+
if (nodedef->nodeboxConnects(n, n2, v))
171171
*neighbors |= v;
172172
}
173173

‎src/nodedef.cpp

+23-2
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ void ContentFeatures::reset()
331331
sound_dug = SimpleSoundSpec();
332332
connects_to.clear();
333333
connects_to_ids.clear();
334+
connect_sides = 0;
334335
}
335336

336337
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
@@ -402,6 +403,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
402403
for (std::set<content_t>::const_iterator i = connects_to_ids.begin();
403404
i != connects_to_ids.end(); ++i)
404405
writeU16(os, *i);
406+
writeU8(os, connect_sides);
405407
}
406408

407409
void ContentFeatures::deSerialize(std::istream &is)
@@ -479,6 +481,7 @@ void ContentFeatures::deSerialize(std::istream &is)
479481
u16 connects_to_size = readU16(is);
480482
for (u16 i = 0; i < connects_to_size; i++)
481483
connects_to_ids.insert(readU16(is));
484+
connect_sides = readU8(is);
482485
}catch(SerializationError &e) {};
483486
}
484487

@@ -517,7 +520,7 @@ class CNodeDefManager: public IWritableNodeDefManager {
517520
virtual void runNodeResolveCallbacks();
518521
virtual void resetNodeResolveState();
519522
virtual void mapNodeboxConnections();
520-
virtual bool nodeboxConnects(MapNode from, MapNode to);
523+
virtual bool nodeboxConnects(MapNode from, MapNode to, u8 connect_face);
521524

522525
private:
523526
void addNameIdMapping(content_t i, std::string name);
@@ -1530,7 +1533,7 @@ void CNodeDefManager::mapNodeboxConnections()
15301533
}
15311534
}
15321535

1533-
bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to)
1536+
bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to, u8 connect_face)
15341537
{
15351538
const ContentFeatures &f1 = get(from);
15361539

@@ -1547,6 +1550,24 @@ bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to)
15471550
// ignores actually looking if back connection exists
15481551
return (f2.connects_to_ids.find(from.param0) != f2.connects_to_ids.end());
15491552

1553+
// does to node declare usable faces?
1554+
if (f2.connect_sides > 0) {
1555+
if ((f2.param_type_2 == CPT2_FACEDIR) && (connect_face >= 4)) {
1556+
static const u8 rot[33 * 4] = {
1557+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1558+
4, 32, 16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 - back
1559+
8, 4, 32, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 - right
1560+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1561+
16, 8, 4, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - front
1562+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1563+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1564+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1565+
32, 16, 8, 4 // 32 - left
1566+
};
1567+
return (f2.connect_sides & rot[(connect_face * 4) + to.param2]);
1568+
}
1569+
return (f2.connect_sides & connect_face);
1570+
}
15501571
// the target is just a regular node, so connect no matter back connection
15511572
return true;
15521573
}

‎src/nodedef.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ struct ContentFeatures
271271
bool legacy_facedir_simple;
272272
// Set to true if wall_mounted used to be set to true
273273
bool legacy_wallmounted;
274+
// for NDT_CONNECTED pairing
275+
u8 connect_sides;
274276

275277
// Sound properties
276278
SimpleSoundSpec sound_footstep;
@@ -325,7 +327,7 @@ class INodeDefManager {
325327

326328
virtual void pendNodeResolve(NodeResolver *nr)=0;
327329
virtual bool cancelNodeResolveCallback(NodeResolver *nr)=0;
328-
virtual bool nodeboxConnects(const MapNode from, const MapNode to)=0;
330+
virtual bool nodeboxConnects(const MapNode from, const MapNode to, u8 connect_face)=0;
329331
};
330332

331333
class IWritableNodeDefManager : public INodeDefManager {

‎src/script/common/c_content.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,34 @@ ContentFeatures read_content_features(lua_State *L, int index)
547547
}
548548
lua_pop(L, 1);
549549

550+
lua_getfield(L, index, "connect_sides");
551+
if (lua_istable(L, -1)) {
552+
int table = lua_gettop(L);
553+
lua_pushnil(L);
554+
while (lua_next(L, table) != 0) {
555+
// Value at -1
556+
std::string side(lua_tostring(L, -1));
557+
// Note faces are flipped to make checking easier
558+
if (side == "top")
559+
f.connect_sides |= 2;
560+
else if (side == "bottom")
561+
f.connect_sides |= 1;
562+
else if (side == "front")
563+
f.connect_sides |= 16;
564+
else if (side == "left")
565+
f.connect_sides |= 32;
566+
else if (side == "back")
567+
f.connect_sides |= 4;
568+
else if (side == "right")
569+
f.connect_sides |= 8;
570+
else
571+
warningstream << "Unknown value for \"connect_sides\": "
572+
<< side << std::endl;
573+
lua_pop(L, 1);
574+
}
575+
}
576+
lua_pop(L, 1);
577+
550578
lua_getfield(L, index, "selection_box");
551579
if(lua_istable(L, -1))
552580
f.selection_box = read_nodebox(L, -1);

5 commit comments

Comments
 (5)

HybridDog commented on Mar 16, 2016

@HybridDog
Contributor

Switching stations are just connecting to the cable if it's below it.
How can you make "foo:hasconnecting" connect to "foo:allsideenter" from all sides but to "foo:justbottomopen" just from below it?

ShadowNinja commented on Mar 20, 2016

@ShadowNinja
Contributor

@HybridDog: Set connect_sides = {"bottom"} on foo:justbottomoopen and leave foo:allsidesenter at the default of all sides.

HybridDog commented on Mar 20, 2016

@HybridDog
Contributor

thanks, l thought connect_sides is part of the nodedef of the connected nodebox node and defines to which side it adds connections, which is actually done by omitting nodeboxes to those sides.

HybridDog commented on Mar 20, 2016

@HybridDog
Contributor

l just noticed that the selection box isn't set to the nodebox:
screenshot_20160320_101448

ShadowNinja commented on Mar 20, 2016

@ShadowNinja
Contributor
Please sign in to comment.