initial steps in doing content type extension
authorPerttu Ahola <celeron55@gmail.com>
Fri, 1 Jul 2011 22:07:54 +0000 (01:07 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Fri, 1 Jul 2011 22:07:54 +0000 (01:07 +0300)
src/content_mapnode.cpp
src/mapblock.cpp
src/mapnode.cpp
src/mapnode.h
src/serialization.h

index 403fb66d398fc86a750e9f5564553e1165ecdf12..d82ccc5c9c7eb48882f34b47ff2b78412304f5cb 100644 (file)
@@ -151,7 +151,6 @@ void content_mapnode_init()
        // Deprecated
        i = CONTENT_COALSTONE;
        f = &content_features(i);
-       //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
        f->setAllTextures("stone.png^mineral_coal.png");
        f->is_ground_content = true;
        setStoneLikeDiggingProperties(f->digging_properties, 1.5);
index c125e67c8021c084a379a5fad4cf5094bdec2478..647a177564c2a1b088eb2820aebe84cf4b98afdf 100644 (file)
@@ -607,24 +607,20 @@ void MapBlock::serialize(std::ostream &os, u8 version)
                        Get data
                */
 
-               SharedBuffer<u8> databuf(nodecount*3);
-
-               // Get contents
+               // Serialize nodes
+               SharedBuffer<u8> databuf_nodelist(nodecount*3);
                for(u32 i=0; i<nodecount; i++)
                {
-                       databuf[i] = data[i].d;
+                       data[i].serialize(&databuf_nodelist[i*3], version);
                }
-
-               // Get params
-               for(u32 i=0; i<nodecount; i++)
-               {
-                       databuf[i+nodecount] = data[i].param;
-               }
-
-               // Get param2
+               
+               // Create buffer with different parameters sorted
+               SharedBuffer<u8> databuf(nodecount*3);
                for(u32 i=0; i<nodecount; i++)
                {
-                       databuf[i+nodecount*2] = data[i].param2;
+                       databuf[i] = databuf_nodelist[i*3];
+                       databuf[i+nodecount] = databuf_nodelist[i*3+1];
+                       databuf[i+nodecount*2] = databuf_nodelist[i*3+2];
                }
 
                /*
@@ -773,20 +769,14 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
                                        ("MapBlock::deSerialize: decompress resulted in size"
                                        " other than nodecount*3");
 
-               // Set contents
-               for(u32 i=0; i<nodecount; i++)
-               {
-                       data[i].d = s[i];
-               }
-               // Set params
-               for(u32 i=0; i<nodecount; i++)
-               {
-                       data[i].param = s[i+nodecount];
-               }
-               // Set param2
+               // deserialize nodes from buffer
                for(u32 i=0; i<nodecount; i++)
                {
-                       data[i].param2 = s[i+nodecount*2];
+                       u8 buf[3];
+                       buf[0] = s[i];
+                       buf[1] = s[i+nodecount];
+                       buf[2] = s[i+nodecount*2];
+                       data[i].deSerialize(buf, version);
                }
                
                /*
@@ -818,25 +808,6 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
                        }
                }
        }
-       
-       /*
-               Translate nodes as specified in the translate_to fields of
-               node features
-
-               NOTE: This isn't really used. Should it be removed?
-       */
-       for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
-       {
-               MapNode &n = data[i];
-
-               MapNode *translate_to = content_features(n.d).translate_to;
-               if(translate_to)
-               {
-                       dstream<<"MapBlock: WARNING: Translating node "<<n.d<<" to "
-                                       <<translate_to->d<<std::endl;
-                       n = *translate_to;
-               }
-       }
 }
 
 void MapBlock::serializeDiskExtra(std::ostream &os, u8 version)
index 1fe231434dec45d7c0e86bb3a81671c87f8d6137..391e593f9548b9715de7f733169e88a50eb44f78 100644 (file)
@@ -30,8 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 ContentFeatures::~ContentFeatures()
 {
-       if(translate_to)
-               delete translate_to;
+       /*if(translate_to)
+               delete translate_to;*/
        if(initial_metadata)
                delete initial_metadata;
 }
@@ -241,6 +241,94 @@ u8 MapNode::getMineral()
        return MINERAL_NONE;
 }
 
