*color = f.color;
}
-void MapNode::setLight(LightBank bank, u8 a_light, const ContentFeatures &f) noexcept
-{
- // If node doesn't contain light data, ignore this
- if(f.param_type != CPT_LIGHT)
- return;
- if(bank == LIGHTBANK_DAY)
- {
- param1 &= 0xf0;
- param1 |= a_light & 0x0f;
- }
- else if(bank == LIGHTBANK_NIGHT)
- {
- param1 &= 0x0f;
- param1 |= (a_light & 0x0f)<<4;
- }
- else
- assert("Invalid light bank" == NULL);
-}
-
-void MapNode::setLight(LightBank bank, u8 a_light, const NodeDefManager *nodemgr)
-{
- setLight(bank, a_light, nodemgr->get(*this));
-}
-
-bool MapNode::isLightDayNightEq(const NodeDefManager *nodemgr) const
-{
- const ContentFeatures &f = nodemgr->get(*this);
- bool isEqual;
-
- if (f.param_type == CPT_LIGHT) {
- u8 day = MYMAX(f.light_source, param1 & 0x0f);
- u8 night = MYMAX(f.light_source, (param1 >> 4) & 0x0f);
- isEqual = day == night;
- } else {
- isEqual = true;
- }
-
- return isEqual;
-}
-
-u8 MapNode::getLight(LightBank bank, const NodeDefManager *nodemgr) const
-{
- // Select the brightest of [light source, propagated light]
- const ContentFeatures &f = nodemgr->get(*this);
-
- u8 light;
- if(f.param_type == CPT_LIGHT)
- light = bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f;
- else
- light = 0;
-
- return MYMAX(f.light_source, light);
-}
-
-u8 MapNode::getLightRaw(LightBank bank, const ContentFeatures &f) const noexcept
-{
- if(f.param_type == CPT_LIGHT)
- return bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f;
- return 0;
-}
-
-u8 MapNode::getLightNoChecks(LightBank bank, const ContentFeatures *f) const noexcept
-{
- return MYMAX(f->light_source,
- bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f);
-}
-
-bool MapNode::getLightBanks(u8 &lightday, u8 &lightnight,
- const NodeDefManager *nodemgr) const
-{
- // Select the brightest of [light source, propagated light]
- const ContentFeatures &f = nodemgr->get(*this);
- if(f.param_type == CPT_LIGHT)
- {
- lightday = param1 & 0x0f;
- lightnight = (param1>>4)&0x0f;
- }
- else
- {
- lightday = 0;
- lightnight = 0;
- }
- if(f.light_source > lightday)
- lightday = f.light_source;
- if(f.light_source > lightnight)
- lightnight = f.light_source;
- return f.param_type == CPT_LIGHT || f.light_source != 0;
-}
-
u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
bool allow_wallmounted) const
{
if (f.param_type_2 == CPT2_FACEDIR ||
f.param_type_2 == CPT2_COLORED_FACEDIR)
return (getParam2() & 0x1F) % 24;
+ if (f.param_type_2 == CPT2_4DIR ||
+ f.param_type_2 == CPT2_COLORED_4DIR)
+ return getParam2() & 0x03;
if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED ||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED))
return wallmounted_to_facedir[getParam2() & 0x07];
{
const ContentFeatures &f = nodemgr->get(*this);
if (f.param_type_2 == CPT2_WALLMOUNTED ||
- f.param_type_2 == CPT2_COLORED_WALLMOUNTED)
+ f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
return getParam2() & 0x07;
+ } else if (f.drawtype == NDT_SIGNLIKE || f.drawtype == NDT_TORCHLIKE ||
+ f.drawtype == NDT_PLANTLIKE ||
+ f.drawtype == NDT_PLANTLIKE_ROOTED) {
+ return 1;
+ }
return 0;
}
}
}
+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;
+}
+
void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
{
ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2;
- if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR) {
+ if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR ||
+ cpt2 == CPT2_4DIR || cpt2 == CPT2_COLORED_4DIR) {
static const u8 rotate_facedir[24 * 4] = {
// Table value = rotated facedir
// Columns: 0, 90, 180, 270 degrees rotation around vertical axis
22, 21, 20, 23,
23, 22, 21, 20
};
- u8 facedir = (param2 & 31) % 24;
- u8 index = facedir * 4 + rot;
- param2 &= ~31;
- param2 |= rotate_facedir[index];
+ 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;
+ u8 index = fourdir + rot;
+ param2 &= ~3;
+ param2 |= rotate_facedir[index];
+ }
} else if (cpt2 == CPT2_WALLMOUNTED ||
cpt2 == CPT2_COLORED_WALLMOUNTED) {
u8 wmountface = (param2 & 7);
Rotation oldrot = wallmounted_to_rot[wmountface - 2];
param2 &= ~7;
param2 |= rot_to_wallmounted[(oldrot - rot) & 3];
+ } 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;
}
}
std::vector<aabb3f> &boxes = *p_boxes;
if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) {
- const std::vector<aabb3f> &fixed = nodebox.fixed;
+ const auto &fixed = nodebox.fixed;
int facedir = n.getFaceDir(nodemgr, true);
u8 axisdir = facedir>>2;
facedir&=0x03;
+
+ boxes.reserve(boxes.size() + fixed.size());
for (aabb3f box : fixed) {
if (nodebox.type == NODEBOX_LEVELED)
box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS;
{
size_t boxes_size = boxes.size();
boxes_size += nodebox.fixed.size();
+ const auto &c = nodebox.getConnected();
+
if (neighbors & 1)
- boxes_size += nodebox.connect_top.size();
+ boxes_size += c.connect_top.size();
else
- boxes_size += nodebox.disconnected_top.size();
+ boxes_size += c.disconnected_top.size();
if (neighbors & 2)
- boxes_size += nodebox.connect_bottom.size();
+ boxes_size += c.connect_bottom.size();
else
- boxes_size += nodebox.disconnected_bottom.size();
+ boxes_size += c.disconnected_bottom.size();
if (neighbors & 4)
- boxes_size += nodebox.connect_front.size();
+ boxes_size += c.connect_front.size();
else
- boxes_size += nodebox.disconnected_front.size();
+ boxes_size += c.disconnected_front.size();
if (neighbors & 8)
- boxes_size += nodebox.connect_left.size();
+ boxes_size += c.connect_left.size();
else
- boxes_size += nodebox.disconnected_left.size();
+ boxes_size += c.disconnected_left.size();
if (neighbors & 16)
- boxes_size += nodebox.connect_back.size();
+ boxes_size += c.connect_back.size();
else
- boxes_size += nodebox.disconnected_back.size();
+ boxes_size += c.disconnected_back.size();
if (neighbors & 32)
- boxes_size += nodebox.connect_right.size();
+ boxes_size += c.connect_right.size();
else
- boxes_size += nodebox.disconnected_right.size();
+ boxes_size += c.disconnected_right.size();
if (neighbors == 0)
- boxes_size += nodebox.disconnected.size();
+ boxes_size += c.disconnected.size();
if (neighbors < 4)
- boxes_size += nodebox.disconnected_sides.size();
+ boxes_size += c.disconnected_sides.size();
boxes.reserve(boxes_size);
BOXESPUSHBACK(nodebox.fixed);
if (neighbors & 1) {
- BOXESPUSHBACK(nodebox.connect_top);
+ BOXESPUSHBACK(c.connect_top);
} else {
- BOXESPUSHBACK(nodebox.disconnected_top);
+ BOXESPUSHBACK(c.disconnected_top);
}
if (neighbors & 2) {
- BOXESPUSHBACK(nodebox.connect_bottom);
+ BOXESPUSHBACK(c.connect_bottom);
} else {
- BOXESPUSHBACK(nodebox.disconnected_bottom);
+ BOXESPUSHBACK(c.disconnected_bottom);
}
if (neighbors & 4) {
- BOXESPUSHBACK(nodebox.connect_front);
+ BOXESPUSHBACK(c.connect_front);
} else {
- BOXESPUSHBACK(nodebox.disconnected_front);
+ BOXESPUSHBACK(c.disconnected_front);
}
if (neighbors & 8) {
- BOXESPUSHBACK(nodebox.connect_left);
+ BOXESPUSHBACK(c.connect_left);
} else {
- BOXESPUSHBACK(nodebox.disconnected_left);
+ BOXESPUSHBACK(c.disconnected_left);
}
if (neighbors & 16) {
- BOXESPUSHBACK(nodebox.connect_back);
+ BOXESPUSHBACK(c.connect_back);
} else {
- BOXESPUSHBACK(nodebox.disconnected_back);
+ BOXESPUSHBACK(c.disconnected_back);
}
if (neighbors & 32) {
- BOXESPUSHBACK(nodebox.connect_right);
+ BOXESPUSHBACK(c.connect_right);
} else {
- BOXESPUSHBACK(nodebox.disconnected_right);
+ BOXESPUSHBACK(c.disconnected_right);
}
if (neighbors == 0) {
- BOXESPUSHBACK(nodebox.disconnected);
+ BOXESPUSHBACK(c.disconnected);
}
if (neighbors < 4) {
- BOXESPUSHBACK(nodebox.disconnected_sides);
+ BOXESPUSHBACK(c.disconnected_sides);
}
}
return LIQUID_LEVEL_SOURCE;
if (f.param_type_2 == CPT2_FLOWINGLIQUID)
return getParam2() & LIQUID_LEVEL_MASK;
- if(f.liquid_type == LIQUID_FLOWING) // can remove if all param_type_2 setted
+ if(f.liquid_type == LIQUID_FLOWING) // can remove if all param_type_2 set
return getParam2() & LIQUID_LEVEL_MASK;
if (f.param_type_2 == CPT2_LEVELED) {
u8 level = getParam2() & LEVELED_MASK;
}
if (level >= LIQUID_LEVEL_SOURCE) {
rest = level - LIQUID_LEVEL_SOURCE;
- setContent(nodemgr->getId(f.liquid_alternative_source));
+ setContent(f.liquid_alternative_source_id);
setParam2(0);
} else {
- setContent(nodemgr->getId(f.liquid_alternative_flowing));
+ setContent(f.liquid_alternative_flowing_id);
setParam2((level & LIQUID_LEVEL_MASK) | (getParam2() & ~LIQUID_LEVEL_MASK));
}
} else if (f.param_type_2 == CPT2_LEVELED) {
}
}
}
-void MapNode::serializeBulk(std::ostream &os, int version,
+
+SharedBuffer<u8> MapNode::serializeBulk(int version,
const MapNode *nodes, u32 nodecount,
- u8 content_width, u8 params_width, bool compressed)
+ u8 content_width, u8 params_width)
{
if (!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported");
throw SerializationError("MapNode::serializeBulk: serialization to "
"version < 24 not possible");
- size_t databuf_size = nodecount * (content_width + params_width);
- u8 *databuf = new u8[databuf_size];
+ SharedBuffer<u8> databuf(nodecount * (content_width + params_width));
u32 start1 = content_width * nodecount;
u32 start2 = (content_width + 1) * nodecount;
writeU8(&databuf[start1 + i], nodes[i].param1);
writeU8(&databuf[start2 + i], nodes[i].param2);
}
-
- /*
- Compress data to output stream
- */
-
- if (compressed)
- compressZlib(databuf, databuf_size, os);
- else
- os.write((const char*) &databuf[0], databuf_size);
-
- delete [] databuf;
+ return databuf;
}
// Deserialize bulk node data
void MapNode::deSerializeBulk(std::istream &is, int version,
MapNode *nodes, u32 nodecount,
- u8 content_width, u8 params_width, bool compressed)
+ u8 content_width, u8 params_width)
{
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported");
|| params_width != 2)
FATAL_ERROR("Deserialize bulk node data error");
- // Uncompress or read data
- u32 len = nodecount * (content_width + params_width);
- SharedBuffer<u8> databuf(len);
- if(compressed)
- {
- std::ostringstream os(std::ios_base::binary);
- decompressZlib(is, os);
- std::string s = os.str();
- if(s.size() != len)
- throw SerializationError("deSerializeBulkNodes: "
- "decompress resulted in invalid size");
- memcpy(&databuf[0], s.c_str(), len);
- }
- else
- {
- is.read((char*) &databuf[0], len);
- if(is.eof() || is.fail())
- throw SerializationError("deSerializeBulkNodes: "
- "failed to read bulk node data");
- }
+ // read data
+ const u32 len = nodecount * (content_width + params_width);
+ Buffer<u8> databuf(len);
+ is.read(reinterpret_cast<char*>(*databuf), len);
// Deserialize content
if(content_width == 1)