]> git.lizzy.rs Git - minetest.git/blobdiff - src/mapnode.cpp
Android: Increase minimum SDK version to 21
[minetest.git] / src / mapnode.cpp
index 24d62b5045ccfbf8aeb370370245b8aa965da1f0..0d58b45db94002689add344c3e48eefba7a7953c 100644 (file)
@@ -53,95 +53,6 @@ void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const
        *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
 {
@@ -149,6 +60,9 @@ u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
        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];
@@ -159,8 +73,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,11 +96,22 @@ 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;
 
-       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
@@ -217,10 +147,17 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
                        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);
@@ -230,6 +167,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 +188,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 +361,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 +410,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);
                }
 
        }
@@ -596,7 +548,7 @@ u8 MapNode::getLevel(const NodeDefManager *nodemgr) const
                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;
@@ -622,10 +574,10 @@ s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 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) {
@@ -704,9 +656,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");
@@ -720,8 +673,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;
@@ -732,23 +684,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");
@@ -758,26 +700,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)