+u32 MapNode::serializedLength(u8 version)
+{
+       if(!ser_ver_supported(version))
+               throw VersionMismatchException("ERROR: MapNode format not supported");
+               
+       if(version == 0)
+               return 1;
+       else if(version <= 9)
+               return 2;
+       else
+               return 3;
+}
+void MapNode::serialize(u8 *dest, u8 version)
+{
+       if(!ser_ver_supported(version))
+               throw VersionMismatchException("ERROR: MapNode format not supported");
+               
+       u8 actual_d = d;
+
+       // Convert from new version to old
+       if(version <= 18)
+       {
+               // In these versions, CONTENT_IGNORE and CONTENT_AIR
+               // are 255 and 254
+               if(d == CONTENT_IGNORE)
+                       d = 255;
+               else if(d == CONTENT_AIR)
+                       d = 254;
+       }
+
+       if(version == 0)
+       {
+               dest[0] = actual_d;
+       }
+       else if(version <= 9)
+       {
+               dest[0] = actual_d;
+               dest[1] = param;
+       }
+       else
+       {
+               dest[0] = actual_d;
+               dest[1] = param;
+               dest[2] = param2;
+       }
+}
+void MapNode::deSerialize(u8 *source, u8 version)
+{
+       if(!ser_ver_supported(version))
+               throw VersionMismatchException("ERROR: MapNode format not supported");
+               
+       if(version == 0)
+       {
+               d = source[0];
+       }
+       else if(version == 1)
+       {
+               d = source[0];
+               // This version doesn't support saved lighting
+               if(light_propagates() || light_source() > 0)
+                       param = 0;
+               else
+                       param = source[1];
+       }
+       else if(version <= 9)
+       {
+               d = source[0];
+               param = source[1];
+       }
+       else
+       {
+               d = source[0];
+               param = source[1];
+               param2 = source[2];
+               
+               // Convert from old version to new
+               if(version <= 18)
+               {
+                       // In these versions, CONTENT_IGNORE and CONTENT_AIR
+                       // are 255 and 254
+                       if(d == 255)
+                               d = CONTENT_IGNORE;
+                       else if(d == 254)
+                               d = CONTENT_AIR;
+               }
+       }
+}
+
 /*
        Gets lighting value at face of node
        
index eb4b17e485efa295cc80808ebe4ac5cd0ccfd255..36d48fb9e4e6536c57bcbb67b17edf0843024ae1 100644 (file)
@@ -36,6 +36,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        - Tile = TileSpec at some side of a node of some content type
 */
 
+/*
+       Ranges:
+               0x000...0x07f: param2 is fully usable
+               0x800...0xfff: param2 lower 4 bytes are free
+*/
+typedef u16 content_t;
+
 /*
        Initializes all kind of stuff in here.
        Many things depend on this.
@@ -59,14 +66,16 @@ void init_mapnode();
        Doesn't create faces with anything and is considered being
        out-of-map in the game map.
 */
-#define CONTENT_IGNORE 255
+//#define CONTENT_IGNORE 255
+#define CONTENT_IGNORE 127
 #define CONTENT_IGNORE_DEFAULT_PARAM 0
 
 /*
        The common material through which the player can walk and which
        is transparent to light
 */
-#define CONTENT_AIR 254
+//#define CONTENT_AIR 254
+#define CONTENT_AIR 126
 
 /*
        Content feature list
@@ -94,7 +103,7 @@ class NodeMetadata;
 struct ContentFeatures
 {
        // If non-NULL, content is translated to this when deserialized
-       MapNode *translate_to;
+       //MapNode *translate_to;
 
        // Type of MapNode::param
        ContentParamType param_type;
@@ -154,7 +163,7 @@ struct ContentFeatures
 
        void reset()
        {
-               translate_to = NULL;
+               //translate_to = NULL;
                param_type = CPT_NONE;
                inventory_texture = NULL;
                is_ground_content = false;
@@ -399,20 +408,30 @@ enum LightBank
 
 struct MapNode
 {
-       // Content
-       u8 d;
+       /*
+               Main content
+               0x00-0x7f: Short content type
+               0x80-0xff: Long content type (param2>>4 makes up low bytes)
+       */
+       union
+       {
+               u8 param0;
+               u8 d;
+       };
 
        /*
                Misc parameter. Initialized to 0.
                - For light_propagates() blocks, this is light intensity,
                  stored logarithmically from 0 to LIGHT_MAX.
                  Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
-               - Contains 2 values, day- and night lighting. Each takes 4 bits.
+                 - Contains 2 values, day- and night lighting. Each takes 4 bits.
+               - Mineral content (should be removed from here)
+               - Uhh... well, most blocks have light or nothing in here.
        */
        union
        {
-               s8 param;
                u8 param1;
+               s8 param;
        };
        
        /*
@@ -437,14 +456,6 @@ struct MapNode
                param2 = a_param2;
        }
 
-       /*MapNode & operator=(const MapNode &other)
-       {
-               d = other.d;
-               param = other.param;
-               param2 = other.param2;
-               return *this;
-       }*/
-
        bool operator==(const MapNode &other)
        {
                return (d == other.d
@@ -452,6 +463,16 @@ struct MapNode
                                && param2 == other.param2);
        }
        
