2024-10-28 15:57:39 +01:00
|
|
|
|
// Luanti
|
|
|
|
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
2010-12-14 00:59:56 +01:00
|
|
|
|
|
2024-09-02 16:09:32 +02:00
|
|
|
|
#include "irrlichttypes_bloated.h"
|
2010-12-14 00:59:56 +01:00
|
|
|
|
#include "mapnode.h"
|
2011-01-07 18:39:27 +01:00
|
|
|
|
#include "porting.h"
|
2011-11-14 20:41:30 +01:00
|
|
|
|
#include "nodedef.h"
|
2017-01-04 19:18:40 +01:00
|
|
|
|
#include "map.h"
|
2017-06-06 16:19:04 +02:00
|
|
|
|
#include "content_mapnode.h" // For mapnode_translate_*_internal
|
2011-11-15 20:00:39 +01:00
|
|
|
|
#include "serialization.h" // For ser_ver_supported
|
2012-06-17 01:40:36 +02:00
|
|
|
|
#include "util/serialize.h"
|
2013-07-27 20:34:30 +02:00
|
|
|
|
#include "log.h"
|
2017-10-15 09:34:14 +02:00
|
|
|
|
#include "util/directiontables.h"
|
2014-11-20 04:36:58 +01:00
|
|
|
|
#include "util/numeric.h"
|
2012-06-17 01:40:36 +02:00
|
|
|
|
#include <string>
|
|
|
|
|
#include <sstream>
|
2011-04-04 10:18:14 +02:00
|
|
|
|
|
2013-07-08 21:19:22 +02:00
|
|
|
|
static const Rotation wallmounted_to_rot[] = {
|
|
|
|
|
ROTATE_0, ROTATE_180, ROTATE_90, ROTATE_270
|
|
|
|
|
};
|
2013-07-09 00:50:29 +02:00
|
|
|
|
|
2013-07-08 21:19:22 +02:00
|
|
|
|
static const u8 rot_to_wallmounted[] = {
|
|
|
|
|
2, 4, 3, 5
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-11-13 09:57:55 +01:00
|
|
|
|
/*
|
|
|
|
|
MapNode
|
|
|
|
|
*/
|
|
|
|
|
|
2017-01-12 15:46:30 +01:00
|
|
|
|
void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const
|
|
|
|
|
{
|
|
|
|
|
if (f.palette) {
|
|
|
|
|
*color = (*f.palette)[param2];
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*color = f.color;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
|
|
|
|
|
bool allow_wallmounted) const
|
2010-12-14 00:59:56 +01:00
|
|
|
|
{
|
2012-01-21 00:11:44 +01:00
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
2017-01-12 15:46:30 +01:00
|
|
|
|
if (f.param_type_2 == CPT2_FACEDIR ||
|
|
|
|
|
f.param_type_2 == CPT2_COLORED_FACEDIR)
|
2015-01-09 06:42:03 +01:00
|
|
|
|
return (getParam2() & 0x1F) % 24;
|
2022-09-16 13:18:55 +02:00
|
|
|
|
if (f.param_type_2 == CPT2_4DIR ||
|
|
|
|
|
f.param_type_2 == CPT2_COLORED_4DIR)
|
|
|
|
|
return getParam2() & 0x03;
|
2017-10-15 09:34:14 +02:00
|
|
|
|
if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED ||
|
2023-05-18 20:31:04 +02:00
|
|
|
|
f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
|
|
|
|
|
u8 wmountface = MYMIN(getParam2() & 0x07, DWM_COUNT - 1);
|
|
|
|
|
return wallmounted_to_facedir[wmountface];
|
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
u8 MapNode::getWallMounted(const NodeDefManager *nodemgr) const
|
2012-01-21 00:11:44 +01:00
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
2017-01-12 15:46:30 +01:00
|
|
|
|
if (f.param_type_2 == CPT2_WALLMOUNTED ||
|
2023-05-18 20:31:04 +02:00
|
|
|
|
f.param_type_2 == CPT2_COLORED_WALLMOUNTED)
|
|
|
|
|
return MYMIN(getParam2() & 0x07, DWM_COUNT - 1);
|
|
|
|
|
else if (f.drawtype == NDT_SIGNLIKE || f.drawtype == NDT_TORCHLIKE ||
|
2021-07-15 21:19:59 +02:00
|
|
|
|
f.drawtype == NDT_PLANTLIKE ||
|
|
|
|
|
f.drawtype == NDT_PLANTLIKE_ROOTED) {
|
2021-04-20 19:50:03 +02:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
v3s16 MapNode::getWallMountedDir(const NodeDefManager *nodemgr) const
|
2012-01-21 00:11:44 +01:00
|
|
|
|
{
|
|
|
|
|
switch(getWallMounted(nodemgr))
|
2011-01-25 23:41:06 +01:00
|
|
|
|
{
|
2012-01-21 00:11:44 +01:00
|
|
|
|
case 0: default: return v3s16(0,1,0);
|
|
|
|
|
case 1: return v3s16(0,-1,0);
|
|
|
|
|
case 2: return v3s16(1,0,0);
|
|
|
|
|
case 3: return v3s16(-1,0,0);
|
|
|
|
|
case 4: return v3s16(0,0,1);
|
|
|
|
|
case 5: return v3s16(0,0,-1);
|
2024-01-17 17:47:06 +01:00
|
|
|
|
case 6: return v3s16(0,1,0);
|
|
|
|
|
case 7: return v3s16(0,-1,0);
|
2011-01-25 23:41:06 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-30 00:25:11 +02:00
|
|
|
|
u8 MapNode::getDegRotate(const NodeDefManager *nodemgr) const
|
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
|
|
|
|
if (f.param_type_2 == CPT2_DEGROTATE)
|
|
|
|
|
return getParam2() % 240;
|
|
|
|
|
if (f.param_type_2 == CPT2_COLORED_DEGROTATE)
|
|
|
|
|
return 10 * ((getParam2() & 0x1F) % 24);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
|
2015-09-21 02:21:28 +02:00
|
|
|
|
{
|
2013-07-08 21:19:22 +02:00
|
|
|
|
ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2;
|
|
|
|
|
|
2022-09-16 13:18:55 +02:00
|
|
|
|
if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR ||
|
|
|
|
|
cpt2 == CPT2_4DIR || cpt2 == CPT2_COLORED_4DIR) {
|
2015-10-02 02:07:57 +02:00
|
|
|
|
static const u8 rotate_facedir[24 * 4] = {
|
2015-09-21 02:21:28 +02:00
|
|
|
|
// Table value = rotated facedir
|
|
|
|
|
// Columns: 0, 90, 180, 270 degrees rotation around vertical axis
|
|
|
|
|
// Rotation is anticlockwise as seen from above (+Y)
|
|
|
|
|
|
|
|
|
|
0, 1, 2, 3, // Initial facedir 0 to 3
|
|
|
|
|
1, 2, 3, 0,
|
|
|
|
|
2, 3, 0, 1,
|
|
|
|
|
3, 0, 1, 2,
|
|
|
|
|
|
|
|
|
|
4, 13, 10, 19, // 4 to 7
|
|
|
|
|
5, 14, 11, 16,
|
|
|
|
|
6, 15, 8, 17,
|
|
|
|
|
7, 12, 9, 18,
|
|
|
|
|
|
|
|
|
|
8, 17, 6, 15, // 8 to 11
|
|
|
|
|
9, 18, 7, 12,
|
|
|
|
|
10, 19, 4, 13,
|
|
|
|
|
11, 16, 5, 14,
|
|
|
|
|
|
|
|
|
|
12, 9, 18, 7, // 12 to 15
|
|
|
|
|
13, 10, 19, 4,
|
|
|
|
|
14, 11, 16, 5,
|
|
|
|
|
15, 8, 17, 6,
|
|
|
|
|
|
|
|
|
|
16, 5, 14, 11, // 16 to 19
|
|
|
|
|
17, 6, 15, 8,
|
|
|
|
|
18, 7, 12, 9,
|
|
|
|
|
19, 4, 13, 10,
|
|
|
|
|
|
|
|
|
|
20, 23, 22, 21, // 20 to 23
|
|
|
|
|
21, 20, 23, 22,
|
|
|
|
|
22, 21, 20, 23,
|
|
|
|
|
23, 22, 21, 20
|
|
|
|
|
};
|
2022-09-16 13:18:55 +02:00
|
|
|
|
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;
|
2023-05-11 22:50:52 +02:00
|
|
|
|
u8 index = fourdir * 4 + rot;
|
2022-09-16 13:18:55 +02:00
|
|
|
|
param2 &= ~3;
|
|
|
|
|
param2 |= rotate_facedir[index];
|
|
|
|
|
}
|
2017-01-12 15:46:30 +01:00
|
|
|
|
} else if (cpt2 == CPT2_WALLMOUNTED ||
|
|
|
|
|
cpt2 == CPT2_COLORED_WALLMOUNTED) {
|
2023-05-18 20:31:04 +02:00
|
|
|
|
u8 wmountface = MYMIN(param2 & 0x07, DWM_COUNT - 1);
|
2015-09-21 02:21:28 +02:00
|
|
|
|
if (wmountface <= 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Rotation oldrot = wallmounted_to_rot[wmountface - 2];
|
|
|
|
|
param2 &= ~7;
|
|
|
|
|
param2 |= rot_to_wallmounted[(oldrot - rot) & 3];
|
2021-03-30 00:25:11 +02:00
|
|
|
|
} else if (cpt2 == CPT2_DEGROTATE) {
|
|
|
|
|
int angle = param2; // in 1.5°
|
|
|
|
|
angle += 60 * rot; // don’t do that on u8
|
|
|
|
|
angle %= 240;
|
|
|
|
|
param2 = angle;
|
|
|
|
|
} else if (cpt2 == CPT2_COLORED_DEGROTATE) {
|
|
|
|
|
int angle = param2 & 0x1F; // in 15°
|
|
|
|
|
int color = param2 & 0xE0;
|
|
|
|
|
angle += 6 * rot;
|
|
|
|
|
angle %= 24;
|
|
|
|
|
param2 = color | angle;
|
2015-09-21 02:21:28 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
|
2018-02-10 21:04:16 +01:00
|
|
|
|
const NodeDefManager *nodemgr, std::vector<aabb3f> *p_boxes,
|
|
|
|
|
u8 neighbors = 0)
|
2012-03-19 04:25:09 +01:00
|
|
|
|
{
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
std::vector<aabb3f> &boxes = *p_boxes;
|
|
|
|
|
|
|
|
|
|
if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
const auto &fixed = nodebox.fixed;
|
2017-10-15 09:34:14 +02:00
|
|
|
|
int facedir = n.getFaceDir(nodemgr, true);
|
2013-03-23 19:17:00 +01:00
|
|
|
|
u8 axisdir = facedir>>2;
|
|
|
|
|
facedir&=0x03;
|
2022-05-09 20:59:28 +02:00
|
|
|
|
|
|
|
|
|
boxes.reserve(boxes.size() + fixed.size());
|
2017-08-18 18:18:25 +02:00
|
|
|
|
for (aabb3f box : fixed) {
|
2017-09-18 06:08:56 +02:00
|
|
|
|
if (nodebox.type == NODEBOX_LEVELED)
|
|
|
|
|
box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS;
|
2013-07-13 19:48:14 +02:00
|
|
|
|
|
2017-08-18 18:18:25 +02:00
|
|
|
|
switch (axisdir) {
|
2013-03-23 19:17:00 +01:00
|
|
|
|
case 0:
|
|
|
|
|
if(facedir == 1)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXZBy(-90);
|
|
|
|
|
box.MaxEdge.rotateXZBy(-90);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 2)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXZBy(180);
|
|
|
|
|
box.MaxEdge.rotateXZBy(180);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 3)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXZBy(90);
|
|
|
|
|
box.MaxEdge.rotateXZBy(90);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 1: // z+
|
|
|
|
|
box.MinEdge.rotateYZBy(90);
|
|
|
|
|
box.MaxEdge.rotateYZBy(90);
|
|
|
|
|
if(facedir == 1)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXYBy(90);
|
|
|
|
|
box.MaxEdge.rotateXYBy(90);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 2)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXYBy(180);
|
|
|
|
|
box.MaxEdge.rotateXYBy(180);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 3)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXYBy(-90);
|
|
|
|
|
box.MaxEdge.rotateXYBy(-90);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 2: //z-
|
|
|
|
|
box.MinEdge.rotateYZBy(-90);
|
|
|
|
|
box.MaxEdge.rotateYZBy(-90);
|
|
|
|
|
if(facedir == 1)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXYBy(-90);
|
|
|
|
|
box.MaxEdge.rotateXYBy(-90);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 2)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXYBy(180);
|
|
|
|
|
box.MaxEdge.rotateXYBy(180);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 3)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXYBy(90);
|
|
|
|
|
box.MaxEdge.rotateXYBy(90);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 3: //x+
|
|
|
|
|
box.MinEdge.rotateXYBy(-90);
|
|
|
|
|
box.MaxEdge.rotateXYBy(-90);
|
|
|
|
|
if(facedir == 1)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateYZBy(90);
|
|
|
|
|
box.MaxEdge.rotateYZBy(90);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 2)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateYZBy(180);
|
|
|
|
|
box.MaxEdge.rotateYZBy(180);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 3)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateYZBy(-90);
|
|
|
|
|
box.MaxEdge.rotateYZBy(-90);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 4: //x-
|
|
|
|
|
box.MinEdge.rotateXYBy(90);
|
|
|
|
|
box.MaxEdge.rotateXYBy(90);
|
|
|
|
|
if(facedir == 1)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateYZBy(-90);
|
|
|
|
|
box.MaxEdge.rotateYZBy(-90);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 2)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateYZBy(180);
|
|
|
|
|
box.MaxEdge.rotateYZBy(180);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 3)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateYZBy(90);
|
|
|
|
|
box.MaxEdge.rotateYZBy(90);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
box.MinEdge.rotateXYBy(-180);
|
|
|
|
|
box.MaxEdge.rotateXYBy(-180);
|
|
|
|
|
if(facedir == 1)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXZBy(90);
|
|
|
|
|
box.MaxEdge.rotateXZBy(90);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 2)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXZBy(180);
|
|
|
|
|
box.MaxEdge.rotateXZBy(180);
|
|
|
|
|
}
|
|
|
|
|
else if(facedir == 3)
|
|
|
|
|
{
|
|
|
|
|
box.MinEdge.rotateXZBy(-90);
|
|
|
|
|
box.MaxEdge.rotateXZBy(-90);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
2013-03-23 19:17:00 +01:00
|
|
|
|
box.repair();
|
2012-03-19 04:25:09 +01:00
|
|
|
|
boxes.push_back(box);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(nodebox.type == NODEBOX_WALLMOUNTED)
|
|
|
|
|
{
|
|
|
|
|
v3s16 dir = n.getWallMountedDir(nodemgr);
|
2024-01-17 17:47:06 +01:00
|
|
|
|
u8 wall = n.getWallMounted(nodemgr);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
|
|
|
|
|
// top
|
|
|
|
|
if(dir == v3s16(0,1,0))
|
|
|
|
|
{
|
2024-01-17 17:47:06 +01:00
|
|
|
|
if (wall == DWM_S1) {
|
|
|
|
|
v3f vertices[2] =
|
|
|
|
|
{
|
|
|
|
|
nodebox.wall_top.MinEdge,
|
|
|
|
|
nodebox.wall_top.MaxEdge
|
|
|
|
|
};
|
|
|
|
|
for (v3f &vertex : vertices) {
|
|
|
|
|
vertex.rotateXZBy(90);
|
|
|
|
|
}
|
|
|
|
|
aabb3f box = aabb3f(vertices[0]);
|
|
|
|
|
box.addInternalPoint(vertices[1]);
|
|
|
|
|
boxes.push_back(box);
|
|
|
|
|
} else {
|
|
|
|
|
boxes.push_back(nodebox.wall_top);
|
|
|
|
|
}
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
|
|
|
|
// bottom
|
|
|
|
|
else if(dir == v3s16(0,-1,0))
|
|
|
|
|
{
|
2024-01-17 17:47:06 +01:00
|
|
|
|
if (wall == DWM_S2) {
|
|
|
|
|
v3f vertices[2] =
|
|
|
|
|
{
|
|
|
|
|
nodebox.wall_bottom.MinEdge,
|
|
|
|
|
nodebox.wall_bottom.MaxEdge
|
|
|
|
|
};
|
|
|
|
|
for (v3f &vertex : vertices) {
|
|
|
|
|
vertex.rotateXZBy(-90);
|
|
|
|
|
}
|
|
|
|
|
aabb3f box = aabb3f(vertices[0]);
|
|
|
|
|
box.addInternalPoint(vertices[1]);
|
|
|
|
|
boxes.push_back(box);
|
|
|
|
|
} else {
|
|
|
|
|
boxes.push_back(nodebox.wall_bottom);
|
|
|
|
|
}
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
|
|
|
|
// side
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
v3f vertices[2] =
|
|
|
|
|
{
|
|
|
|
|
nodebox.wall_side.MinEdge,
|
|
|
|
|
nodebox.wall_side.MaxEdge
|
|
|
|
|
};
|
|
|
|
|
|
2017-08-19 14:25:35 +02:00
|
|
|
|
for (v3f &vertex : vertices) {
|
2012-03-19 04:25:09 +01:00
|
|
|
|
if(dir == v3s16(-1,0,0))
|
2017-08-19 14:25:35 +02:00
|
|
|
|
vertex.rotateXZBy(0);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
if(dir == v3s16(1,0,0))
|
2017-08-19 14:25:35 +02:00
|
|
|
|
vertex.rotateXZBy(180);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
if(dir == v3s16(0,0,-1))
|
2017-08-19 14:25:35 +02:00
|
|
|
|
vertex.rotateXZBy(90);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
if(dir == v3s16(0,0,1))
|
2017-08-19 14:25:35 +02:00
|
|
|
|
vertex.rotateXZBy(-90);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
2012-03-19 04:25:09 +01:00
|
|
|
|
aabb3f box = aabb3f(vertices[0]);
|
|
|
|
|
box.addInternalPoint(vertices[1]);
|
|
|
|
|
boxes.push_back(box);
|
|
|
|
|
}
|
|
|
|
|
}
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
else if (nodebox.type == NODEBOX_CONNECTED)
|
|
|
|
|
{
|
|
|
|
|
size_t boxes_size = boxes.size();
|
|
|
|
|
boxes_size += nodebox.fixed.size();
|
2022-05-09 20:59:28 +02:00
|
|
|
|
const auto &c = nodebox.getConnected();
|
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
if (neighbors & 1)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.connect_top.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
else
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_top.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
if (neighbors & 2)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.connect_bottom.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
else
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_bottom.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
if (neighbors & 4)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.connect_front.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
else
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_front.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
if (neighbors & 8)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.connect_left.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
else
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_left.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
if (neighbors & 16)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.connect_back.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
else
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_back.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
if (neighbors & 32)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.connect_right.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
else
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_right.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
|
|
|
|
if (neighbors == 0)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
|
|
|
|
if (neighbors < 4)
|
2022-05-09 20:59:28 +02:00
|
|
|
|
boxes_size += c.disconnected_sides.size();
|
2017-04-22 21:17:46 +02:00
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
boxes.reserve(boxes_size);
|
|
|
|
|
|
2017-08-20 13:30:50 +02:00
|
|
|
|
#define BOXESPUSHBACK(c) \
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
for (std::vector<aabb3f>::const_iterator \
|
|
|
|
|
it = (c).begin(); \
|
|
|
|
|
it != (c).end(); ++it) \
|
2017-08-20 13:30:50 +02:00
|
|
|
|
(boxes).push_back(*it);
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
|
|
|
|
|
BOXESPUSHBACK(nodebox.fixed);
|
|
|
|
|
|
2017-04-22 21:17:46 +02:00
|
|
|
|
if (neighbors & 1) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.connect_top);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
} else {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_top);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors & 2) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.connect_bottom);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
} else {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_bottom);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors & 4) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.connect_front);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
} else {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_front);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors & 8) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.connect_left);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
} else {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_left);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors & 16) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.connect_back);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
} else {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_back);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors & 32) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.connect_right);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
} else {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_right);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors == 0) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (neighbors < 4) {
|
2022-05-09 20:59:28 +02:00
|
|
|
|
BOXESPUSHBACK(c.disconnected_sides);
|
2017-04-22 21:17:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
}
|
2012-03-19 04:25:09 +01:00
|
|
|
|
else // NODEBOX_REGULAR
|
|
|
|
|
{
|
2017-08-19 09:29:55 +02:00
|
|
|
|
boxes.emplace_back(-BS/2,-BS/2,-BS/2,BS/2,BS/2,BS/2);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-04 19:18:40 +01:00
|
|
|
|
static inline void getNeighborConnectingFace(
|
2018-02-10 21:04:16 +01:00
|
|
|
|
const v3s16 &p, const NodeDefManager *nodedef,
|
2017-01-04 19:18:40 +01:00
|
|
|
|
Map *map, MapNode n, u8 bitmask, u8 *neighbors)
|
|
|
|
|
{
|
2019-08-10 19:45:44 +02:00
|
|
|
|
MapNode n2 = map->getNode(p);
|
2017-01-04 19:18:40 +01:00
|
|
|
|
if (nodedef->nodeboxConnects(n, n2, bitmask))
|
|
|
|
|
*neighbors |= bitmask;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-22 17:36:24 +01:00
|
|
|
|
u8 MapNode::getNeighbors(v3s16 p, Map *map) const
|
2017-01-04 19:18:40 +01:00
|
|
|
|
{
|
2018-02-10 21:04:16 +01:00
|
|
|
|
const NodeDefManager *nodedef = map->getNodeDefManager();
|
2017-01-04 19:18:40 +01:00
|
|
|
|
u8 neighbors = 0;
|
|
|
|
|
const ContentFeatures &f = nodedef->get(*this);
|
|
|
|
|
// locate possible neighboring nodes to connect to
|
|
|
|
|
if (f.drawtype == NDT_NODEBOX && f.node_box.type == NODEBOX_CONNECTED) {
|
|
|
|
|
v3s16 p2 = p;
|
|
|
|
|
|
|
|
|
|
p2.Y++;
|
|
|
|
|
getNeighborConnectingFace(p2, nodedef, map, *this, 1, &neighbors);
|
|
|
|
|
|
|
|
|
|
p2 = p;
|
|
|
|
|
p2.Y--;
|
|
|
|
|
getNeighborConnectingFace(p2, nodedef, map, *this, 2, &neighbors);
|
|
|
|
|
|
|
|
|
|
p2 = p;
|
|
|
|
|
p2.Z--;
|
|
|
|
|
getNeighborConnectingFace(p2, nodedef, map, *this, 4, &neighbors);
|
|
|
|
|
|
|
|
|
|
p2 = p;
|
|
|
|
|
p2.X--;
|
|
|
|
|
getNeighborConnectingFace(p2, nodedef, map, *this, 8, &neighbors);
|
|
|
|
|
|
|
|
|
|
p2 = p;
|
|
|
|
|
p2.Z++;
|
|
|
|
|
getNeighborConnectingFace(p2, nodedef, map, *this, 16, &neighbors);
|
|
|
|
|
|
|
|
|
|
p2 = p;
|
|
|
|
|
p2.X++;
|
|
|
|
|
getNeighborConnectingFace(p2, nodedef, map, *this, 32, &neighbors);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return neighbors;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
void MapNode::getNodeBoxes(const NodeDefManager *nodemgr,
|
2018-12-22 17:36:24 +01:00
|
|
|
|
std::vector<aabb3f> *boxes, u8 neighbors) const
|
2012-03-19 04:25:09 +01:00
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
transformNodeBox(*this, f.node_box, nodemgr, boxes, neighbors);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
void MapNode::getCollisionBoxes(const NodeDefManager *nodemgr,
|
2018-12-22 17:36:24 +01:00
|
|
|
|
std::vector<aabb3f> *boxes, u8 neighbors) const
|
2014-10-18 18:46:16 +02:00
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
|
|
|
|
if (f.collision_box.fixed.empty())
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
transformNodeBox(*this, f.node_box, nodemgr, boxes, neighbors);
|
2014-10-18 18:46:16 +02:00
|
|
|
|
else
|
Nodebox: Allow nodeboxes to "connect"
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
|
|
|
|
transformNodeBox(*this, f.collision_box, nodemgr, boxes, neighbors);
|
2014-10-18 18:46:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
void MapNode::getSelectionBoxes(const NodeDefManager *nodemgr,
|
2018-12-22 17:36:24 +01:00
|
|
|
|
std::vector<aabb3f> *boxes, u8 neighbors) const
|
2012-03-19 04:25:09 +01:00
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
2016-03-15 07:20:56 +01:00
|
|
|
|
transformNodeBox(*this, f.selection_box, nodemgr, boxes, neighbors);
|
2012-03-19 04:25:09 +01:00
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
u8 MapNode::getMaxLevel(const NodeDefManager *nodemgr) const
|
2013-07-27 20:34:30 +02:00
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
|
|
|
|
// todo: after update in all games leave only if (f.param_type_2 ==
|
2013-07-28 15:11:59 +02:00
|
|
|
|
if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID)
|
2013-07-27 20:34:30 +02:00
|
|
|
|
return LIQUID_LEVEL_MAX;
|
|
|
|
|
if(f.leveled || f.param_type_2 == CPT2_LEVELED)
|
2020-05-19 21:08:37 +02:00
|
|
|
|
return f.leveled_max;
|
2013-07-27 20:34:30 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:04:16 +01:00
|
|
|
|
u8 MapNode::getLevel(const NodeDefManager *nodemgr) const
|
2013-07-13 19:48:14 +02:00
|
|
|
|
{
|
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
2013-07-27 20:34:30 +02:00
|
|
|
|
// todo: after update in all games leave only if (f.param_type_2 ==
|
2013-07-13 19:48:14 +02:00
|
|
|
|
if(f.liquid_type == LIQUID_SOURCE)
|
|
|
|
|
return LIQUID_LEVEL_SOURCE;
|
|
|
|
|
if (f.param_type_2 == CPT2_FLOWINGLIQUID)
|
|
|
|
|
return getParam2() & LIQUID_LEVEL_MASK;
|
2022-11-09 17:57:19 +01:00
|
|
|
|
if(f.liquid_type == LIQUID_FLOWING) // can remove if all param_type_2 set
|
2013-07-13 19:48:14 +02:00
|
|
|
|
return getParam2() & LIQUID_LEVEL_MASK;
|
2018-12-12 00:02:09 +01:00
|
|
|
|
if (f.param_type_2 == CPT2_LEVELED) {
|
|
|
|
|
u8 level = getParam2() & LEVELED_MASK;
|
|
|
|
|
if (level)
|
2013-11-30 02:54:04 +01:00
|
|
|
|
return level;
|
2013-07-13 19:48:14 +02:00
|
|
|
|
}
|
2020-05-19 21:08:37 +02:00
|
|
|
|
// Return static value from nodedef if param2 isn't used for level
|
|
|
|
|
if (f.leveled > f.leveled_max)
|
|
|
|
|
return f.leveled_max;
|
2018-12-12 00:02:09 +01:00
|
|
|
|
return f.leveled;
|
2013-07-13 19:48:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-19 21:08:37 +02:00
|
|
|
|
s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 level)
|
2013-07-27 20:34:30 +02:00
|
|
|
|
{
|
2020-05-19 21:08:37 +02:00
|
|
|
|
s8 rest = 0;
|
2013-07-27 20:34:30 +02:00
|
|
|
|
const ContentFeatures &f = nodemgr->get(*this);
|
2013-11-30 02:54:04 +01:00
|
|
|
|
if (f.param_type_2 == CPT2_FLOWINGLIQUID
|
2018-12-12 00:02:09 +01:00
|
|
|
|
|| f.liquid_type == LIQUID_FLOWING
|
|
|
|
|
|| f.liquid_type == LIQUID_SOURCE) {
|
|
|
|
|
if (level <= 0) { // liquid can’t exist with zero level
|
|
|
|
|
setContent(CONTENT_AIR);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2013-07-28 15:11:59 +02:00
|
|
|
|
if (level >= LIQUID_LEVEL_SOURCE) {
|
|
|
|
|
rest = level - LIQUID_LEVEL_SOURCE;
|
2020-05-20 23:52:10 +02:00
|
|
|
|
setContent(f.liquid_alternative_source_id);
|
2018-12-12 00:02:09 +01:00
|
|
|
|
setParam2(0);
|
2013-07-27 20:34:30 +02:00
|
|
|
|
} else {
|
2020-05-20 23:52:10 +02:00
|
|
|
|
setContent(f.liquid_alternative_flowing_id);
|
2018-12-12 00:02:09 +01:00
|
|
|
|
setParam2((level & LIQUID_LEVEL_MASK) | (getParam2() & ~LIQUID_LEVEL_MASK));
|
2013-07-27 20:34:30 +02:00
|
|
|
|
}
|
2018-12-12 00:02:09 +01:00
|
|
|
|
} else if (f.param_type_2 == CPT2_LEVELED) {
|
|
|
|
|
if (level < 0) { // zero means default for a leveled nodebox
|
|
|
|
|
rest = level;
|
|
|
|
|
level = 0;
|
2020-05-19 21:08:37 +02:00
|
|
|
|
} else if (level > f.leveled_max) {
|
|
|
|
|
rest = level - f.leveled_max;
|
|
|
|
|
level = f.leveled_max;
|
2013-07-27 20:34:30 +02:00
|
|
|
|
}
|
2018-12-12 00:02:09 +01:00
|
|
|
|
setParam2((level & LEVELED_MASK) | (getParam2() & ~LEVELED_MASK));
|
2013-07-27 20:34:30 +02:00
|
|
|
|
}
|
|
|
|
|
return rest;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-19 21:08:37 +02:00
|
|
|
|
s8 MapNode::addLevel(const NodeDefManager *nodemgr, s16 add)
|
2013-07-28 15:11:59 +02:00
|
|
|
|
{
|
2020-05-19 21:08:37 +02:00
|
|
|
|
s16 level = getLevel(nodemgr);
|
2013-07-28 15:11:59 +02:00
|
|
|
|
level += add;
|
|
|
|
|
return setLevel(nodemgr, level);
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-02 00:07:54 +02:00
|
|
|
|
u32 MapNode::serializedLength(u8 version)
|
|
|
|
|
{
|
|
|
|
|
if(!ser_ver_supported(version))
|
|
|
|
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
2015-01-04 09:30:10 +01:00
|
|
|
|
|
2017-08-18 18:18:25 +02:00
|
|
|
|
if (version == 0)
|
2011-07-02 00:07:54 +02:00
|
|
|
|
return 1;
|
2017-08-18 18:18:25 +02:00
|
|
|
|
|
|
|
|
|
if (version <= 9)
|
2011-07-02 00:07:54 +02:00
|
|
|
|
return 2;
|
2017-08-18 18:18:25 +02:00
|
|
|
|
|
|
|
|
|
if (version <= 23)
|
2011-07-02 00:07:54 +02:00
|
|
|
|
return 3;
|
2017-08-18 18:18:25 +02:00
|
|
|
|
|
|
|
|
|
return 4;
|
2011-07-02 00:07:54 +02:00
|
|
|
|
}
|
2018-12-22 17:36:24 +01:00
|
|
|
|
void MapNode::serialize(u8 *dest, u8 version) const
|
2012-01-21 00:11:44 +01:00
|
|
|
|
{
|
|
|
|
|
if(!ser_ver_supported(version))
|
|
|
|
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
2015-01-04 09:30:10 +01:00
|
|
|
|
|
2012-07-23 06:20:13 +02:00
|
|
|
|
// Can't do this anymore; we have 16-bit dynamically allocated node IDs
|
|
|
|
|
// in memory; conversion just won't work in this direction.
|
|
|
|
|
if(version < 24)
|
|
|
|
|
throw SerializationError("MapNode::serialize: serialization to "
|
|
|
|
|
"version < 24 not possible");
|
2015-01-04 09:30:10 +01:00
|
|
|
|
|
2012-07-23 06:20:13 +02:00
|
|
|
|
writeU16(dest+0, param0);
|
|
|
|
|
writeU8(dest+2, param1);
|
|
|
|
|
writeU8(dest+3, param2);
|
2012-01-21 00:11:44 +01:00
|
|
|
|
}
|
|
|
|
|
void MapNode::deSerialize(u8 *source, u8 version)
|
2011-07-02 00:07:54 +02:00
|
|
|
|
{
|
2017-06-06 16:19:04 +02:00
|
|
|
|
if(!ser_ver_supported(version))
|
2011-07-02 00:07:54 +02:00
|
|
|
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
2015-01-04 09:30:10 +01:00
|
|
|
|
|
2017-06-06 16:19:04 +02:00
|
|
|
|
if(version <= 21)
|
|
|
|
|
{
|
|
|
|
|
deSerialize_pre22(source, version);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(version >= 24){
|
|
|
|
|
param0 = readU16(source+0);
|
|
|
|
|
param1 = readU8(source+2);
|
|
|
|
|
param2 = readU8(source+3);
|
|
|
|
|
}else{
|
|
|
|
|
param0 = readU8(source+0);
|
|
|
|
|
param1 = readU8(source+1);
|
|
|
|
|
param2 = readU8(source+2);
|
|
|
|
|
if(param0 > 0x7F){
|
|
|
|
|
param0 |= ((param2&0xF0)<<4);
|
2012-07-17 21:04:38 +02:00
|
|
|
|
param2 &= 0x0F;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
}
|
2021-09-01 02:32:31 +02:00
|
|
|
|
|
2024-02-17 15:35:33 +01:00
|
|
|
|
Buffer<u8> MapNode::serializeBulk(int version,
|
2012-01-21 00:11:44 +01:00
|
|
|
|
const MapNode *nodes, u32 nodecount,
|
2021-09-01 02:32:31 +02:00
|
|
|
|
u8 content_width, u8 params_width)
|
2012-01-21 00:11:44 +01:00
|
|
|
|
{
|
2017-07-26 23:37:44 +02:00
|
|
|
|
if (!ser_ver_supported(version))
|
2012-01-21 00:11:44 +01:00
|
|
|
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
|
|
|
|
|
2015-03-06 11:21:51 +01:00
|
|
|
|
sanity_check(content_width == 2);
|
|
|
|
|
sanity_check(params_width == 2);
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
2012-07-23 06:20:13 +02:00
|
|
|
|
// Can't do this anymore; we have 16-bit dynamically allocated node IDs
|
|
|
|
|
// in memory; conversion just won't work in this direction.
|
2017-07-26 23:37:44 +02:00
|
|
|
|
if (version < 24)
|
2012-07-23 06:20:13 +02:00
|
|
|
|
throw SerializationError("MapNode::serializeBulk: serialization to "
|
|
|
|
|
"version < 24 not possible");
|
|
|
|
|
|
2024-02-17 15:35:33 +01:00
|
|
|
|
Buffer<u8> databuf(nodecount * (content_width + params_width));
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
2024-04-10 23:28:03 +02:00
|
|
|
|
// Writing to the buffer linearly is faster
|
|
|
|
|
u8 *p = &databuf[0];
|
|
|
|
|
for (u32 i = 0; i < nodecount; i++, p += 2)
|
|
|
|
|
writeU16(p, nodes[i].param0);
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < nodecount; i++, p++)
|
|
|
|
|
writeU8(p, nodes[i].param1);
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < nodecount; i++, p++)
|
|
|
|
|
writeU8(p, nodes[i].param2);
|
|
|
|
|
|
2021-09-01 02:32:31 +02:00
|
|
|
|
return databuf;
|
2012-01-21 00:11:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deserialize bulk node data
|
|
|
|
|
void MapNode::deSerializeBulk(std::istream &is, int version,
|
|
|
|
|
MapNode *nodes, u32 nodecount,
|
2020-12-09 23:30:37 +01:00
|
|
|
|
u8 content_width, u8 params_width)
|
2012-01-21 00:11:44 +01:00
|
|
|
|
{
|
|
|
|
|
if(!ser_ver_supported(version))
|
|
|
|
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
|
|
|
|
|
2015-03-06 11:21:51 +01:00
|
|
|
|
if (version < 22
|
|
|
|
|
|| (content_width != 1 && content_width != 2)
|
|
|
|
|
|| params_width != 2)
|
|
|
|
|
FATAL_ERROR("Deserialize bulk node data error");
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
2021-09-01 02:32:31 +02:00
|
|
|
|
// read data
|
|
|
|
|
const u32 len = nodecount * (content_width + params_width);
|
|
|
|
|
Buffer<u8> databuf(len);
|
|
|
|
|
is.read(reinterpret_cast<char*>(*databuf), len);
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
|
|
|
|
// Deserialize content
|
|
|
|
|
if(content_width == 1)
|
|
|
|
|
{
|
|
|
|
|
for(u32 i=0; i<nodecount; i++)
|
|
|
|
|
nodes[i].param0 = readU8(&databuf[i]);
|
|
|
|
|
}
|
2012-07-17 21:04:38 +02:00
|
|
|
|
else if(content_width == 2)
|
2012-01-21 00:11:44 +01:00
|
|
|
|
{
|
|
|
|
|
for(u32 i=0; i<nodecount; i++)
|
|
|
|
|
nodes[i].param0 = readU16(&databuf[i*2]);
|
2012-07-17 21:04:38 +02:00
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
|
|
|
|
|
// Deserialize param1
|
|
|
|
|
u32 start1 = content_width * nodecount;
|
|
|
|
|
for(u32 i=0; i<nodecount; i++)
|
|
|
|
|
nodes[i].param1 = readU8(&databuf[start1 + i]);
|
|
|
|
|
|
|
|
|
|
// Deserialize param2
|
|
|
|
|
u32 start2 = (content_width + 1) * nodecount;
|
2012-07-17 21:04:38 +02:00
|
|
|
|
if(content_width == 1)
|
|
|
|
|
{
|
|
|
|
|
for(u32 i=0; i<nodecount; i++) {
|
|
|
|
|
nodes[i].param2 = readU8(&databuf[start2 + i]);
|
|
|
|
|
if(nodes[i].param0 > 0x7F){
|
2012-07-23 06:20:13 +02:00
|
|
|
|
nodes[i].param0 <<= 4;
|
|
|
|
|
nodes[i].param0 |= (nodes[i].param2&0xF0)>>4;
|
2012-07-17 21:04:38 +02:00
|
|
|
|
nodes[i].param2 &= 0x0F;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(content_width == 2)
|
|
|
|
|
{
|
|
|
|
|
for(u32 i=0; i<nodecount; i++)
|
|
|
|
|
nodes[i].param2 = readU8(&databuf[start2 + i]);
|
|
|
|
|
}
|
2012-01-21 00:11:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-06 16:19:04 +02:00
|
|
|
|
/*
|
|
|
|
|
Legacy serialization
|
|
|
|
|
*/
|
2017-08-19 09:29:55 +02:00
|
|
|
|
void MapNode::deSerialize_pre22(const u8 *source, u8 version)
|
2017-06-06 16:19:04 +02:00
|
|
|
|
{
|
|
|
|
|
if(version <= 1)
|
|
|
|
|
{
|
|
|
|
|
param0 = source[0];
|
|
|
|
|
}
|
|
|
|
|
else if(version <= 9)
|
|
|
|
|
{
|
|
|
|
|
param0 = source[0];
|
|
|
|
|
param1 = source[1];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param0 = source[0];
|
|
|
|
|
param1 = source[1];
|
|
|
|
|
param2 = source[2];
|
|
|
|
|
if(param0 > 0x7f){
|
|
|
|
|
param0 <<= 4;
|
|
|
|
|
param0 |= (param2&0xf0)>>4;
|
|
|
|
|
param2 &= 0x0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert special values from old version to new
|
|
|
|
|
if(version <= 19)
|
|
|
|
|
{
|
|
|
|
|
// In these versions, CONTENT_IGNORE and CONTENT_AIR
|
|
|
|
|
// are 255 and 254
|
2019-10-24 02:17:00 +02:00
|
|
|
|
// Version 19 is messed up with sometimes the old values and sometimes not
|
2017-06-06 16:19:04 +02:00
|
|
|
|
if(param0 == 255)
|
|
|
|
|
param0 = CONTENT_IGNORE;
|
|
|
|
|
else if(param0 == 254)
|
|
|
|
|
param0 = CONTENT_AIR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Translate to our known version
|
|
|
|
|
*this = mapnode_translate_to_internal(*this, version);
|
|
|
|
|
}
|