]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapnode.h
Always return from non-void functions
[dragonfireclient.git] / src / mapnode.h
index d975a50c46fb0bf83740b6075c652e56ff8adc39..389fa1c9c7f73da1587d2e6aa34709c9d4ace4af 100644 (file)
@@ -32,9 +32,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /*
        Naming scheme:
        - Material = irrlicht's Material class
-       - Content = (u8) content of a node
+       - Content = (content_t) content of a node
        - Tile = TileSpec at some side of a node of some content type
+
+       Content ranges:
+               0x000...0x07f: param2 is fully usable
+               0x800...0xfff: param2 lower 4 bytes are free
 */
+typedef u16 content_t;
+#define MAX_CONTENT 0xfff
 
 /*
        Initializes all kind of stuff in here.
@@ -59,14 +65,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
@@ -88,15 +96,12 @@ enum LiquidType
        LIQUID_SOURCE
 };
 
-class MapNode;
+struct MapNode;
 class NodeMetadata;
 
 struct ContentFeatures
 {
-       // If non-NULL, content is translated to this when deserialized
-       MapNode *translate_to;
-
-       // Type of MapNode::param
+       // Type of MapNode::param1
        ContentParamType param_type;
 
        /*
@@ -110,7 +115,8 @@ struct ContentFeatures
        TileSpec tiles[6];
        
        video::ITexture *inventory_texture;
-
+       
+       // True for all ground-like things like stone and mud, false for eg. trees
        bool is_ground_content;
        bool light_propagates;
        bool sunlight_propagates;
@@ -122,6 +128,8 @@ struct ContentFeatures
        bool pointable;
        // Player can dig these
        bool diggable;
+        // Player can climb these
+        bool climbable;
        // Player can build on these
        bool buildable_to;
        // Whether the node has no liquid, source liquid or flowing liquid
@@ -142,7 +150,9 @@ struct ContentFeatures
        
        // If the content is liquid, this is the flowing version of the liquid.
        // If content is liquid, this is the same content.
-       u8 liquid_alternative_flowing;
+       content_t liquid_alternative_flowing;
+       // If the content is liquid, this is the source version of the liquid.
+       content_t liquid_alternative_source;
        
        // Amount of light the node emits
        u8 light_source;
@@ -154,7 +164,6 @@ struct ContentFeatures
 
        void reset()
        {
-               translate_to = NULL;
                param_type = CPT_NONE;
                inventory_texture = NULL;
                is_ground_content = false;
@@ -164,6 +173,7 @@ struct ContentFeatures
                walkable = true;
                pointable = true;
                diggable = true;
+               climbable = false;
                buildable_to = false;
                liquid_type = LIQUID_NONE;
                wall_mounted = false;
@@ -194,6 +204,8 @@ struct ContentFeatures
                {
                        setTexture(i, name, alpha);
                }
+               // Force inventory texture too
+               setInventoryTexture(name);
        }
 
        void setTile(u16 i, const TileSpec &tile)
@@ -217,8 +229,8 @@ struct ContentFeatures
 /*
        Call this to access the ContentFeature list
 */
-ContentFeatures & content_features(u8 i);
-
+ContentFeatures & content_features(content_t i);
+ContentFeatures & content_features(MapNode &n);
 
 /*
        Here is a bunch of DEPRECATED functions.
@@ -229,7 +241,7 @@ ContentFeatures & content_features(u8 i);
        in param.
        NOTE: Don't use, use "content_features(m).whatever" instead
 */
-inline bool light_propagates_content(u8 m)
+inline bool light_propagates_content(content_t m)
 {
        return content_features(m).light_propagates;
 }
@@ -238,7 +250,7 @@ inline bool light_propagates_content(u8 m)
        NOTE: It doesn't seem to go through torches regardlessly of this
        NOTE: Don't use, use "content_features(m).whatever" instead
 */
-inline bool sunlight_propagates_content(u8 m)
+inline bool sunlight_propagates_content(content_t m)
 {
        return content_features(m).sunlight_propagates;
 }
@@ -250,35 +262,35 @@ inline bool sunlight_propagates_content(u8 m)
        2: Opaque
        NOTE: Don't use, use "content_features(m).whatever" instead
 */
-inline u8 content_solidness(u8 m)
+inline u8 content_solidness(content_t m)
 {
        return content_features(m).solidness;
 }
 // Objects collide with walkable contents
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_walkable(u8 m)
+inline bool content_walkable(content_t m)
 {
        return content_features(m).walkable;
 }
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_liquid(u8 m)
+inline bool content_liquid(content_t m)
 {
        return content_features(m).liquid_type != LIQUID_NONE;
 }
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_flowing_liquid(u8 m)
+inline bool content_flowing_liquid(content_t m)
 {
        return content_features(m).liquid_type == LIQUID_FLOWING;
 }
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_liquid_source(u8 m)
+inline bool content_liquid_source(content_t m)
 {
        return content_features(m).liquid_type == LIQUID_SOURCE;
 }
 // CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
 // CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline u8 make_liquid_flowing(u8 m)
+inline content_t make_liquid_flowing(content_t m)
 {
        u8 c = content_features(m).liquid_alternative_flowing;
        assert(c != CONTENT_IGNORE);
@@ -286,17 +298,17 @@ inline u8 make_liquid_flowing(u8 m)
 }
 // Pointable contents can be pointed to in the map
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_pointable(u8 m)
+inline bool content_pointable(content_t m)
 {
        return content_features(m).pointable;
 }
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_diggable(u8 m)
+inline bool content_diggable(content_t m)
 {
        return content_features(m).diggable;
 }
 // NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_buildable_to(u8 m)
