]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapnode.h
.
[dragonfireclient.git] / src / mapnode.h
index 680884bcd96ec83e494d463585edba524684945b..e3b921a66604405c5bc44f4f6a89330f7774bdcc 100644 (file)
@@ -28,9 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serialization.h"
 #include "tile.h"
 
-// Size of node in rendering units
-#define BS 10
-
 #define MATERIALS_COUNT 256
 
 /*
@@ -53,9 +50,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 /*
        Suggested materials:
-       GRAVEL
-         - Dynamics of gravel: if there is a drop of more than two
-           blocks on any side, it will drop in there. Is this doable?
+       - Gravel
+       - Sand
        
        New naming scheme:
        - Material = irrlicht's Material class
@@ -63,25 +59,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        - Tile = (u16) Material ID at some side of a node
 */
 
-enum Content
-{
-       CONTENT_STONE,
-       CONTENT_GRASS,
-       CONTENT_WATER,
-       CONTENT_TORCH,
-       CONTENT_TREE,
-       CONTENT_LEAVES,
-       CONTENT_GRASS_FOOTSTEPS,
-       CONTENT_MESE,
-       CONTENT_MUD,
-       CONTENT_OCEAN,
+#define CONTENT_STONE 0
+#define CONTENT_GRASS 1
+#define CONTENT_WATER 2
+#define CONTENT_TORCH 3
+#define CONTENT_TREE 4
+#define CONTENT_LEAVES 5
+#define CONTENT_GRASS_FOOTSTEPS 6
+#define CONTENT_MESE 7
+#define CONTENT_MUD 8
+#define CONTENT_WATERSOURCE 9
+#define CONTENT_CLOUD 10
+#define CONTENT_COALSTONE 11
+#define CONTENT_WOOD 12
        
-       // This is set to the number of the actual values in this enum
-       USEFUL_CONTENT_COUNT
-};
+#define USEFUL_CONTENT_COUNT 13
 
 extern u16 g_content_tiles[USEFUL_CONTENT_COUNT][6];
-extern const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT];
+extern const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT];
+// Initializes g_content_inventory_texture_paths
+void init_content_inventory_texture_paths();
 
 /*
        If true, the material allows light propagation and brightness is stored
@@ -89,11 +86,12 @@ extern const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT];
 */
 inline bool light_propagates_content(u8 m)
 {
-       return (m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER || m == CONTENT_OCEAN);
+       return (m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
 }
 
 /*
        If true, the material allows lossless sunlight propagation.
+       NOTE: It doesn't seem to go through torches regardlessly of this
 */
 inline bool sunlight_propagates_content(u8 m)
 {
@@ -110,9 +108,9 @@ inline bool sunlight_propagates_content(u8 m)
 inline u8 content_solidness(u8 m)
 {
        // As of now, every pseudo node like torches are added to this
-       if(m == CONTENT_AIR || m == CONTENT_TORCH)
+       if(m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER)
                return 0;
-       if(m == CONTENT_WATER || m == CONTENT_OCEAN)
+       if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE)
                return 1;
        return 2;
 }
@@ -120,29 +118,47 @@ inline u8 content_solidness(u8 m)
 // Objects collide with walkable contents
 inline bool content_walkable(u8 m)
 {
-       return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN && m != CONTENT_TORCH);
+       return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE && m != CONTENT_TORCH);
 }
 
-// A liquid resists fast movement
 inline bool content_liquid(u8 m)
 {
-       return (m == CONTENT_WATER || m == CONTENT_OCEAN);
+       return (m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
+}
+
+inline bool content_flowing_liquid(u8 m)
+{
+       return (m == CONTENT_WATER);
+}
+
+inline bool content_liquid_source(u8 m)
+{
+       return (m == CONTENT_WATERSOURCE);
+}
+
+// CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
+// CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
+inline u8 make_liquid_flowing(u8 m)
+{
+       if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE)
+               return CONTENT_WATER;
+       assert(0);
 }
 
 // Pointable contents can be pointed to in the map
 inline bool content_pointable(u8 m)
 {
-       return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN);
+       return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
 }
 
 inline bool content_diggable(u8 m)
 {
-       return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN);
+       return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
 }
 
 inline bool content_buildable_to(u8 m)
 {
-       return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_OCEAN);
+       return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
 }
 
 /*
@@ -151,21 +167,36 @@ inline bool content_buildable_to(u8 m)
 */
 inline bool is_ground_content(u8 m)
 {
-       return(
-               m == CONTENT_STONE ||
-               m == CONTENT_GRASS ||
-               m == CONTENT_GRASS_FOOTSTEPS ||
-               m == CONTENT_MESE ||
-               m == CONTENT_MUD
+       return (
+               m != CONTENT_IGNORE
+               && m != CONTENT_AIR
+               && m != CONTENT_WATER
+               && m != CONTENT_TORCH
+               && m != CONTENT_TREE
+               && m != CONTENT_LEAVES
+               && m != CONTENT_WATERSOURCE
+               && m != CONTENT_CLOUD
        );
 }
 
-/*inline bool content_has_faces(u8 c)
+inline bool is_mineral(u8 c)
+{
+       return(c == CONTENT_MESE
+               || c == CONTENT_COALSTONE);
+}
+
+inline bool liquid_replaces_content(u8 c)
+{
+       return (c == CONTENT_AIR || c == CONTENT_TORCH);
+}
+
+/*
+       When placing a node, drection info is added to it if this is true
+*/
+inline bool content_directional(u8 c)
 {
-       return (m != CONTENT_IGNORE
-            && m != CONTENT_AIR
-                && m != CONTENT_TORCH);
-}*/
+       return (c == CONTENT_TORCH);
+}
 
 /*
        Nodes make a face if contents differ and solidness differs.
@@ -192,19 +223,6 @@ inline u8 face_contents(u8 m1, u8 m2)
                return 2;
 }
 
-inline bool liquid_replaces_content(u8 c)
-{
-       return (c == CONTENT_AIR || c == CONTENT_TORCH);
-}
-
-/*
-       When placing a node, drection info is added to it if this is true
-*/
-inline bool content_directional(u8 c)
-{
-       return (c == CONTENT_TORCH);
-}
-
 /*
        Packs directions like (1,0,0), (1,-1,0)
 */