+       // To be used everywhere
+       content_t getContent()
+       {
+               return d;
+       }
+       void setContent(content_t c)
+       {
+               d = c;
+       }
+       
        /*
                These four are DEPRECATED I guess. -c55
        */
@@ -566,88 +587,15 @@ struct MapNode
                MINERAL_NONE if doesn't contain or isn't able to contain mineral.
        */
        u8 getMineral();
-
+       
        /*
-               These serialization functions are used when informing client
-               of a single node add.
-
-               NOTE: When loading a MapBlock, these are not used. Should they?
+               Serialization functions
        */
 
-       static u32 serializedLength(u8 version)
-       {
-               if(!ser_ver_supported(version))
-                       throw VersionMismatchException("ERROR: MapNode format not supported");
-                       
-               if(version == 0)
-                       return 1;
-               else if(version <= 9)
-                       return 2;
-               else
-                       return 3;
-       }
-       void serialize(u8 *dest, u8 version)
-       {
-               if(!ser_ver_supported(version))
-                       throw VersionMismatchException("ERROR: MapNode format not supported");
-                       
-               if(version == 0)
-               {
-                       dest[0] = d;
-               }
-               else if(version <= 9)
-               {
-                       dest[0] = d;
-                       dest[1] = param;
-               }
-               else
-               {
-                       dest[0] = d;
-                       dest[1] = param;
-                       dest[2] = param2;
-               }
-       }
-       void deSerialize(u8 *source, u8 version)
-       {
-               if(!ser_ver_supported(version))
-                       throw VersionMismatchException("ERROR: MapNode format not supported");
-                       
-               if(version == 0)
-               {
-                       d = source[0];
-               }
-               else if(version == 1)
-               {
-                       d = source[0];
-                       // This version doesn't support saved lighting
-                       if(light_propagates() || light_source() > 0)
-                               param = 0;
-                       else
-                               param = source[1];
-               }
-               else if(version <= 9)
-               {
-                       d = source[0];
-                       param = source[1];
-               }
-               else
-               {
-                       d = source[0];
-                       param = source[1];
-                       param2 = source[2];
-               }
-
-               // Translate deprecated stuff
-               // NOTE: This doesn't get used because MapBlock handles node
-               // parameters directly
-               MapNode *translate_to = content_features(d).translate_to;
-               if(translate_to)
-               {
-                       dstream<<"MapNode: WARNING: Translating "<<d<<" to "
-                                       <<translate_to->d<<std::endl;
-                       *this = *translate_to;
-               }
-       }
+       static u32 serializedLength(u8 version);
+       void serialize(u8 *dest, u8 version);
+       void deSerialize(u8 *source, u8 version);
+       
 };
 
 /*
index 80a33610123f1d7a80946c645349aaff2470e45e..974ae95d8aa8392dabf4d31668ee16bf5256c996 100644 (file)
@@ -53,12 +53,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        15: StaticObjects
        16: larger maximum size of node metadata, and compression
        17: MapBlocks contain timestamp
-       18: sqlite/new generator/whatever
+       18: new generator (not really necessary, but it's there)
+       19: new content type handling
 */
 // This represents an uninitialized or invalid format
 #define SER_FMT_VER_INVALID 255
 // Highest supported serialization version
-#define SER_FMT_VER_HIGHEST 18
+#define SER_FMT_VER_HIGHEST 19
 // Lowest supported serialization version
 #define SER_FMT_VER_LOWEST 0