]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapnode.cpp
Reduce size of ContentFeatures structure
[dragonfireclient.git] / src / mapnode.cpp
index 557b376c3041ef1654fa3190703aac48e69e9127..42f020e7106b651eeca3ad4e4d3f7630cac56429 100644 (file)
@@ -159,8 +159,13 @@ u8 MapNode::getWallMounted(const NodeDefManager *nodemgr) const
 {
        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;
 }
 
@@ -177,6 +182,16 @@ v3s16 MapNode::getWallMountedDir(const NodeDefManager *nodemgr) const
        }
 }
 
+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;
@@ -230,6 +245,17 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
                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;
        }
 }
 
@@ -240,10 +266,12 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
        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;
@@ -411,41 +439,43 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
        {
                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);
 
@@ -458,47 +488,47 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
                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);
                }
 
        }
@@ -584,7 +614,7 @@ u8 MapNode::getMaxLevel(const NodeDefManager *nodemgr) const
        if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID)
                return LIQUID_LEVEL_MAX;
        if(f.leveled || f.param_type_2 == CPT2_LEVELED)
-               return LEVELED_MAX;
+               return f.leveled_max;
        return 0;
 }
 
@@ -603,14 +633,15 @@ u8 MapNode::getLevel(const NodeDefManager *nodemgr) const
                if (level)
                        return level;
        }
-       if (f.leveled > LEVELED_MAX)
-               return LEVELED_MAX;
+       // Return static value from nodedef if param2 isn't used for level
+       if (f.leveled > f.leveled_max)
+               return f.leveled_max;
        return f.leveled;
 }
 
-u8 MapNode::setLevel(const NodeDefManager *nodemgr, s8 level)
+s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 level)
 {
-       u8 rest = 0;
+       s8 rest = 0;
        const ContentFeatures &f = nodemgr->get(*this);
        if (f.param_type_2 == CPT2_FLOWINGLIQUID
                        || f.liquid_type == LIQUID_FLOWING
@@ -621,28 +652,28 @@ u8 MapNode::setLevel(const NodeDefManager *nodemgr, s8 level)
                }
                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) {
                if (level < 0) { // zero means default for a leveled nodebox
                        rest = level;
                        level = 0;
-               } else if (level > LEVELED_MAX) {
-                       rest = level - LEVELED_MAX;
-                       level = LEVELED_MAX;
+               } else if (level > f.leveled_max) {
+                       rest = level - f.leveled_max;
+                       level = f.leveled_max;
                }
                setParam2((level & LEVELED_MASK) | (getParam2() & ~LEVELED_MASK));
        }
        return rest;
 }
 
-u8 MapNode::addLevel(const NodeDefManager *nodemgr, s8 add)
+s8 MapNode::addLevel(const NodeDefManager *nodemgr, s16 add)
 {
-       s8 level = getLevel(nodemgr);
+       s16 level = getLevel(nodemgr);
        level += add;
        return setLevel(nodemgr, level);
 }
@@ -703,9 +734,10 @@ void MapNode::deSerialize(u8 *source, u8 version)
                }
        }
 }
-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");
@@ -719,8 +751,7 @@ void MapNode::serializeBulk(std::ostream &os, int version,
                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;
@@ -731,23 +762,13 @@ void MapNode::serializeBulk(std::ostream &os, int version,
                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");
@@ -757,26 +778,10 @@ void MapNode::deSerializeBulk(std::istream &is, int version,
                        || 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)
@@ -846,7 +851,7 @@ void MapNode::deSerialize_pre22(const u8 *source, u8 version)
        {
                // In these versions, CONTENT_IGNORE and CONTENT_AIR
                // are 255 and 254
-               // Version 19 is fucked up with sometimes the old values and sometimes not
+               // Version 19 is messed up with sometimes the old values and sometimes not
                if(param0 == 255)
                        param0 = CONTENT_IGNORE;
                else if(param0 == 254)