@@ -279,6 +297,60 @@ inline u16 content_tile(u8 c, v3s16 dir)
        return g_content_tiles[c][dir_i];
 }
 
+enum LightBank
+{
+       LIGHTBANK_DAY,
+       LIGHTBANK_NIGHT
+};
+
+#if 0
+#define DIR_PX 1 //X+
+#define DIR_NX 2 //X-
+#define DIR_PZ 4 //Z+
+#define DIR_NZ 8 //Z-
+#define DIR_PY 16 //Y+
+#define DIR_NY 32 //Y-
+
+inline void decode_dirs(u8 b, core::list<v3s16> &dirs)
+{
+       if(b & DIR_PX)
+               dirs.push_back(v3s16(1,0,0));
+       if(b & DIR_NX)
+               dirs.push_back(v3s16(-1,0,0));
+       if(b & DIR_PZ)
+               dirs.push_back(v3s16(0,0,1));
+       if(b & DIR_NZ)
+               dirs.push_back(v3s16(0,0,-1));
+       if(b & DIR_PY)
+               dirs.push_back(v3s16(0,1,0));
+       if(b & DIR_NY)
+               dirs.push_back(v3s16(0,-1,0));
+}
+
+inline u8 encode_dirs(core::list<v3s16> &dirs)
+{
+       u8 b = 0;
+       for(core::list<v3s16>::Iterator
+                       i = dirs.begin();
+                       i != dirs.end(); i++)
+       {
+               if(*i == v3s16(1,0,0))
+                       b += DIR_PX;
+               else if(*i == v3s16(-1,0,0))
+                       b += DIR_NX;
+               else if(*i == v3s16(0,0,1))
+                       b += DIR_PZ;
+               else if(*i == v3s16(0,0,-1))
+                       b += DIR_NZ;
+               else if(*i == v3s16(0,1,0))
+                       b += DIR_PY;
+               else if(*i == v3s16(0,-1,0))
+                       b += DIR_NY;
+       }
+       return b;
+}
+#endif
+
 struct MapNode
 {
        // Content
@@ -289,11 +361,14 @@ struct MapNode
                - 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.
        */
        s8 param;
        
        union
        {
+               u8 param2;
+               
                /*
                        Pressure for liquids
                */
@@ -301,7 +376,7 @@ struct MapNode
 
                /*
                        Direction for torches and other stuff.
-                       If possible, packed with packDir.
+                       Format is freeform. e.g. packDir or encode_dirs can be used.
                */
                u8 dir;
        };
@@ -351,23 +426,89 @@ struct MapNode
                return 0;
        }
 
-       u8 getLight()
+       u8 getLightBanksWithSource()
+       {
+               // Select the brightest of [light source, propagated light]
+               u8 lightday = 0;
+               u8 lightnight = 0;
+               if(light_propagates())
+               {
+                       lightday = param & 0x0f;
+                       lightnight = (param>>4)&0x0f;
+               }
+               if(light_source() > lightday)
+                       lightday = light_source();
+               if(light_source() > lightnight)
+                       lightnight = light_source();
+               return (lightday&0x0f) | ((lightnight<<4)&0xf0);
+       }
+
+       void setLightBanks(u8 a_light)
+       {
+               param = a_light;
+       }
+
+       u8 getLight(enum LightBank bank)
        {
                // Select the brightest of [light source, propagated light]
                u8 light = 0;
                if(light_propagates())
-                       light = param & 0x0f;
+               {
+                       if(bank == LIGHTBANK_DAY)
+                               light = param & 0x0f;
+                       else if(bank == LIGHTBANK_NIGHT)
+                               light = (param>>4)&0x0f;
+                       else
+                               assert(0);
+               }
                if(light_source() > light)
                        light = light_source();
                return light;
        }
-
-       void setLight(u8 a_light)
+       
+       // 0 <= daylight_factor <= 1000
+       // 0 <= return value <= LIGHT_SUN
+       u8 getLightBlend(u32 daylight_factor)
+       {
+               u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
+                       + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
+                       )/1000;
+               u8 max = LIGHT_MAX;
+               if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+                       max = LIGHT_SUN;
+               if(l > max)
+                       l = max;
+               return l;
+       }
+       /*// 0 <= daylight_factor <= 1000
+       // 0 <= return value <= 255
+       u8 getLightBlend(u32 daylight_factor)
+       {
+               u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
+               u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
+               u8 mix = ((daylight_factor * daylight
+                       + (1000-daylight_factor) * nightlight)
+                       )/1000;
+               return mix;
+       }*/
+
+       void setLight(enum LightBank bank, u8 a_light)
        {
                // If not transparent, can't set light
                if(light_propagates() == false)
                        return;
-               param = a_light;
+               if(bank == LIGHTBANK_DAY)
+               {
+                       param &= 0xf0;
+                       param |= a_light & 0x0f;
+               }
+               else if(bank == LIGHTBANK_NIGHT)
+               {
+                       param &= 0x0f;
+                       param |= (a_light & 0x0f)<<4;
+               }
+               else
+                       assert(0);
        }
 
        u16 getTile(v3s16 dir)