+inline bool content_buildable_to(content_t m)
 {
        return content_features(m).buildable_to;
 }
@@ -308,7 +320,7 @@ inline bool content_buildable_to(u8 m)
                1: Face uses m1's content
                2: Face uses m2's content
 */
-inline u8 face_contents(u8 m1, u8 m2)
+inline u8 face_contents(content_t m1, content_t m2)
 {
        if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
                return 0;
@@ -382,6 +394,9 @@ inline v3s16 unpackDir(u8 b)
        facedir: CPT_FACEDIR_SIMPLE param1 value
        dir: The face for which stuff is wanted
        return value: The face from which the stuff is actually found
+
+       NOTE: Currently this uses 2 bits for Z-,X-,Z+,X+, should there be Y+
+             and Y- too?
 */
 v3s16 facedir_rotate(u8 facedir, v3s16 dir);
 
@@ -391,36 +406,54 @@ enum LightBank
        LIGHTBANK_NIGHT
 };
 
+/*
+       Masks for MapNode.param2 of flowing liquids
+ */
+#define LIQUID_LEVEL_MASK 0x07
+#define LIQUID_FLOW_DOWN_MASK 0x08
+
 /*
        This is the stuff what the whole world consists of.
 */
 
+
 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;
        };
        
        /*
                The second parameter. Initialized to 0.
                E.g. direction for torches and flowing water.
+               If param0 >= 0x80, bits 0xf0 of this is extended content type data
        */
        union
        {
                u8 param2;
-               u8 dir;
+               //u8 dir;
        };
 
        MapNode(const MapNode & n)
@@ -428,46 +461,64 @@ struct MapNode
                *this = n;
        }
        
-       MapNode(u8 data=CONTENT_AIR, u8 a_param=0, u8 a_param2=0)
+       MapNode(content_t content=CONTENT_AIR, u8 a_param1=0, u8 a_param2=0)
        {
-               d = data;
-               param = a_param;
+               //param0 = a_param0;
+               param1 = a_param1;
                param2 = a_param2;
+               // Set after other params because this needs to override part of param2
+               setContent(content);
        }
 
-       /*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
-                               && param == other.param
+               return (param0 == other.param0
+                               && param1 == other.param1
                                && param2 == other.param2);
        }
        
+       // To be used everywhere
+       content_t getContent()
+       {
+               if(param0 < 0x80)
+                       return param0;
+               else
+                       return (param0<<4) + (param2>>4);
+       }
+       void setContent(content_t c)
+       {
+               if(c < 0x80)
+               {
+                       if(param0 >= 0x80)
+                               param2 &= ~(0xf0);
+                       param0 = c;
+               }
+               else
+               {
+                       param0 = c>>4;
+                       param2 &= ~(0xf0);
+                       param2 |= (c&0x0f)<<4;
+               }
+       }
+       
        /*
                These four are DEPRECATED I guess. -c55
        */
        bool light_propagates()
        {
-               return light_propagates_content(d);
+               return light_propagates_content(getContent());
        }
        bool sunlight_propagates()
        {
-               return sunlight_propagates_content(d);
+               return sunlight_propagates_content(getContent());
        }
        u8 solidness()
        {
-               return content_solidness(d);
+               return content_solidness(getContent());
        }
        u8 light_source()
        {
-               return content_features(d).light_source;
+               return content_features(*this).light_source;
        }
 
        u8 getLightBanksWithSource()
@@ -475,10 +526,10 @@ struct MapNode
                // Select the brightest of [light source, propagated light]
                u8 lightday = 0;
                u8 lightnight = 0;
-               if(content_features(d).param_type == CPT_LIGHT)
+               if(content_features(*this).param_type == CPT_LIGHT)
                {
-                       lightday = param & 0x0f;
-                       lightnight = (param>>4)&0x0f;
+                       lightday = param1 & 0x0f;
+                       lightnight = (param1>>4)&0x0f;
                }
                if(light_source() > lightday)
                        lightday = light_source();
@@ -491,12 +542,12 @@ struct MapNode
        {
                // Select the brightest of [light source, propagated light]
                u8 light = 0;
-               if(content_features(d).param_type == CPT_LIGHT)
+               if(content_features(*this).param_type == CPT_LIGHT)
                {
                        if(bank == LIGHTBANK_DAY)
-                               light = param & 0x0f;
+                               light = param1 & 0x0f;
                        else if(bank == LIGHTBANK_NIGHT)
-                               light = (param>>4)&0x0f;
+                               light = (param1>>4)&0x0f;
                        else
                                assert(0);
                }
@@ -534,17 +585,17 @@ struct MapNode
        void setLight(enum LightBank bank, u8 a_light)
        {
                // If node doesn't contain light data, ignore this
-               if(content_features(d).param_type != CPT_LIGHT)
+               if(content_features(*this).param_type != CPT_LIGHT)
                        return;
                if(bank == LIGHTBANK_DAY)
                {
-                       param &= 0xf0;
-                       param |= a_light & 0x0f;
+                       param1 &= 0xf0;
+                       param1 |= a_light & 0x0f;
                }
                else if(bank == LIGHTBANK_NIGHT)
                {
-                       param &= 0x0f;
-                       param |= (a_light & 0x0f)<<4;
+                       param1 &= 0x0f;
+                       param1 |= (a_light & 0x0f)<<4;
                }
                else
                        assert(0);
@@ -564,88 +615,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);
+       
 };
 
 /*