Falling sand and gravel
[oweals/minetest.git] / src / mapnode.cpp
index 829147839cbb4cd210de468fecba156cdcc7bab0..a757149b10612925093837750b52a9a0d43f5599 100644 (file)
@@ -23,9 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 #include "mineral.h"
 #include "main.h" // For g_settings
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 #include "content_mapnode.h" // For mapnode_translate_*_internal
+#include "serialization.h" // For ser_ver_supported
 
+#ifndef SERVER
 /*
        Nodes make a face if contents differ and solidness differs.
        Return value:
@@ -33,8 +35,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
                1: Face uses m1's content
                2: Face uses m2's content
        equivalent: Whether the blocks share the same face (eg. water and glass)
+
+       TODO: Add 3: Both faces drawn with backface culling, remove equivalent
 */
-u8 face_contents(content_t m1, content_t m2, bool *equivalent)
+u8 face_contents(content_t m1, content_t m2, bool *equivalent,
+               INodeDefManager *nodemgr)
 {
        *equivalent = false;
 
@@ -43,13 +48,15 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
        
        bool contents_differ = (m1 != m2);
        
+       const ContentFeatures &f1 = nodemgr->get(m1);
+       const ContentFeatures &f2 = nodemgr->get(m2);
+
        // Contents don't differ for different forms of same liquid
-       if(content_liquid(m1) && content_liquid(m2)
-                       && make_liquid_flowing(m1) == make_liquid_flowing(m2))
+       if(f1.sameLiquid(f2))
                contents_differ = false;
        
-       u8 c1 = content_solidness(m1);
-       u8 c2 = content_solidness(m2);
+       u8 c1 = f1.solidness;
+       u8 c2 = f2.solidness;
 
        bool solidness_differs = (c1 != c2);
        bool makes_face = contents_differ && solidness_differs;
@@ -58,16 +65,16 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
                return 0;
        
        if(c1 == 0)
-               c1 = content_features(m1).visual_solidness;
+               c1 = f1.visual_solidness;
        if(c2 == 0)
-               c2 = content_features(m2).visual_solidness;
+               c2 = f2.visual_solidness;
        
        if(c1 == c2){
                *equivalent = true;
                // If same solidness, liquid takes precense
-               if(content_features(m1).liquid_type != LIQUID_NONE)
+               if(f1.isLiquid())
                        return 1;
-               if(content_features(m2).liquid_type != LIQUID_NONE)
+               if(f2.isLiquid())
                        return 2;
        }
        
@@ -76,6 +83,7 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
        else
                return 2;
 }
+#endif
 
 v3s16 facedir_rotate(u8 facedir, v3s16 dir)
 {
@@ -147,28 +155,24 @@ v3s16 unpackDir(u8 b)
        MapNode
 */
 
-// These four are DEPRECATED.
-bool MapNode::light_propagates()
+// Create directly from a nodename
+// If name is unknown, sets CONTENT_IGNORE
+MapNode::MapNode(INodeDefManager *ndef, const std::string &name,
+               u8 a_param1, u8 a_param2)
 {
-       return light_propagates_content(getContent());
-}
-bool MapNode::sunlight_propagates()
-{
-       return sunlight_propagates_content(getContent());
-}
-u8 MapNode::solidness()
-{
-       return content_solidness(getContent());
-}
-u8 MapNode::light_source()
-{
-       return content_features(*this).light_source;
+       content_t id = CONTENT_IGNORE;
+       ndef->getId(name, id);
+       param1 = a_param1;
+       param2 = a_param2;
+       // Set content (param0 and (param2&0xf0)) after other params
+       // because this needs to override part of param2
+       setContent(id);
 }
 
-void MapNode::setLight(enum LightBank bank, u8 a_light)
+void MapNode::setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr)
 {
        // If node doesn't contain light data, ignore this
-       if(content_features(*this).param_type != CPT_LIGHT)
+       if(nodemgr->get(*this).param_type != CPT_LIGHT)
                return;
        if(bank == LIGHTBANK_DAY)
        {
@@ -184,11 +188,11 @@ void MapNode::setLight(enum LightBank bank, u8 a_light)
                assert(0);
 }
 
-u8 MapNode::getLight(enum LightBank bank)
+u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
 {
        // Select the brightest of [light source, propagated light]
        u8 light = 0;
-       if(content_features(*this).param_type == CPT_LIGHT)
+       if(nodemgr->get(*this).param_type == CPT_LIGHT)
        {
                if(bank == LIGHTBANK_DAY)
                        light = param1 & 0x0f;
@@ -197,85 +201,31 @@ u8 MapNode::getLight(enum LightBank bank)
                else
                        assert(0);
        }
-       if(light_source() > light)
-               light = light_source();
+       if(nodemgr->get(*this).light_source > light)
+               light = nodemgr->get(*this).light_source;
        return light;
 }
 
-u8 MapNode::getLightBanksWithSource()
+u8 MapNode::getLightBanksWithSource(INodeDefManager *nodemgr) const
 {
        // Select the brightest of [light source, propagated light]
        u8 lightday = 0;
        u8 lightnight = 0;
-       if(content_features(*this).param_type == CPT_LIGHT)
+       if(nodemgr->get(*this).param_type == CPT_LIGHT)
        {
                lightday = param1 & 0x0f;
                lightnight = (param1>>4)&0x0f;
        }
-       if(light_source() > lightday)
-               lightday = light_source();
-       if(light_source() > lightnight)
-               lightnight = light_source();
+       if(nodemgr->get(*this).light_source > lightday)
+               lightday = nodemgr->get(*this).light_source;
+       if(nodemgr->get(*this).light_source > lightnight)
+               lightnight = nodemgr->get(*this).light_source;
        return (lightday&0x0f) | ((lightnight<<4)&0xf0);
 }
 
-#ifndef SERVER
-TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
-{
-       if(content_features(*this).param_type == CPT_FACEDIR_SIMPLE)
-               dir = facedir_rotate(param1, dir);
-       
-       TileSpec spec;
-       
-       s32 dir_i = -1;
-       
-       if(dir == v3s16(0,0,0))
-               dir_i = -1;
-       else if(dir == v3s16(0,1,0))
-               dir_i = 0;
-       else if(dir == v3s16(0,-1,0))
-               dir_i = 1;
-       else if(dir == v3s16(1,0,0))
-               dir_i = 2;
-       else if(dir == v3s16(-1,0,0))
-               dir_i = 3;
-       else if(dir == v3s16(0,0,1))
-               dir_i = 4;
-       else if(dir == v3s16(0,0,-1))
-               dir_i = 5;
-       
-       if(dir_i == -1)
-               // Non-directional
-               spec = content_features(*this).tiles[0];
-       else 
-               spec = content_features(*this).tiles[dir_i];
-       
-       /*
-               If it contains some mineral, change texture id
-       */
-       if(content_features(*this).param_type == CPT_MINERAL && tsrc)
-       {
-               u8 mineral = getMineral();
-               std::string mineral_texture_name = mineral_block_texture(mineral);
-               if(mineral_texture_name != "")
-               {
-                       u32 orig_id = spec.texture.id;
-                       std::string texture_name = tsrc->getTextureName(orig_id);
-                       //texture_name += "^blit:";
-                       texture_name += "^";
-                       texture_name += mineral_texture_name;
-                       u32 new_id = tsrc->getTextureId(texture_name);
-                       spec.texture = tsrc->getTexture(new_id);
-               }
-       }
-
-       return spec;
-}
-#endif
-
-u8 MapNode::getMineral()
+u8 MapNode::getMineral(INodeDefManager *nodemgr) const
 {
-       if(content_features(*this).param_type == CPT_MINERAL)
+       if(nodemgr->get(*this).param_type == CPT_MINERAL)
        {
                return param1 & 0x0f;
        }
@@ -344,11 +294,6 @@ void MapNode::deSerialize(u8 *source, u8 version)
        else if(version == 1)
        {
                param0 = source[0];
-               // This version doesn't support saved lighting
-               if(light_propagates() || light_source() > 0)
-                       param1 = 0;
-               else
-                       param1 = source[1];
        }
        else if(version <= 9)
        {
@@ -402,12 +347,12 @@ void MapNode::deSerialize(u8 *source, u8 version)
        returns encoded light value.
 */
 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
-               v3s16 face_dir)
+               v3s16 face_dir, INodeDefManager *nodemgr)
 {
        try{
                u8 light;
-               u8 l1 = n.getLightBlend(daynight_ratio);
-               u8 l2 = n2.getLightBlend(daynight_ratio);
+               u8 l1 = n.getLightBlend(daynight_ratio, nodemgr);
+               u8 l2 = n2.getLightBlend(daynight_ratio, nodemgr);
                if(l1 > l2)
                        light = l1;
                else